1

When calling WSASend(), I have to pass it a WSAOVERLAPPED instance, and I cannot re-use this WSAOVERLAPPED instance until the previous WSASend() operation has been completed (i.e. when a completion packet has been placed in the completion port).

Is there a way I can know if the WSASend() operation has been completed without calling GetQueuedCompletionStatus()?

Steve
  • 691
  • 5
  • 18
  • 1
    `GetQueuedCompletionStatus()` only works if you are using an I/O Completion Port. Are you? To simply check the current status of the operation, you can wait on the event object you put in the `WSAOVERLAPPED`, or you can call `WSAGetOverlappedResult()` with `fWait` set to FALSE. – Remy Lebeau Feb 24 '17 at 10:15
  • @Remy Lebeau Yes I am using IOCP. – Steve Feb 24 '17 at 10:22
  • You're not allowed to reuse the `WSAOVERLAPPED` instance until you've dequeued the IOCP by calling `GetQueuedCompletionStatus()`. Whether the underlying operation has completed or not is irrelevant. – Harry Johnston Feb 24 '17 at 23:42
  • Steve -- if you do have a completion port, you may introduce a race condition with such check, depending of course on what you do after the packet is dequeued from the port. You may end up checking the result of a wrong operation (if OVERLAPPED is reused) or dereferencing invalid memory if it freed. – Sergei Vorobiev Mar 08 '17 at 06:25

2 Answers2

2

you need bind own socket to system created IOCP as result when operation finished your callback will be called automatic. you have 2 options here:

after you create socket by

SOCKET socket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, 0, 0, WSA_FLAG_OVERLAPPED)

you need call BindIoCompletionCallback((HANDLE)socket, *,0) or CreateThreadpoolIo((HANDLE)socket, *, 0, 0);

and all. you not need call GetQueuedCompletionStatus() or wait at all

RbMm
  • 31,280
  • 3
  • 35
  • 56
1

You can use WSAGetOverlappedResult to get the WSASend progression:

/* size bytes to send */
WSASend(Sock, &aBuf, 1, NULL, 0, &overlap, NULL);

/* warning no test for error cases */
DWORD dummy;
DWORD sent;   
do 
{
    /* Ask for the sending progression without waiting */
    WSAGetOverlappedResult(Sock, &SendOverlapped, &sent, FALSE, &dummy);
    /* to prevent too much CPU usage */
    Sleep(15);
} while (size != sent);
Mathieu
  • 8,840
  • 7
  • 32
  • 45
  • But the documentation says the following: *"If another form of notification was selected, the usage of the hEvent parameter of the WSAOVERLAPPED structure is different, and setting fWait to TRUE causes unpredictable results"*, and I am using another form of notification (which is a completion port). – Steve Feb 24 '17 at 16:22
  • Yes, that's why I set it to FALSE – Mathieu Feb 24 '17 at 16:33