in cpp/Riosock/Riosock.cpp [258:350]
HRESULT RIOSOCKAPI RIOSockInitialize()
{
// Return if already initialized
if (RIOSockRef > 0) {
InterlockedIncrement(&RIOSockRef);
return S_OK;
}
// Create lock for Completion Queue access
CQAccessLock = new (std::nothrow) PrioritizedLock;
if (nullptr == CQAccessLock) {
return E_OUTOFMEMORY;
}
// Create IOCP handle for RECV CQ
auto iocpHandleOfRecv = CreateIoCompletionPort(INVALID_HANDLE_VALUE, nullptr, 0, 0);
if (iocpHandleOfRecv == nullptr)
{
DWORD errorCode = GetLastError();
delete CQAccessLock;
SetLastError(errorCode);
return HRESULT_FROM_WIN32(errorCode);
}
// Create IOCP handle for SEND CQ
auto iocpHandleOfSend = CreateIoCompletionPort(INVALID_HANDLE_VALUE, nullptr, 0, 0);
if (iocpHandleOfSend == nullptr)
{
DWORD errorCode = GetLastError();
// Close IOCP handle
CloseHandle(iocpHandleOfRecv);
delete CQAccessLock;
SetLastError(errorCode);
return HRESULT_FROM_WIN32(errorCode);
}
// Create OVERLAPPED
auto overLapped = calloc(1, sizeof(OVERLAPPED));
if (nullptr == overLapped) {
// Close IOCP handle
CloseHandle(iocpHandleOfRecv);
CloseHandle(iocpHandleOfSend);
delete CQAccessLock;
SetLastError(WSAENOBUFS);
return HRESULT_FROM_WIN32(WSAENOBUFS);
}
// With RIO, we don't associate the IOCP handle with the socket like 'typical' sockets
// - Instead we directly pass the IOCP handle through RIOCreateCompletionQueue
::ZeroMemory(&RecvCompletionType, sizeof(RecvCompletionType));
RecvCompletionType.Type = RIO_IOCP_COMPLETION;
RecvCompletionType.Iocp.CompletionKey = reinterpret_cast<void*>(1);
RecvCompletionType.Iocp.Overlapped = overLapped;
RecvCompletionType.Iocp.IocpHandle = iocpHandleOfRecv;
::ZeroMemory(&SendCompletionType, sizeof(SendCompletionType));
SendCompletionType.Type = RIO_IOCP_COMPLETION;
SendCompletionType.Iocp.CompletionKey = reinterpret_cast<void*>(1);
SendCompletionType.Iocp.Overlapped = overLapped;
SendCompletionType.Iocp.IocpHandle = iocpHandleOfSend;
// Create a completion queue for RECV
RecvCQ = CreateRIOCompletionQueue(DefaultRIOCQSize, &RecvCompletionType);
if (RIO_INVALID_CQ == RecvCQ) {
DWORD errorCode = WSAGetLastError();
CloseHandle(iocpHandleOfRecv);
CloseHandle(iocpHandleOfSend);
free(overLapped);
delete CQAccessLock;
SetLastError(errorCode);
return HRESULT_FROM_WIN32(errorCode);
}
// Create a completion queue for SEND
SendCQ = CreateRIOCompletionQueue(DefaultRIOCQSize, &SendCompletionType);
if (RIO_INVALID_CQ == SendCQ) {
DWORD errorCode = WSAGetLastError();
CloseRIOCompletionQueue(RecvCQ);
RecvCQ = RIO_INVALID_CQ;
CloseHandle(iocpHandleOfRecv);
CloseHandle(iocpHandleOfSend);
free(overLapped);
delete CQAccessLock;
SetLastError(errorCode);
return HRESULT_FROM_WIN32(errorCode);
}
// now that the CQ is created, update info
CQSize = DefaultRIOCQSize;
CQUsed = 0;
return S_OK;
}