Since Windows NT 4.0 Microsoft included support for IO Completion Ports.
This feature allows multiple threads to wait on asynchronous I/O operations and it also
provides a way to submit operation results manually.
Multithreaded applications for Windows have got very powerful and convenient way in which
they can be programmed.

Actually, with IOCP it is possible to organize a message queue which guarantees
that no CPU resources are used when worker threads are waiting for new messages.
Messages, which are being passed to threads through IOCP are defined by OVERLAPPED structure.
It is useful to define a custom OVERLAPPED structure where you can include additional information.
Recently I noticed that it is also possible to use IOCP with Winsock 2 sockets.
A socket handle can be passed to the CreateIoCompletionPort function and this allows to
associate asynchronous operations on that socket with the completion port.
A lot of details and some source code is available in the article:
Write Scalable Winsock Apps Using Completion Ports
Considering this information I do not think that coding with select() or WSAEventSelect() or WSAAsyncSelect() is a good choice for implementing robust and scalable server applications on current Win32 API because:
- select() does not allow to use sockets managed by different LSP providers. This means you can use select() only with TCP sockets or with IrDA sockets but you cannot mix them into one FD_SET structure to make one function call.
- select() does not allow to exit on demand, although a thread is in alertable state when it is executing select() code. The only good solution is to create a signaling (control) socket to be able to quit from select() code. A possible solution with QueueUserAPC does not allow to do anything significant because after APC call select() continues its execution
- WSAEventSelect() is actually good for small applications but impossible in a large server because of the restriction of possible 64 events that can be wait on.
- WSAAsyncSelect() is GUI mode only function.
Thus I will use IOCP with Winsock 2.