Hi, I'm Paul, but you can also call me Todd and I won't get upset.
Paul.Todd | 19 September, 2006 17:43
In the first part we covered how to correctly and cleanly shutdown a process.
Now we are going to cover how to shutdown a thread.
Typically people start threads to do some form of processing but often fail to plan how to shutdown a thread.
I often heard the old saying "Fail to Plan then plan to fail". It is essential to decide early on what conditions are necessary for the thread to stop.
By terminating threads all sorts of issues can be introduced or can can occur depending on when the thread is killed so it really makes sense to plan how to end the threads aside from using terminate or kill.
There are a number of ways to stop a thread and we are going to cover the most important ones here
Watching for a thread to die
In Symbian the easiest way to watch for the thread dying is to use the RThread::Logon method.
You can use it as follows:
RThread thread;
thread.Open(myThreadId);
TRequestStatus watcher;
thread.Logon(watcher);
// start your thread shutdown here
// The below will block until the thread dies
// so make sure you shutdown quickly, otherwise you will
// need to use a wait dialog or something similar
User::WaitForRequest(watcher);
Note that until the thread dies, the thread that is executing the logon/WaitForRequest will be blocked, though you can encapsulate the logon inside an active object. In practice the time from the point where you request the thread to when it is shutdown is sub-second so its normally not worth the hassle.
Using a TRequestStatus to stop a thread
This is normally the "Symbian" preferred method.
Here you pass a pointer an TRequestStatus the thread and when you want to shut down the thread you just complete the TRequeststatus and wait for the thread to complete. Note that the TRequestStatus is "used" by the thread being shutdown and not be the calling thread. It looks intuitively wrong but works.
TRequestStatus* killer = NULL;
mythread.Create(_L("Thread"), MyThreadFunction, 1000,1000,2000, killer);
....
.... we now want to stop the thread
TRequestStatus waiter;
myThread.Logon(waiter); // watch the thread
User::RequestComplete(killer, KErrNone); // tell the thread to stop
User::WaitForRequest(waiter); // when it closes the wait will end
LOCAL_C void MyThreadFunction(TAny* aAny)
{
// setup stuff like active scheduler etc.
TRequestStatus threadstop = KRequestPending;
TRequestStatus* sink = REINTERPRET_CAST(TRequestStatus*,aAny);
sink = &threadstop;
// do something e.g.
TRequestStatus event;
wsSession.EventReady(&event);
// Note WaitForRequest allows two AO's!
User::WaitForRequest(event, threadstop);
if (threadstop != KRequestPending)
{
// this is called when the stop TRS was
// signalled by the main app
//
// do what ever you need to stop the thread
// e.g. shut handles, delete object etc.
return;
}
// event was signalled so do some more processing
// this was not the thread stop TRS so we can still run
// as we have not been requested to shut down
}
Using a global variable
In your main application you can create a global variable, say static TInt32 gShutdownFlag = 0. Of course it need to be static, you could pass a pointer across just as easily.
You can then set this from your main application and in your thread loop you can check to see if this flag is correctly. this is particularly suited to games as these generally do not use Active Objects heavily.
A source of concern might be that reading and writing data across threads is unsafe. Generally speaking read and writes are safe provided they are 32 bits wide. However in OS 9.x Symbian have introduced a new API in the User module, called SafeInc and SafeDec which guarantee that this is atomic.
Another method which I have'nt used is the Publish and Subscribe API. This API allows different processes to work with a common system wide global variable.
You must login to post comments.
Login
Re: Shutting down Servers and Threads Part 2
regan_coleman | 21/09/2006, 17:32
Thanks for posting this -- excellent post. I'm looking forward to part II.
regards,
Regan
Forum Nokia Champion