Пример #1
0
        internal void DisconnectInternal(bool sendMessage, bool timeout)
        {
#if ALLOW_CONNECTION_STUB
            if (IsStub)
            {
                // NOOP
                return;
            }
#endif

            // TODO: Could be just a normal write lock. The chance of it not being a write in the end is small.
            _stateLock.EnterUpgradeableReadLock();

            try
            {
                if (State == ConnectionState.Connected && sendMessage && !timeout)
                {
                    // Send disconnect message

                    // Allocate memory
                    HeapMemory memory = MemoryManager.AllocHeapMemory(1);

                    // Write disconnect header
                    memory.Buffer[0] = HeaderPacker.Pack(MessageType.Disconnect);

                    // Send disconnect message
                    SendInternal(new ArraySegment <byte>(memory.Buffer, 0, (int)memory.VirtualCount), true);

                    // Release memory
                    MemoryManager.DeAlloc(memory);
                }

                if (State != ConnectionState.Disconnected)
                {
                    _stateLock.EnterWriteLock();

                    try
                    {
                        // Set the state to disconnected
                        State = ConnectionState.Disconnected;

                        // Release all memory
                        Release();
                    }
                    finally
                    {
                        _stateLock.ExitWriteLock();
                    }

                    // Remove from global lookup
                    Socket.RemoveConnection(this);

                    // Send disconnect to userspace
                    Socket.PublishEvent(new NetworkEvent()
                    {
                        Connection        = this,
                        Socket            = Socket,
                        Type              = timeout ? NetworkEventType.Timeout : NetworkEventType.Disconnect,
                        AllowUserRecycle  = false,
                        ChannelId         = 0,
                        Data              = new ArraySegment <byte>(),
                        InternalMemory    = null,
                        SocketReceiveTime = NetTime.Now,
                        MemoryManager     = MemoryManager,
                        EndPoint          = EndPoint
                    });
                }
            }
            finally
            {
                _stateLock.ExitUpgradeableReadLock();
            }
        }