unsafe void ListenIocpComplete(object o) { IntPtr lpNumberOfBytes; IntPtr lpCompletionKey; RioNativeOverlapped *lpOverlapped = stackalloc RioNativeOverlapped[1]; int lpcbTransfer; int lpdwFlags; while (true) { if (Kernel32.GetQueuedCompletionStatusRio(_listenIocp, out lpNumberOfBytes, out lpCompletionKey, out lpOverlapped, -1)) { if (WinSock.WSAGetOverlappedResult(_listenerSocket, lpOverlapped, out lpcbTransfer, false, out lpdwFlags)) { var res = allSockets[lpOverlapped->SocketIndex]; activeSockets.TryAdd(res.GetHashCode(), res); OnAccepted(res); } else { //recycle socket } } else { var error = Marshal.GetLastWin32Error(); if (error != 0 && error != 64) //connection no longer available { throw new Win32Exception(error); } } } }
protected override unsafe void SocketIocpComplete(object o) { IntPtr lpNumberOfBytes; IntPtr lpCompletionKey; RioNativeOverlapped *lpOverlapped = stackalloc RioNativeOverlapped[1]; while (true) { if (Kernel32.GetQueuedCompletionStatusRio(socketIocp, out lpNumberOfBytes, out lpCompletionKey, out lpOverlapped, -1)) { BeginAccept(allSockets[lpOverlapped->SocketIndex]); } else { var error = Marshal.GetLastWin32Error(); if (error == 735) { break; } if (error != 0 && error != 64) //connection no longer available { throw new Win32Exception(error); } } } }
protected unsafe void SocketIocpComplete(object o) { IntPtr lpNumberOfBytes; IntPtr lpCompletionKey; RioNativeOverlapped *lpOverlapped = stackalloc RioNativeOverlapped[1]; RioNativeOverlapped *lpOverlappedNull = (RioNativeOverlapped *)0; while (true) { if (Kernel32.GetQueuedCompletionStatusRio(socketIocp, out lpNumberOfBytes, out lpCompletionKey, out lpOverlapped, -1)) { SocketIocpOk(allSockets[lpOverlapped->SocketIndex], lpOverlapped->Status); } else { var error = Marshal.GetLastWin32Error(); RioConnectionOrientedSocket socket = null; byte status = 0; if (lpOverlapped != lpOverlappedNull) { socket = allSockets[lpOverlapped->SocketIndex]; status = lpOverlapped->Status; } if (SocketIocpError(error, socket, status)) { break; } } } }
protected override unsafe void SocketIocpComplete(object o) { IntPtr lpNumberOfBytes; IntPtr lpCompletionKey; RioNativeOverlapped * lpOverlapped = stackalloc RioNativeOverlapped[1]; TaskCompletionSource <RioSocket> r; RioConnectionOrientedSocket res; int lpcbTransfer; int lpdwFlags; while (true) { if (Kernel32.GetQueuedCompletionStatusRio(socketIocp, out lpNumberOfBytes, out lpCompletionKey, out lpOverlapped, -1)) { if (lpOverlapped->Status == 1) { _freeSockets.Enqueue(allSockets[lpOverlapped->SocketIndex]); } else if (lpOverlapped->Status == 2) { if (WinSock.WSAGetOverlappedResult(allSockets[lpOverlapped->SocketIndex].Socket, lpOverlapped, out lpcbTransfer, false, out lpdwFlags)) { res = allSockets[lpOverlapped->SocketIndex]; activeSockets.TryAdd(res.GetHashCode(), res); if (_ongoingConnections.TryRemove(res, out r)) { r.SetResult(res); } } else { //recycle socket } } } //1225 else { var error = Marshal.GetLastWin32Error(); if (error == 735) { break; } else if (error != 0 && error != 64 && error != 1225 && error != 735) //connection no longer available { throw new Win32Exception(error); } else { res = allSockets[lpOverlapped->SocketIndex]; _freeSockets.Enqueue(allSockets[lpOverlapped->SocketIndex]); if (_ongoingConnections.TryRemove(res, out r)) { r.SetException(new Win32Exception(error)); } } } } }
internal RioConnectionOrientedSocket(IntPtr overlapped, IntPtr adressBuffer, RioConnectionOrientedSocketPool pool, RioFixedBufferPool sendBufferPool, RioFixedBufferPool receiveBufferPool, uint maxOutstandingReceive, uint maxOutstandingSend, IntPtr SendCompletionQueue, IntPtr ReceiveCompletionQueue) : base(sendBufferPool, receiveBufferPool, maxOutstandingReceive, maxOutstandingSend, SendCompletionQueue, ReceiveCompletionQueue, ADDRESS_FAMILIES.AF_INET, SOCKET_TYPE.SOCK_STREAM, PROTOCOL.IPPROTO_TCP) { _overlapped = (RioNativeOverlapped*)overlapped.ToPointer(); _eventHandle = Kernel32.CreateEvent(IntPtr.Zero, false, false, null); _adressBuffer = adressBuffer; _pool = pool; unsafe { var n = (NativeOverlapped*)overlapped.ToPointer(); n->EventHandle = _eventHandle; } }
internal RioConnectionOrientedSocket(IntPtr overlapped, IntPtr adressBuffer, RioConnectionOrientedSocketPool pool, RioFixedBufferPool sendBufferPool, RioFixedBufferPool receiveBufferPool, uint maxOutstandingReceive, uint maxOutstandingSend, IntPtr SendCompletionQueue, IntPtr ReceiveCompletionQueue) : base(sendBufferPool, receiveBufferPool, maxOutstandingReceive, maxOutstandingSend, SendCompletionQueue, ReceiveCompletionQueue, ADDRESS_FAMILIES.AF_INET, SOCKET_TYPE.SOCK_STREAM, PROTOCOL.IPPROTO_TCP) { _overlapped = (RioNativeOverlapped *)overlapped.ToPointer(); _eventHandle = Kernel32.CreateEvent(IntPtr.Zero, false, false, null); _adressBuffer = adressBuffer; _pool = pool; unsafe { var n = (NativeOverlapped *)overlapped.ToPointer(); n->EventHandle = _eventHandle; } }
protected override unsafe void SocketIocpComplete(object o) { IntPtr lpNumberOfBytes; IntPtr lpCompletionKey; RioNativeOverlapped *lpOverlapped = stackalloc RioNativeOverlapped[1]; while (true) { if (Kernel32.GetQueuedCompletionStatusRio(socketIocp, out lpNumberOfBytes, out lpCompletionKey, out lpOverlapped, -1)) { BeginAccept(allSockets[lpOverlapped->SocketIndex]); } else { Kernel32.ThrowLastError(); } } }
unsafe void AcceptIocpComplete(object o) { IntPtr lpNumberOfBytes; IntPtr lpCompletionKey; RioNativeOverlapped *lpOverlapped = stackalloc RioNativeOverlapped[1]; while (true) { if (Kernel32.GetQueuedCompletionStatusRio(_listenIocp, out lpNumberOfBytes, out lpCompletionKey, out lpOverlapped, -1)) { var res = allSockets[lpOverlapped->SocketIndex]; activeSockets.TryAdd(res.GetHashCode(), res); void *apa = _listenerSocket.ToPointer(); if (res.SetSocketOption(SOL_SOCKET_SocketOptions.SO_UPDATE_ACCEPT_CONTEXT, &apa, IntPtr.Size) != 0) { WinSock.ThrowLastWSAError(); } res.SetInUse(true); OnAccepted(res); } else { var error = Marshal.GetLastWin32Error(); if (error == Kernel32.ERROR_ABANDONED_WAIT_0) { break; } else if (error == Kernel32.ERROR_NETNAME_DELETED) { BeginRecycle(allSockets[lpOverlapped->SocketIndex], false); } else { throw new Win32Exception(error); } } } }
internal RioConnectionOrientedSocket(ulong socketid, IntPtr overlapped, IntPtr adressBuffer, RioConnectionOrientedSocketPool pool, RioFixedBufferPool sendBufferPool, RioFixedBufferPool receiveBufferPool, RioFixedBufferPool adressBufferPool, uint maxOutstandingReceive, uint maxOutstandingSend, IntPtr SendCompletionQueue, IntPtr ReceiveCompletionQueue, ADDRESS_FAMILIES adressFam, SOCKET_TYPE sockType, PROTOCOL protocol) : base(sendBufferPool, receiveBufferPool, adressBufferPool, maxOutstandingReceive, maxOutstandingSend, SendCompletionQueue, ReceiveCompletionQueue, adressFam, sockType, protocol) { _overlapped = (RioNativeOverlapped *)overlapped.ToPointer(); _adressBuffer = adressBuffer; _pool = pool; onreadCompletion = id => { if (id == currentId) { Interlocked.Decrement(ref pendingRecives); } }; onSendCompletion = id => { if (id == currentId) { Interlocked.Decrement(ref pendingSends); } }; sendTimeout = Stopwatch.Frequency * 5; receiveTimeout = Stopwatch.Frequency * 5; currentId = socketid; }
internal static extern unsafe bool WSAGetOverlappedResult(IntPtr socket, [In] RioNativeOverlapped *lpOverlapped, out int lpcbTransfer, bool fWait, out int lpdwFlags);
internal static extern unsafe bool GetQueuedCompletionStatusRio(IntPtr CompletionPort, out IntPtr lpNumberOfBytes, out IntPtr lpCompletionKey, out RioNativeOverlapped *lpOverlapped, int dwMilliseconds);