Synchronisation Techniques

Describes the use of RThread::Rendezvous() to synchronize threads.

There are a number of techniques to synchronize or coordinate the activities of your threads with one another:

Thread Rendezvous

The RThread::Rendezvous() function allows a thread to signal that it has reached a point in its execution. This works in a similar way to the Logon() function, except that Logon() signals the termination of a thread, and Rendezvous() signals that a particular point within the thread has been reached.

The classic use for this function is in a server, where the main thread must wait until the initialisation of the server thread has completed before continuing.

Using Rendezvous

The following example shows code a function creating a thread and then waiting for it to reach a certain point before continuing. The code shown here is taken from …\examples\base\threadsandprocesses\Rendezvous\, which you can build and run.

      // create threads to wait for
    RThread thread;

        // indicate completion status
    TRequestStatus myThreadRendezvousStatus;

        // pass 500 as the parameter to MyThread        
    TInt r=thread.Create(KMsgMyThreadName, MyThread, KDefaultStackSize, KHeapSize,KHeapSize,(TAny*) 2000000, EOwnerThread); 
    if (r!=KErrNone)
        {   
        console->Printf(KMsgCreateThreadFailed);
            return;
        }
        // create rendezvous
    thread.Rendezvous(myThreadRendezvousStatus);

        //EXCECUTE THREAD!
    console->Printf(KMsgStartThread);                    
    thread.Resume();

    User::WaitForRequest(myThreadRendezvousStatus);
    if(myThreadRendezvousStatus==KErrNone)
        {
        console->Printf(KMsgThreadRendezvousReached);
        }
        else
        {
        console->Printf(KMsgSomethingIsWrong);   
        }   
        
    thread.Close();
    console->Printf(KMsgEndOfTest);

The following function is the MyThread() function created in the previous example. The MyThread() function calls the rendezvous function to signal that the rendezvous point has been reached, MyThread() can then continue.

TInt MyThread(TAny* aParameter)
    {
        // simulate some processing
    User::After((TInt)aParameter);      
            
            // signal Rendezvous
    RThread::Rendezvous(KErrNone);
    
        // simulate some processing
    User::After((TInt)aParameter);      
    
    return(KErrNone);
    }

Note: MyThread() can fail before signalling the Rendezvous, for example, if MyThread() panics with a KERN-EXEC 3, then the Rendezvous completes with the reason code KErrDied or another system wide error code other than KErrNone.

If MyThread() enters a never ending loop before the rendezvous is reached, then this situation cannot be detected and results in the calling thread waiting indefinitely for the rendezvous. This can be avoided by careful programming.