I'm using IOCP on Windows. Previously I used method GetQueuedCompletionStatus to poll the queue and everything was fine. But when I decided to refactor the logic in the way to utilize completion routine with WSARecv call it always fails with the error WSAEINVAL (10022). This code is in thread created with CreateTread
int flags = 0;
m_iocport = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, NULL, 0);
handle = CreateIoCompletionPort(clientSocket, m_iocport, 0, 0);
OVERLAPPED_EX *over = new OVERLAPPED_EX();
result = WSARecv(clientSocket, &over->m_wsabuf, 1, NULL, &flags, over, WorkerRoutine);
And the worker routine is empty and has following definition:
void static CALLBACK WorkerRoutine(DWORD Error, DWORD BytesTransferred, LPWSAOVERLAPPED Overlapped, DWORD InFlags) {}
When I pass NULL instead of WorkerRoutine to the WSARecv method everything works fine. But when I pass completion routine to the call it fails with the error 10022. I tried to use WorkerRoutine and &WorkerRoutine nothing helps.
the hEvent property is set to NULL in the OVERLAPPED_EX object.
the I/O completion port associated with file and
lpCompletionRoutinethis is mutually exclusive parameters. you can not use it both at once. when you do this - kernel returnSTATUS_INVALID_PARAMETERwhich is translated toWSAEINVAL. so you and must got exactly this error.the IOCP and ApcRoutine 2 different ways for notify you about operation complete. when you use IOCP - system send packet to IOCP on complete. you need use
GetQueuedCompletionStatusorNtRemoveIoCompletionto extract this packet later. and this is not "poll". from another side if you useApcRoutinesystem insert apc to your thread. use two ways for notify at once and in concurrent - this is logic error and kernel correct doing when return to youSTATUS_INVALID_PARAMETERin this case.unfortunately this is not clear stated in MSDN or how minimum i can not fount this. but some research + WRK source code help understand this situation:
WSARecvinternally callZwDeviceIoControlFileand as result in kernel calledIopXxxControlFile. whenlpCompletionRoutine != 0theApcRoutineparameter forIopXxxControlFileis present and you fail exactly at this point:also you can allocate m_wsabuf in stack. valid must be only buffer to which point
WSABUFso you can place to
OVERLAPPED_EXonly buffer to which pointWSABUF.bufbut not wholeWSABUF. but this already not related to your error