Although this mechanism is sufficient for simple applications, it cannot support the complex message-dispatching requirements of more advanced applications such as those using the Multiple Document Interface (MDI) model. For such applications, a thread-specific "blocking hook" may be installed by the application. This will be called by the service provider instead of the default blocking hook described above. A service provider must retrieve a pointer to the per-thread blocking hook from the WS2_32.DLLby calling WPUQueryBlockingCallback. If the application has not installed its own blocking hook a pointer to the default blocking hook function will be returned.
A Windows Sockets service provider cannot assume that an application-supplied blocking hook allows message processing to continue as the default blocking hook does. Some applications cannot tolerate the possibility of reentrant messages while a blocking operation is outstanding. Such an application's blocking hook function would simply return FALSE. If a service provider depends on messages for its internal operation, it may execute PeekMessage(hMyWnd...) before executing the application's blocking hook so that it can get its own messages without affecting the rest of the system.
There is no default blocking hook installed in preemptive multithreaded versions of Windows. This is because other processes will not be blocked if a single application is waiting for an operation to complete (and hence not calling PeekMessage or GetMessage which causes the application to yield the processor in nonpreemptive Windows). When the service provider calls WPUQueryBlockingCallback a null pointer will be returned indicating that the provider is to use native OS blocking functions. However, in order to preserve backward compatibility, an application-supplied blocking hook can still be installed on a per-thread basis in 32 bit versions of Windows.
The Windows Sockets service provider calls the blocking hook only if all of the following are true: the routine is one which is defined as being able to block, the specified socket is a blocking socket, and the request cannot be completed immediately. If only non-blocking sockets and WSPAsyncSelect/WSPEventSelect instead of WSPSelect are used, then the blocking hook will never be called.
Important If, during the time pseudo blocking is being used to block a thread, a Windows message is received for the thread, there is a risk that the thread will attempt to issue another Windows Sockets call. Because of the difficulty of managing this condition safely, the Windows Sockets 1.1 specification disallowed this behavior. It is not permissible for a given thread to make multiple nested Windows Sockets function calls. Only one outstanding function call is allowed for a particular thread. Any nested Windows Sockets function calls fail with the error WSAEINPROGRESS. It should be emphasized that this restriction applies to both blocking and non-blocking operations, but only in WinSock 1.1 environments. There are a few exceptions to this rule, including two functions which allow an application to determine whether a pseudo blocking operation is in fact in progress, and to cancel such an operation if need be. These are described below.