/// <summary> /// Posts a receive operation to this socket /// </summary> private unsafe void DoReceive() { // Make a room from Request Queue of this socket for operation. var errorStatus = AllocateRequest(); if (errorStatus != 0) { logger.LogError("Cannot post receive operation due to no room in Request Queue."); receivedDataQueue.Add(ByteBuf.NewErrorStatusByteBuf(errorStatus)); return; } // Allocate buffer to receive incoming network data. var dataBuffer = ByteBufPool.UnsafeDefault.Allocate(); if (dataBuffer == null) { logger.LogError("Failed to allocate ByteBuf at DoReceive()."); receivedDataQueue.Add(ByteBuf.NewErrorStatusByteBuf((int)SocketError.NoBufferSpaceAvailable)); return; } var context = new RequestContext(SocketOperation.Receive, dataBuffer); var recvId = GenerateUniqueKey(); // Add the operation context to request table for completion callback. while (!requestContexts.TryAdd(recvId, context)) { // Generate another key, if the key is duplicated. recvId = GenerateUniqueKey(); } // Post a receive operation via native method. var rioBuf = dataBuffer.GetInputRioBuf(); if (RioNative.PostRIOReceive(rioRqHandle, &rioBuf, 1, 0, recvId)) { return; } requestContexts.TryRemove(recvId, out context); context.Data.Release(); if (isCleanedUp) { logger.LogDebug("Socket is already disposed. DoReceive() do nothing."); receivedDataQueue.Add(ByteBuf.NewErrorStatusByteBuf((int)SocketError.NetworkDown)); return; } // Log exception, if post receive operation failed. var socketException = new SocketException(); logger.LogError("Failed to call DoReceive() with error code [{0}], error message: {1}", socketException.ErrorCode, socketException.Message); context.Data.Status = socketException.ErrorCode; receivedDataQueue.Add(context.Data); }
/// <summary> /// Posts a send operation to this socket. /// </summary> private unsafe void DoSend(long sendId, RequestContext context) { // Make a room from Request Queue of this socket for operation. var errorStatus = AllocateRequest(); if (errorStatus != 0) { logger.LogError("Cannot post send operation due to no room in Request Queue."); sendStatusQueue.Add(errorStatus); return; } // Add the operation context to request table for completion callback. while (!requestContexts.TryAdd(sendId, context)) { // Generate another key, if the key is duplicated. sendId = GenerateUniqueKey(); } // Post a send operation via native method. var rioBuf = context.Data.GetOutputRioBuf(); if (RioNative.PostRIOSend(rioRqHandle, &rioBuf, 1, 0, sendId)) { return; } requestContexts.TryRemove(sendId, out context); context.Data.Release(); if (isCleanedUp) { logger.LogDebug("Socket is already disposed. PostSend() do nothing."); receivedDataQueue.Add(ByteBuf.NewErrorStatusByteBuf((int)SocketError.NetworkDown)); return; } // Log exception, if post send operation failed. var socketException = new SocketException(); logger.LogError("Failed to call PostRIOSend() with error code [{0}]. Error message: {1}", socketException.ErrorCode, socketException.Message); sendStatusQueue.Add(socketException.ErrorCode); }