|
||
An asynchronous service provider offers one or more request functions.
Only one request on a service provider can be outstanding at any
one time. A request function is one that takes a
TRequestStatus&
parameter or, in rare cases, a
TRequestStatus*
parameter.
When a request function is called (or when the asynchronous service provider is constructed, opened or initialised), the handle of the client thread is noted by the asynchronous service provider, so it knows which thread made the request. A panic results if any other thread tries to use the asynchronous service provider — for instance, to call its cancel function, or to issue another request — since the client of an asynchronous service provider is assumed to be a single thread.
The asynchronous service provider's request function:
first sets the value of the passed TRequestStatus
to KRequestPending
then initiates the request, which may complete any time later.
There are several typical cases:
the request completes normally some time after the request function has returned.
the request completes during the request function call, either because the request completes immediately, or because of an error such as bad parameters meaning that the request cannot even be initiated.
some other type of abnormal completion such as cancellation, which can occur either during the request function call or later.
When a request completes, the client thread’s request semaphore is signalled to indicate completion.
Each thread has a single request semaphore. A thread which uses asynchronous services must have a program whose main loop waits on the thread’s request semaphore for any outstanding request to complete.
When any request completes, the thread program must identify which
of the outstanding requests has completed. It does this by checking the
TRequestStatus
object associated with each outstanding request
and, if its value is not KRequestPending
, the program knows that
the request is complete and can handle the completion of that request.
All asynchronous service providers provide one or more cancel functions, which cancel any outstanding request.
Because of the asynchronous nature of requests, a cancel function
may be called after the request has actually completed. For this reason, a
cancel function should be viewed as a request for early
completion. If you issue a cancel, the asynchronous service provider
may complete the request abnormally by posting KErrCancel
in the
request status object, or it may complete the request normally by posting an
appropriate completion code.