private void InitBlock() { asn1ID = new Asn1Identifier(); asn1Len = new Asn1Length(); }
/// <summary> This thread decodes and processes RfcLdapMessage's from the server. /// /// Note: This thread needs a graceful shutdown implementation. /// </summary> public virtual void Run() { System.String reason = "reader: thread stopping"; InterThreadException notify = null; Message info = null; System.IO.IOException ioex = null; this.enclosingInstance.reader = SupportClass.ThreadClass.Current(); // Enclosing_Instance.reader = SupportClass.ThreadClass.Current(); // Console.WriteLine("Inside run:" + this.enclosingInstance.reader.Name); try { for (; ; ) { // ------------------------------------------------------- // Decode an RfcLdapMessage directly from the socket. // ------------------------------------------------------- Asn1Identifier asn1ID; System.IO.Stream myIn; /* get current value of in, keep value consistant * though the loop, i.e. even during shutdown */ myIn = this.enclosingInstance.in_Renamed; if (myIn == null) { break; } asn1ID = new Asn1Identifier(myIn); int tag = asn1ID.Tag; if (asn1ID.Tag != Asn1Sequence.TAG) { continue; // loop looking for an RfcLdapMessage identifier } // Turn the message into an RfcMessage class Asn1Length asn1Len = new Asn1Length(myIn); RfcLdapMessage msg = new RfcLdapMessage(this.enclosingInstance.decoder, myIn, asn1Len.Length); // ------------------------------------------------------------ // Process the decoded RfcLdapMessage. // ------------------------------------------------------------ int msgId = msg.MessageID; // Find the message which requested this response. // It is possible to receive a response for a request which // has been abandoned. If abandoned, throw it away try { info = this.enclosingInstance.messages.findMessageById(msgId); info.putReply(msg); // queue & wake up waiting thread } catch (System.FieldAccessException ex) { /* * We get the NoSuchFieldException when we could not find * a matching message id. First check to see if this is * an unsolicited notification (msgID == 0). If it is not * we throw it away. If it is we call any unsolicited * listeners that might have been registered to listen for these * messages. */ /* Note the location of this code. We could have required * that message ID 0 be just like other message ID's but * since message ID 0 has to be treated specially we have * a separate check for message ID 0. Also note that * this test is after the regular message list has been * checked for. We could have always checked the list * of messages after checking if this is an unsolicited * notification but that would have inefficient as * message ID 0 is a rare event (as of this time). */ if (msgId == 0) { // Notify any listeners that might have been registered this.enclosingInstance.notifyAllUnsolicitedListeners(msg); /* * Was this a server shutdown unsolicited notification. * IF so we quit. Actually calling the return will * first transfer control to the finally clause which * will do the necessary clean up. */ if (this.enclosingInstance.unsolSvrShutDnNotification) { notify = new InterThreadException(ExceptionMessages.SERVER_SHUTDOWN_REQ, new System.Object[]{this.enclosingInstance.host, this.enclosingInstance.port}, LdapException.CONNECT_ERROR, null, null); return ; } } else { } } if ((this.enclosingInstance.stopReaderMessageID == msgId) || (this.enclosingInstance.stopReaderMessageID == Novell.Directory.Ldap.Connection.STOP_READING)) { // Stop the reader Thread. return ; } } } catch (System.IO.IOException ioe) { ioex = ioe; if ((this.enclosingInstance.stopReaderMessageID != Novell.Directory.Ldap.Connection.STOP_READING) && this.enclosingInstance.clientActive) { // Connection lost waiting for results from host:port notify = new InterThreadException(ExceptionMessages.CONNECTION_WAIT, new System.Object[]{this.enclosingInstance.host, this.enclosingInstance.port}, LdapException.CONNECT_ERROR, ioe, info); } // The connection is no good, don't use it any more this.enclosingInstance.in_Renamed = null; this.enclosingInstance.out_Renamed = null; } finally { /* * There can be four states that the reader can be in at this point: * 1) We are starting TLS and will be restarting the reader * after we have negotiated TLS. * - Indicated by whether stopReaderMessageID does not * equal CONTINUE_READING. * - Don't call Shutdown. * 2) We are stoping TLS and will be restarting after TLS is * stopped. * - Indicated by an IOException AND stopReaderMessageID equals * STOP_READING - in which case notify will be null. * - Don't call Shutdown * 3) We receive a Server Shutdown notification. * - Indicated by messageID equal to 0. * - call Shutdown. * 4) Another error occured * - Indicated by an IOException AND notify is not NULL * - call Shutdown. */ if ((!this.enclosingInstance.clientActive) || (notify != null)) { //#3 & 4 this.enclosingInstance.shutdown(reason, 0, notify); } else { this.enclosingInstance.stopReaderMessageID = Novell.Directory.Ldap.Connection.CONTINUE_READING; } } this.enclosingInstance.deadReaderException = ioex; this.enclosingInstance.deadReader = this.enclosingInstance.reader; this.enclosingInstance.reader = null; return ; }