NSPR Reference Previous Contents Next |
Multiwait trades off the simplicity of fully synchronous I/O for a limited amount of asynchronous behavior. Its premise is that the connections are mostly idle, spending most of their time waiting for network input. This premise is based on the anticipated behavior of the passive partner (the server) in a client/server relationship. In that environment, the server receives a request from the network, processes that request, sends back the response, and then waits for the next request to arrive. This scenario repeats itself for the lifetime of the connection. If the time of waiting for a request is an order of magnitude or more greater than the time spent in formulating and delivering the response, then multiwait should be applicable.
An incoming request is serviced by a thread from a pool of threads supplied by the client. All threads are assumed to be equivalent and the runtime selects the one most convenient from those available. The client can define different wait groups, that allow separate pools of threads to be associated with different collections of file descriptors.
Multiwait Types
Multiwait Client Functions
PRRecvWait
PRWaitGroup
PRMWStatus
PRMemoryDescriptor
#include <prmwait.h>
typedef struct PRRecvWait
{
PRCList internal;
PRFileDesc *fd;
PRMWStatus outcome;
PRIntervalTime timeout;
PRInt32 bytesRecv;
PRMemoryDescriptor buffer;
PRMWaitClientData *client;
} PRRecvWait;
The completion status of the wait operation is noted in the object's outcome
field.
The fields are not valid when the NSPR runtime is in possession of the object.
The memory descriptor describes an interval of writable memory in the caller's address space where data from an initial read can be placed. The description can indicate a null interval.
#include <prmwait.h>
typedef struct PRWaitGroup PRWaitGroup;
The PRWaitGroup
structure is opaque. The runtime deals with its creation,
destruction, and internal structure. Most of the API's methods require a pointer to a
wait group (also known as the wait group's identity) as an argument. There is a
default wait group, represented by a NULL
identity.
#include <prmwait.h>
typedef enum PRMWStatus
{
PR_MW_PENDING = 1,
PR_MW_SUCCESS = 0,
PR_MW_FAILURE = -1,
PR_MW_TIMEOUT = -2,
PR_MW_INTERRUPT = -3
} PRMWStatus;
PRMWStatus
enumeration is used to indicate the completion status of a receive
wait object. Generally stated, a positive value indicates that the operation is not yet
complete. A zero value indicates success (similar to PR_SUCCESS
) and any negative
value is an indication of failure. The reason for the failure can be retrieved by
calling PR_GetError
.
PR_MW_PENDING
|
The operation is still pending. None of the other fields of the
object is currently valid.
|
PR_MW_SUCCESS
|
The operation is complete and it was successful.
|
PR_MW_FAILURE
|
The operation failed. The reason for the failure can be retrieved
by calling PR_GetError .
|
PR_MW_TIMEOUT
|
The amount of time allowed for by the object's timeout field has
expired without the operation otherwise coming to closure.
|
PR_MW_INTERRUPT
|
The operation was canceled by the client, either by calling
PR_CancelWaitFileDesc or by canceling the entire wait
group using PR_CancelWaitGroup .
|
#include <prmwait.h>
typedef struct PRMemoryDescriptor
{
void *start;
PRSize length;
} PRMemoryDescriptor;
start
|
This is the address of the first byte of memory that the descriptor
defines.
|
length
|
The length of the memory in bytes.
|
PR_CreateWaitGroup
PR_DestroyWaitGroup
PR_AddWaitFileDesc
PR_WaitRecvReady
PR_CancelWaitFileDesc
PR_CancelWaitGroup
#include <prmwait.h>
PRWaitGroup
* PR_CreateWaitGroup (PRInt32 size_hint);
PR_DestroyWaitGroup
.
If unsuccessful, returns NULL
. Retrieve the reason for the failure using
PR_GetError
. The only reason for failure is a heap allocation failure
(PR_OUT_OF_MEMORY_ERROR
).
NULL
identifier. A wait request that was added under a wait group is serviced by a
call to PR_WaitRecvReady
that specifies the same wait group.
#include <prmwait.h>
PRStatus PR_DestroyWaitGroup (PRWaitGroup
*group);
group
|
The identity of the wait group to cancel. This must refer to a valid
wait group and the group must not have any waiting threads or
wait descriptors.
|
PR_SUCCESS
. Otherwise,
returns PR_FAILURE
. Retrieve the reason for the failure by calling PR_GetError
.
PR_CreateWaitGroup
. The wait group
must not contain any receive wait objects. Clear the wait group of all receive wait
objects using the PR_CancelWaitGroup
, before calling this function.
Error codes that can be returned by PR_GetError
when this function fails are:
PR_INVALID_ARGUMENT_ERROR
|
The wait group identity was not known to the
runtime.
|
PR_INVALID_STATE_ERROR
|
The specified wait group was not empty. It had
either wait receive objects or threads waiting.
|
#include <prmwait.h>
PRStatus PR_AddWaitFileDesc (
PRWaitGroup *group,
PRRecvWait *desc);
group
|
A pointer to the wait group to which to add the file descriptor, or
NULL . When NULL , the default group is used.
|
desc
|
A pointer to a valid receive wait descriptor.
|
PR_SUCCESS
. Otherwise, returns PR_FAILURE
.
Retrieve the reason for the failure by calling PR_GetError
.
group
must be either a valid group identifier as returned from
PR_CreateWaitGroup
, or NULL
, which specifies the default group.
Completions of the wait operation are reported when you specify the same wait
group in a call to PR_WaitRecvReady
.
Ownership of the specified receive wait descriptor is temporarily passed to the
runtime; the caller may not alter any portion of the object as long as the runtime
has ownership. The runtime relinquishes ownership when the reference to the
object is returned as a result of PR_WaitRecvReady
.
Error codes that can be returned by PR_GetError
when this function fails are:
#include <prmwait.h>
PRRecvWait* PR_WaitRecvReady(PRWaitGroup *group);
group
|
A pointer to the wait group where receive descriptors were added.
|
NULL
in case of error. Retrieve
the reason for the error by calling PR_GetError
.
PR_AddWaitFileDesc
are returned.
The descriptor returned may have completed and have input data available, or it
may have encountered some error (timeout or interrupt). Check the outcome
field
of the returned object and test it for success. If the function returns NULL
or the
outcome
field indicates other than success, retrieve the reason for the error by
calling PR_GetError
. Possible errors are:
PR_INVALID_ARGUMENT_ERROR
|
The value of group does not represent a group
identifier known to the runtime.
|
PR_PENDING_INTERRUPT_ERROR
|
If the function returned NULL , the call to
PR_WaitRecvReady was interrupted by
another thread.
Otherwise, the descriptor was specifically
canceled (see
|
PR_INVALID_STATE_ERROR
|
The call specified a wait group that is being
destroyed.
|
#include <prmwait.h>
PRStatus PR_CancelWaitFileDesc (
PRWaitGroup *group,
PRRecvWait *desc);
group
|
A pointer to a wait group, or NULL , which indicates the default wait
group.
|
desc
|
A pointer to the receive wait descriptor to be canceled.
|
PR_SUCCESS
. Otherwise, returns PR_FAILURE
. Retrieve the reason for
the failure by calling PR_GetError
.
PR_AddWaitFileDesc
. If the runtime locates the specified descriptor in the
specified wait group, it is marked as having failed because it was interrupted
(similar to PR_Interrupt
).
The first available thread blocked in PR_WaitRecvReady
is made to return with the
reference to the specified descriptor. The object's outcome
field indicates that the
operation was canceled.
If the function returns a value of PR_FAILURE
, retrieve the exact cause of the failure
by calling PR_GetError
. Possible errors are:
#include <prmwait.h>
PRRecvWait* PR_CancelWaitGroup (PRWaitGroup *group);
group
|
A pointer to the wait group to be canceled.
|
A
pointer to a wait receive object, or NULL
if no objects are contained in the group or
in case of error. Retrieve the reason for the failure by calling PR_GetError
.
Each successive call returns a pointer to a receive wait descriptor that was
previously registered with the specified group using PR_AddWaitFileDesc
. The
returned object's outcome
field contains the indication that the operation had been
canceled.
If no wait objects are associated with the specified wait group, the function returns
NULL
. Call this function in a loop until it returns NULL
to reclaim all the wait objects
from a wait group, prior to calling PR_DestroyWaitGroup
.
When the function returns NULL
, retrieve the exact cause by calling PR_GetError
.
Possible errors are:
Last Updated May 18, 2001