Using CAsyncOneShot

This document descrbes the use of the CAsyncOneShot class in scheduling.

An instance of a class derived from the CAsyncOneShot class can be used to perform one-off processing when no higher-priority active objects are ready to run.

While it has many uses, a common usage is to use it to unload a library. A typical CAsyncOneShot derived class is defined as:

class CLibUnloader : public CAsyncOneShot
    {
public:
    static CLibUnloader* NewL(RLibrary& aLibrary);
    inline void Unload();
protected:
    CLibUnloader();
    ~CLibUnloader();
    virtual void RunL();
private:
    RLibrary iLib;
    };

The static NewL() function takes a reference to an existing open RLibrary object and creates a new CLibUnloader object:

CLibUnloader* CLibUnloader::NewL(RLibrary& aLibrary)
    {
    CLibUnloader* u=new(ELeave)CLibUnloader;
    u->iLib=aLibrary;
    return u;
    }

The remaining functions are implemented as follows:

  • Constructor sets a low active object priority

    CLibUnloader::CLibUnloader()
         :CAsyncOneShot(E_a_very_low_priority)
         {}
  • Calling Unload() activates the active object; the active scheduler will call its RunL() function as soon as there are no other higher priority active objects ready to run.

    void CLibUnloader::Unload()
        {
        Call();
        }
  • The active scheduler calls RunL(), which, in this example, simply deletes the active object. This causes the destructor to be called which closes the library. It also has the effect of removing the active object from the active scheduler through the CActive base class destructor.

    void CLibUnloader::RunL()
        {
        delete this;
        }
    CLibUnloader::~CLibUnloader()
        {
        Cancel();
        iLib.Close();
        }

In other uses of CAsyncOneShot, RunL() could do more complex processing, and indeed could re-queue the active object with another call to CAsyncOneShot::Call().