public void TestConcurrentAccess() { int count = 20; // Initialize using a specific count. var pool = new SocketAwaitablePool(count); Assert.AreEqual(pool.Count, count); // Deplete the pool. Parallel.For(0, count, i => Assert.IsNotNull(pool.Take())); Assert.AreEqual(pool.Count, 0); // Force pool to initialize new awaitables. var newAwaitables = new SocketAwaitable[count]; Parallel.For(0, count, i => Assert.IsNotNull(newAwaitables[i] = pool.Take())); // Add new awaitables [back] to the pool. Parallel.For(0, count, i => pool.Add(newAwaitables[i])); Assert.AreEqual(pool.Count, count); // Add to, take from and iterate the pool in parallel. var addTask = Task.Run( () => Parallel.For(0, 1000000, i => pool.Add(new SocketAwaitable()))); var takeTask = Task.Run( () => Parallel.For(0, 1000000 + count, i => Assert.IsNotNull(pool.Take()))); var iterateTask = Task.Run( () => Parallel.ForEach(pool, e => Assert.IsNotNull(e))); Task.WaitAll(addTask, takeTask, iterateTask); }
private async Task ConnectAsync(EndPoint endPoint) { var result = SocketError.Fault; for (var i = 0; i < _socketConnectAttempts; i++) { if (_socket != null) { _socket.Close(); _socket = null; } _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) { UseOnlyOverlappedIO = true, NoDelay = true, ReceiveTimeout = _receiveTimeout, SendTimeout = _sendTimeout, ReceiveBufferSize = _receiveBufferSize, SendBufferSize = _sendBufferSize }; var awaitable = _socketAwaitablePool.Take(); try { awaitable.RemoteEndPoint = endPoint; var socketAwaitable = _socket.ConnectAsync(awaitable); _lastActivity = DateTime.UtcNow; result = await socketAwaitable; if (result == SocketError.Success) { break; } } finally { awaitable.Clear(); _socketAwaitablePool.Add(awaitable); } } if (result != SocketError.Success) { if (_socket != null) { _socket.Close(); _socket = null; } throw new RiakException("Unable to connect to remote server: {0}:{1} error code {2}".Fmt(_endPoint.Host, _endPoint.Port, result)); } }
public async Task SendAsyncImmediatelly(byte[] packetBytes) { int totalBytesSent = 0; var socketAwaitable = socketAwaitablePool.Take(); var sendBuffer = bufferManager.GetBuffer(); var sendBufferMaxSize = sendBuffer.Count; try { while (totalBytesSent < packetBytes.Length) { socketAwaitable.Clear(); var writeCount = Math.Min(packetBytes.Length - totalBytesSent, sendBufferMaxSize); Buffer.BlockCopy(packetBytes, totalBytesSent, sendBuffer.Array, sendBuffer.Offset, writeCount); socketAwaitable.Buffer = new ArraySegment <byte>(sendBuffer.Array, sendBuffer.Offset, writeCount); var result = await Socket.SendAsync(socketAwaitable); if (result != SocketError.Success || socketAwaitable.Transferred.Count == 0) { if (Logger.IsDebugEnabled && result != SocketError.Success) { Logger.Debug("Socket did not succeed when sending a packet socketError[{0}] IP[{1}]", result, RemoteIP); } return; } totalBytesSent += socketAwaitable.Transferred.Count; } } // Ignore cases where we accidentally send to the socket after its been disposed catch (ObjectDisposedException) { } catch (Exception e) { Logger.Warn(e, "Unexpected exception in send IP[{0}]", RemoteIP); } finally { socketAwaitable.Clear(); socketAwaitablePool.Add(socketAwaitable); bufferManager.ReleaseBuffer(sendBuffer); } }
public void TestAddingAfterDispose() { var count = 20; var pool = new SocketAwaitablePool(count); Assert.AreEqual(pool.Count, count); pool.Dispose(); Assert.AreEqual(pool.Count, 0); var awaitable = new SocketAwaitable(); Assert.IsFalse(awaitable.IsDisposed); pool.Add(awaitable); Assert.IsTrue(awaitable.IsDisposed); }