예제 #1
0
        static void ReadCallback(object state)
        {
            ListenerConnectionModeReader reader = (ListenerConnectionModeReader)state;

            bool      completeSelf        = false;
            Exception completionException = null;

            try
            {
                if (reader.GetReadResult())
                {
                    completeSelf = reader.ContinueReading();
                }
            }
#pragma warning suppress 56500 // Microsoft, transferring exception to caller
            catch (Exception e)
            {
                if (Fx.IsFatal(e))
                {
                    throw;
                }

                completeSelf        = true;
                completionException = e;
            }

            if (completeSelf)
            {
                reader.Complete(completionException);
            }
        }
        void OnConnectionAvailable(IConnection connection, Action connectionDequeuedCallback)
        {
            if (transportType == TransportType.Tcp)
            {
                ListenerPerfCounters.IncrementConnectionsAcceptedTcp();
            }
            else
            {
                ListenerPerfCounters.IncrementConnectionsAcceptedNamedPipe();
            }

            ListenerConnectionModeReader modeReader = SetupModeReader(connection);

            if (modeReader != null)
            {
                // StartReading() will never throw non-fatal exceptions;
                // it propagates all exceptions into the onConnectionModeKnown callback,
                // which is where we need our robust handling
                modeReader.StartReading(this.channelInitializationTimeout, connectionDequeuedCallback);
            }
            else
            {
                connectionDequeuedCallback();
            }
        }
        void OnConnectionModeKnown(ListenerConnectionModeReader modeReader)
        {
            lock (ThisLock)
            {
                if (isDisposed)
                {
                    return;
                }

                connectionReaders.Remove(modeReader);
            }

            try
            {
                FramingMode framingMode = modeReader.GetConnectionMode();
                switch (framingMode)
                {
                case FramingMode.Duplex:
                    OnDuplexConnection(modeReader);
                    break;

                case FramingMode.Singleton:
                    OnSingletonConnection(modeReader);
                    break;

                default:
                {
                    Exception inner = new InvalidDataException(SR.GetString(
                                                                   SR.FramingModeNotSupported, framingMode));
                    Exception exception = new ProtocolException(inner.Message, inner);
                    FramingEncodingString.AddFaultString(exception, FramingEncodingString.UnsupportedModeFault);
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(exception);
                }
                }
            }
            catch (ProtocolException exception)
            {
                DiagnosticUtility.TraceHandledException(exception, TraceEventType.Information);

                modeReader.Dispose();
            }
            catch (Exception exception)
            {
                if (Fx.IsFatal(exception))
                {
                    throw;
                }

                DiagnosticUtility.TraceHandledException(exception, TraceEventType.Error);

                // containment -- abort the errant reader
                modeReader.Dispose();
            }
        }
        void OnDuplexConnection(ListenerConnectionModeReader modeReader)
        {
            ListenerSessionConnectionReader sessionReader = new ListenerSessionConnectionReader(
                modeReader.Connection, modeReader.GetConnectionDequeuedCallback(),
                transportType, modeReader.StreamPosition,
                modeReader.BufferOffset, modeReader.BufferSize,
                onConnectionClosed, onViaDecoded);

            lock (ThisLock)
            {
                if (isDisposed)
                {
                    sessionReader.Dispose();
                    return;
                }

                connectionReaders.Add(sessionReader);
            }
            sessionReader.StartReading(modeReader.AccruedData, modeReader.GetRemainingTimeout());
        }
        ListenerConnectionModeReader SetupModeReader(IConnection connection)
        {
            if (onConnectionModeKnown == null)
            {
                onConnectionModeKnown = new ListenerConnectionModeCallback(OnConnectionModeKnown);
            }

            ListenerConnectionModeReader modeReader = new ListenerConnectionModeReader(connection, onConnectionModeKnown, onConnectionClosed);
            lock (ThisLock)
            {
                if (isDisposed)
                {
                    modeReader.Dispose();
                    return null;
                }
                else
                {
                    connectionReaders.Add(modeReader);
                    return modeReader;
                }
            }
        }
        ListenerConnectionModeReader SetupModeReader(IConnection connection)
        {
            if (onConnectionModeKnown == null)
            {
                onConnectionModeKnown = new ListenerConnectionModeCallback(OnConnectionModeKnown);
            }

            ListenerConnectionModeReader modeReader = new ListenerConnectionModeReader(connection, onConnectionModeKnown, onConnectionClosed);

            lock (ThisLock)
            {
                if (isDisposed)
                {
                    modeReader.Dispose();
                    return(null);
                }
                else
                {
                    connectionReaders.Add(modeReader);
                    return(modeReader);
                }
            }
        }
        void OnDuplexConnection(ListenerConnectionModeReader modeReader)
        {
            ListenerSessionConnectionReader sessionReader = new ListenerSessionConnectionReader(
                modeReader.Connection, modeReader.GetConnectionDequeuedCallback(), 
                transportType, modeReader.StreamPosition,
                modeReader.BufferOffset, modeReader.BufferSize,
                onConnectionClosed, onViaDecoded);

            lock (ThisLock)
            {
                if (isDisposed)
                {
                    sessionReader.Dispose();
                    return;
                }

                connectionReaders.Add(sessionReader);
            }
            sessionReader.StartReading(modeReader.AccruedData, modeReader.GetRemainingTimeout());
        }
        void OnConnectionModeKnown(ListenerConnectionModeReader modeReader)
        {
            lock (ThisLock)
            {
                if (isDisposed)
                {
                    return;
                }

                connectionReaders.Remove(modeReader);
            }

            try
            {
                FramingMode framingMode = modeReader.GetConnectionMode();
                switch (framingMode)
                {
                    case FramingMode.Duplex:
                        OnDuplexConnection(modeReader);
                        break;
                    case FramingMode.Singleton:
                        OnSingletonConnection(modeReader);
                        break;
                    default:
                        {
                            Exception inner = new InvalidDataException(SR.GetString(
                                SR.FramingModeNotSupported, framingMode));
                            Exception exception = new ProtocolException(inner.Message, inner);
                            FramingEncodingString.AddFaultString(exception, FramingEncodingString.UnsupportedModeFault);
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(exception);
                        }
                }
            }
            catch (ProtocolException exception)
            {
                DiagnosticUtility.TraceHandledException(exception, TraceEventType.Information);

                modeReader.Dispose();
            }
            catch (Exception exception)
            {
                if (Fx.IsFatal(exception))
                {
                    throw;
                }

                DiagnosticUtility.TraceHandledException(exception, TraceEventType.Error);

                // containment -- abort the errant reader
                modeReader.Dispose();
            }
        }