This document describes how requests to active objects are serviced non pre-emptively.
The UI server frameworks spend most of their time waiting for some event to occur, and then spend a short time executing a RunL() function to service that event. When one event has been serviced, processing returns to the wait loop in the active scheduler allowing other events to be serviced.
If a second request completes while the RunL() function is handling completion of the first request, then another call to RunL() to handle completion of the second request cannot be scheduled until the first invocation of RunL() is complete.
This means that active object scheduling is non pre-emptive.
Active objects are queued from the active scheduler in order of priority. The priority is usually determined at the time that the active object is constructed, although it can be changed later.
If several requests complete while a RunL() function is handling the completion of earlier request, the active scheduler takes the first active object (i.e. the one with the highest priority) with a completed request and calls its RunL() function.
As scheduling is non pre-emptive, a high-priority request cannot be serviced until the previously running request’s RunL() has completed.
Most active objects should have a priority of TPriority::EPriorityStandard and processing should not depend on the order in which active objects are scheduled.
However, any active object involved in user input should have a higher priority over other active objects to ensure responsiveness and to allow user control over a device.
Long running and background services should have a low priority.