Beispiel #1
0
 internal MemoryManager(SocketConfig config)
 {
     _configuration        = config;
     _pooledHeapMemory     = new ConcurrentCircularQueue <HeapMemory>(_configuration.HeapMemoryPoolSize);
     _pooledPointerArrays  = new ConcurrentCircularQueue <HeapPointers>(_configuration.HeapPointersPoolSize);
     _pooledMemoryWrappers = new ConcurrentCircularQueue <MemoryWrapper>(_configuration.MemoryWrapperPoolSize);
 }
Beispiel #2
0
        public void ArrayTest()
        {
            var queue = new ConcurrentCircularQueue <DataClass>(_testList.Count);

            queue.Enqueue(new DataClass());
            queue.Dequeue();

            queue.Enqueue(_testList);

            Assert.AreEqual(_testList.Count, queue.Count);

            foreach (var item in _testList)
            {
                var result = queue.Dequeue();
                Assert.AreSame(item, result);
            }

            queue.Enqueue(new DataClass());
            queue.Dequeue();

            queue.Enqueue(_testList);
            DataClass[] copyList = new DataClass[_testList.Count];
            queue.CopyTo(copyList, 0);

            for (int i = 0; i < _testList.Count; ++i)
            {
                Assert.AreSame(_testList[i], copyList[i]);
            }
        }
Beispiel #3
0
        public void BasicTest()
        {
            var queue = new ConcurrentCircularQueue <DataClass>(_testList.Count);

            foreach (var item in _testList)
            {
                queue.Enqueue(item);
            }

            Assert.AreEqual(_testList.Count, queue.Count);

            List <DataClass> _dequeueList = new List <DataClass>(_testList.Count);

            foreach (var item in _testList)
            {
                _dequeueList.Add(queue.Dequeue());
            }

            Assert.AreEqual(0, queue.Count);

            CheckList(_dequeueList, _dequeueList.Count);

            for (int i = 0; i < _testList.Count * 3; ++i)
            {
                var item = _testList[i % _testList.Count];
                queue.Enqueue(item);
                var result = queue.Dequeue();

                Assert.AreSame(item, result);
            }
        }
Beispiel #4
0
        public void OverflowTest()
        {
            int allocCount = _testList.Count / 2;
            var queue      = new ConcurrentCircularQueue <DataClass>(allocCount);

            for (int i = 0; i < _testList.Count; ++i)
            {
                bool result = queue.Enqueue(_testList[i]);
                if (i < allocCount)
                {
                    Assert.AreEqual(true, result);
                }
                else
                {
                    Assert.AreEqual(false, result);
                }
            }

            Assert.AreEqual(allocCount, queue.Count);

            List <DataClass> _dequeueList = new List <DataClass>(_testList.Count);

            for (int i = 0; i < allocCount; ++i)
            {
                _dequeueList.Add(queue.Dequeue());
            }

            Assert.AreEqual(0, queue.Count);

            CheckList(_dequeueList, _dequeueList.Count);
        }
Beispiel #5
0
        private Task EnqueueTest(ConcurrentCircularQueue <DataClass> queue)
        {
            foreach (var item in _testList)
            {
                queue.Enqueue(item);
            }

            return(Task.CompletedTask);
        }
Beispiel #6
0
        internal Connection(ulong id, ConnectionState state, IPEndPoint endpoint, RuffleSocket socket)
        {
#if ALLOW_CONNECTION_STUB
            if (IsStub)
            {
                // NOOP
                return;
            }
#endif
            this.Id                              = id;
            this.Socket                          = socket;
            this.EndPoint                        = endpoint;
            this.MTU                             = Config.MinimumMTU;
            this.SmoothRoundtrip                 = 0;
            this.HighestRoundtripVarience        = 0;
            this.Roundtrip                       = 500;
            this.LowestRoundtrip                 = 500;
            this.LastMessageIn                   = NetTime.Now;
            this.LastMessageOut                  = NetTime.Now;
            this.ConnectionStarted               = NetTime.Now;
            this.ConnectionCompleted             = NetTime.Now;
            this.HandshakeStarted                = NetTime.Now;
            this.HandshakeLastSendTime           = NetTime.Now;
            this.HandshakeResendAttempts         = 0;
            this.ChallengeAnswer                 = 0;
            this.ConnectionChallenge             = RandomProvider.GetRandomULong();
            this.ChallengeDifficulty             = (byte)Config.ChallengeDifficulty;
            this.PreConnectionChallengeTimestamp = 0;
            this.PreConnectionChallengeCounter   = 0;
            this.PreConnectionChallengeIV        = 0;
            this.PreConnectionChallengeSolved    = false;
            this.State                           = state;

            if (Config.EnableBandwidthTracking && Config.CreateBandwidthTracker != null)
            {
                this.BandwidthTracker = Config.CreateBandwidthTracker();
            }

            if (Config.EnableHeartbeats)
            {
                this.HeartbeatChannel = new UnreliableOrderedChannel(0, this, Config, MemoryManager);
            }

            if (Config.EnablePacketMerging)
            {
                this.Merger = new MessageMerger(Config.MaxMergeMessageSize, Config.MinimumMTU);
            }

            if (Logging.CurrentLogLevel <= LogLevel.Debug)
            {
                Logging.LogInfo("Allocating " + Config.EventQueueSize + " event slots");
            }
            this._userEventQueue        = new ConcurrentCircularQueue <NetworkEvent>(Config.EventQueueSize, true);
            this.IsUserEventQueueActive = true;
        }
Beispiel #7
0
        internal ChannelPool(SocketConfig config)
        {
            if (config.ReuseChannels)
            {
                if ((config.PooledChannels & PooledChannelType.Reliable) == PooledChannelType.Reliable)
                {
                    _reliableChannels = new ConcurrentCircularQueue <ReliableChannel>(config.ChannelPoolSize);
                }

                if ((config.PooledChannels & PooledChannelType.ReliableFragmented) == PooledChannelType.ReliableFragmented)
                {
                    _reliableFragmentedChannels = new ConcurrentCircularQueue <ReliableFragmentedChannel>(config.ChannelPoolSize);
                }

                if ((config.PooledChannels & PooledChannelType.ReliableOrdered) == PooledChannelType.ReliableOrdered)
                {
                    _reliableOrderedChannels = new ConcurrentCircularQueue <ReliableOrderedChannel>(config.ChannelPoolSize);
                }

                if ((config.PooledChannels & PooledChannelType.ReliableSequenced) == PooledChannelType.ReliableSequenced)
                {
                    _reliableSequencedChannels = new ConcurrentCircularQueue <ReliableSequencedChannel>(config.ChannelPoolSize);
                }

                if ((config.PooledChannels & PooledChannelType.ReliableSequencedFragmented) == PooledChannelType.ReliableSequencedFragmented)
                {
                    _reliableSequencedFragmentedChannels = new ConcurrentCircularQueue <ReliableSequencedFragmentedChannel>(config.ChannelPoolSize);
                }

                if ((config.PooledChannels & PooledChannelType.Unreliable) == PooledChannelType.Unreliable)
                {
                    _unreliableChannels = new ConcurrentCircularQueue <UnreliableChannel>(config.ChannelPoolSize);
                }

                if ((config.PooledChannels & PooledChannelType.UnreliableOrdered) == PooledChannelType.UnreliableOrdered)
                {
                    _unreliableOrderedChannels = new ConcurrentCircularQueue <UnreliableOrderedChannel>(config.ChannelPoolSize);
                }

                if ((config.PooledChannels & PooledChannelType.UnreliableSequenced) == PooledChannelType.UnreliableSequenced)
                {
                    _unreliableSequencedChannels = new ConcurrentCircularQueue <UnreliableSequencedChannel>(config.ChannelPoolSize);
                }

                if ((config.PooledChannels & PooledChannelType.UnreliableRaw) == PooledChannelType.UnreliableRaw)
                {
                    _unreliableRawChannels = new ConcurrentCircularQueue <UnreliableRawChannel>(config.ChannelPoolSize);
                }
            }
        }
Beispiel #8
0
        public QueueBenchmark()
        {
            _list = new List <DataClass>(TestCount);
            for (int i = 0; i < TestCount; ++i)
            {
                _list.Add(new DataClass()
                {
                    Value = i
                });
            }

            _concurrentQueue         = new ConcurrentQueue <DataClass>();
            _concurrentCircluarQueue = new ConcurrentCircularQueue <DataClass>(TestCount);
        }
Beispiel #9
0
        public async Task MultithreadTest()
        {
            int taskCount = 20;
            var queue     = new ConcurrentCircularQueue <DataClass>(_testList.Count * taskCount);

            List <Task> taskList = new List <Task>();

            for (int i = 0; i < taskCount; ++i)
            {
                taskList.Add(EnqueueTest(queue));
            }

            await Task.WhenAll(taskList);

            Assert.AreEqual(_testList.Count * taskCount, queue.Count);

            var sortedQueue = new List <DataClass>(queue.ToArray());

            sortedQueue.Sort((x, y) => x.Value.CompareTo(y.Value));

            for (int x = 0; x < _testList.Count; ++x)
            {
                for (int y = 0; y < taskCount; ++y)
                {
                    Assert.AreSame(_testList[x], sortedQueue[x * taskCount + y]);
                }
            }

            var queue2 = new ConcurrentCircularQueue <DataClass>(_testList.Count);

            taskList.Clear();
            for (int i = 0; i < taskCount; ++i)
            {
                taskList.Add(EnqueueDequeueTest(queue2));
            }

            await Task.WhenAll(taskList);

            Assert.AreEqual(0, queue2.Count);
        }
Beispiel #10
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();
                    }

                    //

                    IsUserEventQueueActive = false;
                    while (_userEventQueue != null && _userEventQueue.TryDequeue(out NetworkEvent networkEvent))
                    {
                        // Recycle all packets to prevent leak detection
                        networkEvent.Recycle();
                    }
                    // Release user queue
                    _userEventQueue = null;

                    //

                    // 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();
            }
        }