private unsafe CancellationToken CreateDisconnectToken(ulong connectionId) { LogHelper.LogDebug(_logger, "CreateDisconnectToken", "Registering connection for disconnect for connection ID: " + connectionId); // Create a nativeOverlapped callback so we can register for disconnect callback var cts = new CancellationTokenSource(); var returnToken = cts.Token; SafeNativeOverlapped nativeOverlapped = null; var boundHandle = _requestQueue.BoundHandle; nativeOverlapped = new SafeNativeOverlapped(boundHandle, boundHandle.AllocateNativeOverlapped( (errorCode, numBytes, overlappedPtr) => { LogHelper.LogDebug(_logger, "CreateDisconnectToken", "http.sys disconnect callback fired for connection ID: " + connectionId); // Free the overlapped nativeOverlapped.Dispose(); // Pull the token out of the list and Cancel it. ConnectionCancellation token; _connectionCancellationTokens.TryRemove(connectionId, out token); try { cts.Cancel(); } catch (AggregateException exception) { LogHelper.LogException(_logger, "CreateDisconnectToken Callback", exception); } }, null, null)); uint statusCode; try { statusCode = HttpApi.HttpWaitForDisconnectEx(requestQueueHandle: _requestQueue.Handle, connectionId: connectionId, reserved: 0, overlapped: nativeOverlapped); } catch (Win32Exception exception) { statusCode = (uint)exception.NativeErrorCode; LogHelper.LogException(_logger, "CreateDisconnectToken", exception); } if (statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_IO_PENDING && statusCode != UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS) { // We got an unknown result, assume the connection has been closed. nativeOverlapped.Dispose(); ConnectionCancellation ignored; _connectionCancellationTokens.TryRemove(connectionId, out ignored); LogHelper.LogDebug(_logger, "HttpWaitForDisconnectEx", new Win32Exception((int)statusCode)); cts.Cancel(); } if (statusCode == UnsafeNclNativeMethods.ErrorCodes.ERROR_SUCCESS && HttpSysListener.SkipIOCPCallbackOnSuccess) { // IO operation completed synchronously - callback won't be called to signal completion nativeOverlapped.Dispose(); ConnectionCancellation ignored; _connectionCancellationTokens.TryRemove(connectionId, out ignored); cts.Cancel(); } return(returnToken); }