/// <summary> /// If possible, this method dequeues a read from the read queue and starts it. /// This is only possible if all of the following are true: /// 1) any previous read has completed /// 2) there's a read in the queue /// 3) and the stream is ready. /// /// This method is thread safe. /// </summary> private void MaybeDequeueRead(object ignore) { lock (lockObj) { if ((flags & kClosed) > 0) { readQueue.Clear(); return; } if ((currentRead == null) && (stream != null)) { if((flags & kPauseReads) > 0) { // Don't do any reads yet. // We're waiting for TLS negotiation to start and/or finish. } else if(readQueue.Count > 0) { // Get the next object in the read queue Object nextRead = readQueue.Dequeue(); if (nextRead is AsyncSpecialPacket) { // Next read packet is a special instruction packet. // Right now this can only mean a StartTLS instruction. AsyncSpecialPacket specialRead = (AsyncSpecialPacket)nextRead; // Update flags - this flag will be unset when TLS finishes flags |= kPauseReads; // And attempt to start TLS // This method won't do anything unless both kPauseReads and kPauseWrites are set. MaybeStartTLS(); } else { // Get the new current read AsyncReadPacket currentRead = (AsyncReadPacket)nextRead; // Start time-out timer if (currentRead.timeout >= 0) { readTimer = new System.Threading.Timer(new TimerCallback(stream_DidNotRead), currentRead, currentRead.timeout, Timeout.Infinite); } // Do we have any overflow data that we've already read from the stream? if (readOverflow != null) { // Start reading from the overflow DoReadOverflow(); } else { // Start reading from the stream DoStartRead(); } } } else if((flags & kCloseAfterReads) > 0) { if ((flags & kCloseAfterWrites) > 0) { if ((writeQueue.Count == 0) && (currentWrite == null)) { Close(null); } } else { Close(null); } } } } }
/// <summary> /// Ends the current read by disposing and nullifying the read timer, /// and then nullifying the current read. /// </summary> private void EndCurrentRead() { if (readTimer != null) { readTimer.Dispose(); readTimer = null; } currentRead = null; }