This document describes the purpose of asynchronous service providers.
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 initialized), 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.