/**
* Funkcja suca do niskopoziomowego odtwarzania dwiku
*/
void OdtwarzajDzwiek( const TDesC8& aStrumien )
{
    // Odtwarzanie dwiku...
}

/**
* Funkcja przygotowujca strumie dwikowy na podstawie kodu
* bdu. Odpowiednie dane mog by adowane z plikw dwikowych.
*/
void OdtworzDzwiek( TInt aBlad, RSemaphore& aSemafor )
{
    HBufC8* dzwiek = NULL;
    // Przygotowanie dwiku na podstawie kodu bdu zapisanego 
    // w parametrze aBlad (zakadamy, e wskanik dzwiek bdzie
    // wskazywa na dane ju zaadowane do pamici).
    
    aSemafor.Wait();    // Inkrementuj licznik semafora.
    OdtwarzajDzwiek( *dzwiek );
    aSemafor.Signal();    // Dekrementuj licznik semafora.
}

// Funkcje wtkw
TInt FunkcjaWatkuPierwszego( TAny* aPtr )
{
    TInt blad = KErrNone;
    
    // Wykonywanie operacji...
    
    OdtworzDzwiek( blad, *static_cast<RSemaphore*>(aPtr) );    
    return blad;
}

TInt FunkcjaWatkuDrugiego( TAny* aPtr )
{
    TInt blad = KErrNone;
    
    // Wykonywanie operacji...
    
    OdtworzDzwiek( blad, *static_cast<RSemaphore*>(aPtr) );    
    return blad;    
}

TInt FunkcjaWatkuTrzeciego( TAny* aPtr )
{
    TInt blad = KErrNone;
    
    // Wykonywanie operacji...
    
    OdtworzDzwiek( blad, *static_cast<RSemaphore*>(aPtr) );    
    return blad;
}

// ----------------------------------
// ------ Wtek gwny procesu ------
// ----------------------------------

// Tworzymy lokalny semafor, do ktrego uchwyt moe by wspdzielony pomidzy
// wtkami procesu. Inicjalizujemy licznik semafora wartoci 2, co oznacza, e w danej 
// chwili tylko dwa wtki bd miay dostp do podsystemu dwiku.
User::LeaveIfError( iSemafor.CreateLocal( 2 ) );

// Tworzymy wtki
_LIT( KPierwszyWatek, "Watek1" );
_LIT( KDrugiWatek, "Watek2" );
_LIT( KTrzeciWatek, "Watek3" );

TInt blad = iPierwszyWatek.Create( KPierwszyWatek, 
                    FunkcjaWatkuPierwszego,
                    KDefaultStackSize,
                    NULL,    // aHeap = NULL, uywamy sterty wtku gwnego.
                    static_cast<TAny*>( &iSemafor ) );
User::LeaveIfError( blad );

blad = iDrugiWatek.Create( KDrugiWatek, 
                FunkcjaWatkuDrugiego,
                KDefaultStackSize,
                NULL,    // aHeap = NULL, uywamy sterty wtku gwnego.
                static_cast<TAny*>( &iSemafor ) );
User::LeaveIfError( blad );

blad = iTrzeciWatek.Create( KTrzeciWatek, 
                FunkcjaWatkuTrzeciego,
                KDefaultStackSize,
                NULL,    // aHeap = NULL, uywamy sterty wtku gwnego.
                static_cast<TAny*>( &iSemafor ) );
User::LeaveIfError( blad );

// Wszystkie wtki zostay utworzone pomylnie -  ustawiamy je jako
// gotowe do uruchomienia. Wtki zostan uruchomione, gdy w systemie
// nie bd wykonywane wtki o wyszym priorytecie.
iPierwszyWatek.Resume();
iDrugiWatek.Resume();
iTrzeciWatek.Resume();
