// UWAGA
// Ponisza implementacja powstaa na podstawie dokumentacji klasy CActiveScheduler
// oraz analizy zachowania aktywnych obiektw.


void CActiveScheduler::Run(TLoopOwner* const volatile& aLoop)
{
    CActive* ao=NULL;

    do
    {
        TInt err=KErrNone;
    
        TRAPD( err, DoRunL( aLoop, ao ) );
        if( err != KErrNone )
        {
            err = ao->RunError( err );
            if( err != KErrNone )
            {
                Error( err );
            }
        }
    }
    while( aLoop );
}

void CActiveScheduler::DoRunL(TLoopOwner* const volatile& aLoop, CActive* volatile & aCurrentObj)
{
    TInt err=KErrNone;

    do
    {
        // Czekanie na wykonanie jakiejkolwiek usugi asynchronicznej zwizanej
        // z biecym wtkiem.
        // Czekanie skoczy si po spenieniu jednego z poniszych warunkw:
        // - Dostawca Usug Asynchronicznych wywoa metod RThread::RequestComplete()
        //   na obiekcie reprezentujcym biecy wtek;
        // - jeden z aktywnych obiektw dziaajcych w biecym wtku wywoa metod 
        //   User::RequestComplete().
        // Uwaga: Metody klasy User w zdecydowanej wikszoci dotycz biecego wtku.
        User::WaitForAnyRequest();    // Czekanie...
        
        // Ok, przynajmniej jedna usuga asynchroniczna zwizana z biecym wtkiem
        // zostaa zakoczona.
        
        TPtrList<CActive>* aoList( iActiveQ );
        
        // Ponisza ptla sprawdza aktywne obiekty wedug priorytetw.
        do
        {        
            aCurrentObj = aoList->GetCurrent();
            if( aCurrentObj == NULL )
            {
                // Jestemy poza list, co oznacza, e usuga asynchroniczna 
// zostaa wykonana, ale nie zosta znaleziony aden 
// obiekt j reprezentujcy.
                User::Panic( _L("E32USER-CBASE"), 46 );    // Zagubiony sygna
            }
                
            aoList->GoToNext();
            
            // Jeeli obiekt nie jest aktywny lub jest aktywny, ale usuga z nim 
// zwizana nie zostaa jeszcze wykonana - przejd do nastpnego
// obiektu.
            if( !aCurrentObj->IsActive() || aCurrentObj->iStatus==KRequestPending )
                continue;
            
            // Obiekt jest aktywny oraz zwizana z nim usuga zostaa wykonana.
            // Przecz aktywny obiekt w stan nieaktywny.
            aCurrentObj->iStatus.iFlags = 0;
            // Obsu aktywny obiekt.
            aCurrentObj->RunL();
            break;
        }while( ETrue );
    }while( aLoop );
    
    aCurrentObj = NULL;
}
