CActiveScheduler Class Reference

class CActiveScheduler : public CBase

Controls the handling of asynchronous requests as represented by active objects.

An active scheduler is used to schedule the sequence in which active object request completion events are handled by a single event-handling thread.

An active scheduler can be instantiated and used directly if either:

  • the RunL() function of all of its active objects is guaranteed not to leave, or

  • each of its active objects implements a suitable RunError() function to provide suitable cleanup

If any of the active scheduler's active objects does not provide a RunError() function, then a CActiveScheduler derived class must be defined and an implementation of the Error() function provided to perform the cleanup required.

There is one active scheduler per thread and the static functions provided by the class always refer to the current active scheduler.

CActiveScheduler::Error CActive CActiveSchedulerWait

Inherits from

Public Member Functions
IMPORT_C voidAdd(CActive *)
IMPORT_C CActiveScheduler *Current()
IMPORT_C voidError(TInt)
IMPORT_C voidHalt(TInt)
IMPORT_C voidInstall(CActiveScheduler *)
IMPORT_C CActiveScheduler *Replace(CActiveScheduler *)
IMPORT_C TBoolRunIfReady(TInt &, TInt)
IMPORT_C TIntStackDepth()
IMPORT_C voidStart()
IMPORT_C voidStop()
IMPORT_C voidWaitForAnyRequest()
Protected Member Functions
IMPORT_C TIntExtension_(TUint, TAny *&, TAny *)
TInt Level()
Private Member Functions
voidDoRunL(TLoopOwner *const volatile &, CActive *volatile &, TCleanupBundle *)
IMPORT_C voidOnStarting()
IMPORT_C voidOnStopping()
IMPORT_C voidReserved_1()
IMPORT_C voidReserved_2()
voidRun(TLoopOwner *const volatile &)
voidStart(TLoopOwner *)
Inherited Functions
CBase::Delete(CBase *)
CBase::operator new(TUint)
CBase::operator new(TUint,TAny *)
CBase::operator new(TUint,TLeave)
CBase::operator new(TUint,TLeave,TUint)
CBase::operator new(TUint,TUint)
Public Member Type Definitions
typedefTLoop * TLoopOwner
Private Attributes
TPriQue< CActive >iActiveQ
TAny *iSpare
TLoop *iStack

Constructor & Destructor Documentation



Constructs an active scheduler.

After construction, the scheduler should be installed.




Frees resources prior to destruction.

Specifically, it removes all active objects from the active scheduler's list of active objects.

An active scheduler should only be destroyed when the top-level call to Start() has returned.

CActiveScheduler::Start CActiveScheduler::Stop

Member Functions Documentation

Add(CActive *)

IMPORT_C voidAdd(CActive *aActive)[static]

Adds the specified active object to the current active scheduler.

An active object can be removed from an active scheduler either by destroying the active object or by using its Deque() member function.

E32USER-CBase 41 if the active object aRequest has already been added to the current active scheduler.
E32USER-CBase 48 if aRequest is NULL.
E32USER-CBase 44 if the thread does not have an installed active scheduler.


CActive * aActivePointer to the active object to be added.


IMPORT_C CActiveScheduler *Current()[static]

Gets a pointer to the currently installed active scheduler.

DoRunL(TLoopOwner *const volatile &, CActive *volatile &, TCleanupBundle *)

voidDoRunL(TLoopOwner *const volatile &aLoop,
CActive *volatile &aCurrentObj,
TCleanupBundle *aCleanupBundle

The inner active scheduler loop. This repeatedly waits for a signal and then dispatches the highest priority ready active object. The loop terminates either if one of the RunLs stops the current active scheduler level or leaves.

Stop when aLoop becomes 'Inactive'
EClnCheckFailed 90 This will panic when the RunL has left the cleanup stack in an unbalanced state.


TLoopOwner *const volatile & aLoop
CActive *volatile & aCurrentObj
TCleanupBundle * aCleanupBundle


IMPORT_C voidError(TIntaError)const [virtual]

Handles the result of a leave occurring in an active object s RunL() function.

An active scheduler always invokes an active object s RunL() function under a trap harness.

The default implementation must be replaced.

Any cleanup relevant to the possible causes of leaving should be performed. If Stop() or Halt() is called from within this function, the current wait loop terminates. This may be an appropriate response to catastrophic error conditions.

E32USER-CBase 47 if the default implementation is invoked.
CActive::RunL CActiveScheduler::Stop CActiveScheduler::Halt


TInt aErrorThe leave code propagated from the active object s RunL() function

Extension_(TUint, TAny *&, TAny *)

IMPORT_C TIntExtension_(TUintaExtensionId,
TAny *&a0,
TAny *a1
)[protected, virtual]

Extension function


TUint aExtensionId
TAny *& a0
TAny * a1


IMPORT_C voidHalt(TIntaExitCode)const

Unilaterally terminates the current scheduler loop.

This causes the current scheduler loop to stop, whether it was started using CActiveSchedulerWait::Start() or CActiveScheduler::Start(). It can also trigger a leave from Start() if an exit code is provided. If the current level has already been stopped, then this still records the exit code.


TInt aExitCodeIf non-zero, the reason code reported by Start().

Install(CActiveScheduler *)

IMPORT_C voidInstall(CActiveScheduler *aScheduler)[static]

Installs the specified active scheduler as the current active scheduler.

The installed active scheduler now handles events for this thread.

The current active scheduler can be uninstalled by passing a NULL pointer.

E32USER-CBase 43 if If there is already an installed active scheduler.


CActiveScheduler * aSchedulerA pointer to the active scheduler to be installed. If this is NULL, the current active scheduler is uninstalled.


TInt Level()const [protected, inline]

Use the StackDepth() function instead.

Gets the scheduler's level of nestedness.



IMPORT_C voidOnStarting()[private, virtual]

Dummy EXPORT for Binary Compatibility reasons. This method is never called.


IMPORT_C voidOnStopping()[private, virtual]

Dummy EXPORT for Binary Compatibility reasons. This method is never called.

Replace(CActiveScheduler *)

IMPORT_C CActiveScheduler *Replace(CActiveScheduler *aNewActiveScheduler)[static]

Allows the current active scheduler to be replaced, while retaining its active objects.


CActiveScheduler * aNewActiveSchedulerThe new active scheduler.


IMPORT_C voidReserved_1()[private, virtual]

Dummy EXPORT for Binary Compatibility reasons.


IMPORT_C voidReserved_2()[private, virtual]

Dummy EXPORT for Binary Compatibility reasons.

Run(TLoopOwner *const volatile &)

voidRun(TLoopOwner *const volatile &aLoop)[private]

Start dispatching request completions.

Stop when aLoop becomes 'Inactive'

This version uses the original implementation of TRAP/Leave.


TLoopOwner *const volatile & aLoop

RunIfReady(TInt &, TInt)

IMPORT_C TBoolRunIfReady(TInt &aError,

Causes the RunL() function of at most one pending active object of priority aMinimumPriority or greater to be run.


TInt & aErrorError returned by called active object.
TInt aMinimumPriorityMinimum priority of active object to run.


IMPORT_C TIntStackDepth()const

Gets the current number of nested wait loops.


IMPORT_C voidStart()[static]

Starts a new wait loop under the control of the current active scheduler.

At least one active object, with an outstanding request, must be added to the scheduler before the wait loop is started, otherwise no events will occur and the thread will hang, or any events that do occur will be counted as stray signals, raising a panic.

While Start() is executing, user code runs only:

1. in the RunL() function of active objects known to the current active scheduler

2. in the RunError() function of an active object that leaves from its RunL()

3. in the current active scheduler s Error() function, if an active object s RunError() returns an error code.

Start() returns only when a corresponding Stop() or Halt() is issued.

Although this can be used to start a nested wait loop, this API is deprecated for that specific functionality, and a CActiveSchedulerWait object should be used instead.

(Note that a nested wait loop is used when the handling of a completed event in an active object requires the processing of further events from the other active objects before it can complete. This is a form of modal processing.)

E32USER-CBase 44 if the thread does not have an active scheduler installed.
CActiveScheduler::Stop CActiveScheduler::Halt CActive::RunL CActive::RunError CActiveScheduler::Error CActiveSchedulerWait

Start(TLoopOwner *)

voidStart(TLoopOwner *aOwner)[private, static]

Start a new nesting level


TLoopOwner * aOwner


IMPORT_C voidStop()[static]

Stops the wait loop started by the most recent call to Start().

Typically, this is called by the RunL() of one of the scheduler s active objects. When this RunL() finishes, the scheduler s wait loop terminates, i.e. it does not wait for the completion of the next request.

It will not stop a wait loop started by a call to CActiveSchedulerWait::Start().

Stop() may also be called from Error().

Note that stopping a nested wait loop is deprecated using this functionality, use a CActiveSchedulerWait object instead.

CActiveSchedulerWait::Start CActive::RunL CActiveSchedulerWait::Error CActiveSchedulerWait::AsyncStop


IMPORT_C voidWaitForAnyRequest()[virtual]

Wait for an asynchronous request to complete.

The default implementation just calls User::WaitForAnyRequest().

Derived classes can replace this. Typically, this would be done to implement code for maintaining an outstanding request; this would be followed by a call to User::WaitForAnyRequest().


Member Type Definitions Documentation

Typedef TLoopOwner

typedef TLoop *TLoopOwner

Member Data Documentation

TPriQue< CActive > iActiveQ

TPriQue< CActive >iActiveQ[private]

TAny * iSpare

TAny *iSpare[private]

TLoop * iStack

TLoop *iStack[private]