Completion ports and sockets - scaling my app



Hi,

I got some serious problems understanding the behaviour of socket-related iocps driven by multiple threads.

I post some sends without waiting for their completion.
Lets assume 2 chunks of data.

First chunk 1 is put on his way by WSASend(). The send could not be satisfied in one call so only a part of the data could be sent and the rest has to be sended again.

Thread 1 gets an IO-completion packet about the partial send and tries to send the rest. Right after receiving the completion packet for that send and before calling the WSASend for the rest of the data, the thread is preemted.

The second thread sends chunk 2, so the data will be corrupted, won't they?

So after considering this would it not be better to have only ONE outstanding send? Better wait for completion of one send before scheduling the next?

Using sync-objects wouldn't make things better, I have to wait anyway for copletion of the send.


There is the great article in MSDN

Windows Sockets 2.0: Write Scalable Winsock Apps Using Completion Ports
by Anthony Jones and Amol Deshpande
which states:

"
However, a high-performance server application can turn off the send buffering, yet not lose performance. Such an application must, however, take great care to ensure that it posts multiple overlapped sends, instead of waiting for one overlapped send to complete before posting another. If the application posts overlapped sends in a sequential manner, it wastes the time window between one send completion and the posting of the next send. If it had another buffer already posted, the transport would be able to use that buffer immediately and not wait for the application's next send operati"




How can I post multiple overlapped sends without corrupting my data? By implementing some kind of sequence numbering scheme?
.




Relevant Pages

  • Re: serving a file to a client --- background fcopy read fileevent event puts socket cha
    ... invokes a callback when there's both data waiting and somewhere to ... probably not -size (although having -size pre-load the input buffer ... you can't even observe the progress of the [fcopy] from outside (ie. ... The division of functionality I mentioned should have negligible impact ...
    (comp.lang.tcl)
  • XFS related hang (was Re: How to send a break? - dump from frozen 64bit linux)
    ... we're waiting here on a synchronisation variable that'll ... that'd be called by the I/O completion handler on the buffer ... waiting for the driver to wake us up when its done. ... we aren't seeing the I/O completion here for some reason... ...
    (Linux-Kernel)
  • Re: Piping between 2 threads
    ... I have the following pipe buffer shared between threads. ... 1 - R starts waiting on write event. ... Use a ringbuffer of buffer pointers. ...
    (comp.programming)
  • Re: Can NetworkStream.Write() block?
    ... myNetworkStream.BeginWrite(bytebuffer, int offset, int size) since all that does is create a backlog of BeginWrite threads all waiting to complete. ... In general, you can assume asynchronous calls are *more* efficient than their synchronous companions, since those *always* take up a thread (namely the thread waiting for completion) while the asynchronous ones generally only take up a thread when executing the completion callback. ... The overlapped requests are simply queued until there's an opportunity to process them. ...
    (microsoft.public.dotnet.languages.csharp)