Windows Sockets 1.1 Blocking routines & EINPROGRESS
One major issue in porting applications from a Berkeley sockets environment to
a Windows environment involves "blocking"; that is, invoking a function that
does not return until the associated operation is completed. A problem arises
when the operation takes an arbitrarily long time to complete: an example is a recv
, which might block until data has been received from the peer system. The
default behavior within the Berkeley sockets model is for a socket to operate in a
blocking mode unless the programmer explicitly requests that operations be
treated as nonblocking. Windows Sockets 1.1 environments could not assume
pre-emptive scheduling. Therefore, it was strongly recommended that programmers use the
nonblocking (asynchronous) operations if at all possible. Because this was not
always possible, the psuedo-blocking facilities described below were provided.
Even on a blocking socket, some functions bind
, and getpeername
complete immediately. There is no difference between a blocking and a
nonblocking operation for those functions. Other operations, such as recv,
can complete immediately or could take an arbitrary time to complete,
depending on various transport conditions. When applied to a blocking socket, these
operations are referred to as blocking operations. All routines that can block
are listed with an asterisk in the tables above and below.
With Windows Sockets 1.1, a blocking operation that cannot complete
immediately is handled by psuedo-blocking as follows. The service provider initiates the
operation, then enters a loop in which it dispatches any Windows messages
(yielding the processor to another thread if necessary), and then checks for the
completion of the Windows Sockets function. If the function has completed, or if WSACancelBlockingCall
has been invoked, the blocking function completes with an appropriate result.
A service provider must allow installation of a blocking hook function that
does not process messages in order to avoid the possibility of re-entrant
messages while a blocking operation is outstanding. The simplest such blocking hook
function would return FALSE. If a Windows Sockets DLL depends on messages for
internal operation, it can execute PeekMessage(hMyWnd...) before executing the
application blocking hook so that it can get its messages without affecting the
rest of the system.
In a Windows Sockets 1.1 environment, if a Windows message is received for a
process for which a blocking operation is in progress, there is a risk that the
application will attempt to issue another Windows Sockets call. Because of the
difficulty in managing this condition safely, Windows Sockets 1.1 does not
support such application behavior. An application it not permitted to make more
than one nested Windows Sockets function calls. Only one outstanding function call
will be allowed for a particular task. The only exceptions are two functions
that are provided to assist the programmer in this situation: WSAIsBlocking
function can be called at any time to determine whether or not a blocking
Windows Sockets 1.1 call is in progress. Similarly, the WSACancelBlockingCall
fucntion can be called at any time to cancel an in-progress blocking call.
Any other nesting of Windows Sockets functions will fail with the error
WSAEINPROGRESS. It should be emphasized that this restriction applies to both blocking
and non-blocking operations.
Although this mechanism is sufficient for simple applications, it cannot
support the complex message-dispatching requirements of more advanced applications
(for example, those using the MDI model). For such applications, the Windows
Sockets API includes the function WSASetBlockingHook
, which allows the application to specify a special routine which will be
called instead of the default message dispatch routine described above.
The Windows Sockets provider calls the blocking hook only if all of the
following are true: the routine is one that is defined as being able to block, the
specified socket is a blocking socket, and the request cannot be completed
immediately. (A socket is set to blocking by default, but the IOCTL FIONBIO or the WSAAsyncSelect
function set a socket to nonblocking mode.)
The blocking hook will never be called and the application does not need to be
concerned with the re-entrancy issues the blocking hook can introduce if an
application follows these guideline:
- It uses only nonblocking sockets, and;
- It uses the WSAAsyncSelect and/or the WSAAsyncGetXByY routines instead of select and the getXbyY routines.
If a Windows Sockets 1.1 application invokes an asynchronous or nonblocking
operation that takes a pointer to a memory object (a buffer, or a global variable
for example) as an argument, it is the responsibility of the application to
ensure that the object is available to Windows Sockets throughout the operation.
The application must not invoke any Windows function that might affect the
mapping or addressability of the memory involved.
- Software for developers
Software for Android Developers
- More information resources
Unix Manual Pages