A communication request is pending if the communication has not yet started.
As a matter of taste, the implementations of the minimal API sketched here do not use polling to implement their ``wait'' methods. If a waitany method specifying a particular request has been invoked, a wait-object may be associated with that request. Any wait-object provides a synch() method, which implements barrier synchronization between precisely two threads. This can be implemented as follows:
class Wait { void synchronized int synch() { if(waiting) { waiting = false ; notify() ; } else { waiting = true ; wait() ; } } boolean waiting = false ; }
Wait-objects are used for synchronization between input-handlers and user threads. In practise wait-objects will contain extra fields relating to nominated and selected sets of request objects, and these fields will provide a channel of communication between input-handlers and user threads.
Besides wait-objects, the principle means of synchronization is mutual exclusion on a single lock that controls access to the communication sets--data structures describing the ongoing communications. The communication sets include the input-buffer and the pending-request-set. The input-buffer contains messages that have been accepted by the input handlers, but not yet consumed by the user threads. Depending on the protocol, the input-buffer may hold request-to-send messages and/or complete messages containing user data. The pending-request-set, as its name implies, is the set of communication request objects that are currently pending.
The input-handlers are threads--one per input socket connection. These handle all input from sockets. All output to sockets occurs in the context of user threads.