/// <summary> /// Creates a request queue for this socket operation /// </summary> private void CreateRequestQueue() { // Allocate completion from completion queue if (!RioNative.AllocateRIOCompletion((uint)InitialCqRoom)) { var socketException = new SocketException(); logger.LogError( "AllocateRIOCompletion() failed to allocate completions to this socket. Returns error {0}", socketException.ErrorCode); throw socketException; } // Create the RQ for this socket. connectionId = GenerateUniqueKey(); while (!RioNative.ConnectionTable.TryAdd(connectionId, this)) { connectionId = GenerateUniqueKey(); } rioRqHandle = RioNative.CreateRIORequestQueue(SockHandle, rqReservedSize >> 1, rqReservedSize >> 1, connectionId); if (rioRqHandle != IntPtr.Zero) { return; } // Error Handling var sockException = new SocketException(); RioNative.ReleaseRIOCompletion((uint)InitialCqRoom); RioSocketWrapper sock; RioNative.ConnectionTable.TryRemove(connectionId, out sock); logger.LogError("CreateRIORequestQueue() returns error {0}", sockException.ErrorCode); throw sockException; }
private int AllocateRequest() { var newRqUsed = rqUsed + 1; if (newRqUsed > rqReservedSize) { var newRqReservedSize = rqReservedSize + rioRqGrowthFactor; if (!RioNative.AllocateRIOCompletion((uint)rioRqGrowthFactor)) { var errorCode = Marshal.GetLastWin32Error(); logger.LogError( "Failed to allocate completions to this socket. AllocateRIOCompletion() returns error {0}", errorCode); return(errorCode); } // Resize the RQ. if (!RioNative.ResizeRIORequestQueue(rioRqHandle, (uint)newRqReservedSize >> 1, (uint)newRqReservedSize >> 1)) { var errorCode = Marshal.GetLastWin32Error(); logger.LogError("Failed to resize the request queue. ResizeRIORequestQueue() returns error {0}", errorCode); RioNative.ReleaseRIOCompletion((uint)rioRqGrowthFactor); return(errorCode); } // since it succeeded, update reserved with the new size rqReservedSize = (uint)newRqReservedSize; } // everything succeeded - update rqUsed with the new slots being used for this next IO rqUsed = newRqUsed; return(0); }
private void Dispose(bool disposing) { // Mark this as disposed before changing anything else. var cleanedUp = isCleanedUp; isCleanedUp = true; if (!cleanedUp && disposing) { try { // Release room back to Completion Queue RioNative.ReleaseRIOCompletion((uint)InitialCqRoom); // Remove this socket from the connected socket table. RioSocketWrapper socket; RioNative.ConnectionTable.TryRemove(connectionId, out socket); } catch (Exception) { logger.LogDebug("RioNative default instance already disposed."); } // Remove all pending socket operations if (!requestContexts.IsEmpty) { foreach (var keyValuePair in requestContexts) { // Release the data buffer of the pending operation keyValuePair.Value.Data.Release(); } requestContexts.Clear(); } // Remove received Data from the queue, and release buffer back to byte pool. while (receivedDataQueue.Count > 0) { ByteBuf data; receivedDataQueue.TryTake(out data); data.Release(); } // Close the socket handle. No need to release Request Queue handle that // will be gone once the socket handle be closed. if (SockHandle != IntPtr.Zero) { RioNative.closesocket(SockHandle); SockHandle = IntPtr.Zero; } GC.SuppressFinalize(this); } isConnected = false; isListening = false; }