You Are Here:

Community: Blogs

Paul Todd's Forum Nokia Blog

Shutting down Servers and Threads Part 2

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.

RSSComments

Re: Shutting down Servers and Threads Part 2

regan_coleman | 21/09/2006, 17:32

Paul,

Thanks for posting this -- excellent post. I'm looking forward to part II.


regards,
Regan

Forum Nokia Champion

Re: Shutting down Servers and Threads Part 2

Tina_Tibrewal | 13/10/2006, 09:57

Hi Paul.
How do I kill an EXE from an app.
If the EXE is not implemented as a server.
But it is just listening for incoming messages.

Regards.

Re: Shutting down Servers and Threads Part 2

Paul.Todd | 15/10/2006, 14:28

Paul.Todd I am assuming you are using the 3rd editon sdk, in which case you cannot kill it without PowerMgt capability

You could try using RProperty in the publish and subscribe API's
You must login to post comments. Login
 

Rate This

 
 
Bookmark this page: DeliciousDiggFacebookGoogleYahooStumbleUponRedditDiigoTechnocratiTwitter  Share this page Share this page Print this Page Print this page Invite a friend Invite a friend
京ICP备05048969号    Email Newsletters Press Terms & Conditions Privacy Policy Sitemap Contact Us © 2009 Nokia 
RDF Facets: qdcZdescriptionQSxHiE2cE20IE27mE20PaulE2cE20butE20youE20canE20alsoE20callE20meE20ToddE20andE20IE20wonE27tE20getE20upsetE2eE20PaulE2eToddE20E7cE2019E20SeptemberE2cE202006E2017E3a43E20InE20theE20firstE20partE20weE20coveredE20howE20toE20correctlyE20andE20cleanlyE20shutdownE20aE20processE2eNowE20weE20areE20goingE20toE20coverE20howE20toE20shutdownE20aE20threadE2eTypicallyE20peopleE20startE20threadsE20toE20doE20someE20formE20ofE20processingE20butE20oftenE20failE20toE20planE20howE20toE20shutdownE20aE20threadE2eIE20oftenE20heardE20theE20oldE20sayingE20E22FailE20toE20PlanE20thenE20planE20toE20failE22E2eE20ItE20isE20essentialE20toE20decideE20earlyE20onE20whatE20conditionsE20areE20necessaryE20forE20theE20threadE20toE20stoE2eE2eE2eX qdcZidentifierQSxhttpE3aE2fE2fblogsE2eforumE2enokiaE2ecomE2fblogE2fpaulE2dtoddsE2dforumE2dnokiaE2dblogE2f2006E2f09E2f19E2fshuttingE2ddownE2dserversE2dandE2dthreadsE2dpartE2d2X qdcZpublisherQUxhttpE3aE2fE2fswE2enokiaE2ecomE2fidE2fc764fd1cE2d8b06E2d499aE2d9a6aE2d17c3903d5a65E2fforumE5fnokiaE5fcrawlerE5fagentX qdcZtitleQSxPaulE20ToddE27sE20ForumE20NokiaE20BlogE20E7cE20ShuttingE20downE20ServersE20andE20ThreadsE20PartE202X qdcZtypeQUqfnZE45E78cludedFromGeneralE4cistingsQ qdcZtypeQUqfntypeZBlogContentQ qdcZtypeQUqfntypeZBlogE45ntryQ qdcZtypeQUqfntypeZCommunityContentQ qdcZtypeQUqfntypeZE52esourceQ qdcZtypeQUqfntypeZWebpageQ qdcZtypeQUqmarsZManagedE52esourceQ qdcZtypeQUqwebZInformationE52esourceQ qdcZtypeQUqwebZPageQ qdcZtypeQUqwebZE52esourceQ qdcZtypeQUqrdfsZE52esourceQ qrssZdescriptionQSxHiE2cE20IE27mE20PaulE2cE20butE20youE20canE20alsoE20callE20meE20ToddE20andE20IE20wonE27tE20getE20upsetE2eE20PaulE2eToddE20E7cE2019E20SeptemberE2cE202006E2017E3a43E20InE20theE20firstE20partE20weE20coveredE20howE20toE20correctlyE20andE20cleanlyE20shutdownE20aE20processE2eNowE20weE20areE20goingE20toE20coverE20howE20toE20shutdownE20aE20threadE2eTypicallyE20peopleE20startE20threadsE20toE20doE20someE20formE20ofE20processingE20butE20oftenE20failE20toE20planE20howE20toE20shutdownE20aE20threadE2eIE20oftenE20heardE20theE20oldE20sayingE20E22FailE20toE20PlanE20thenE20planE20toE20failE22E2eE20ItE20isE20essentialE20toE20decideE20earlyE20onE20whatE20conditionsE20areE20necessaryE20forE20theE20threadE20toE20stoE2eE2eE2eX qfnZdistributionQUxhttpE3aE2fE2fblogsE2eforumE2enokiaE2ecomE2fX qfnZtopicQUqfnTopicZcppQRqdcZtypeQUqrdfsZE52esourceQRqmarsZrelevanceQNx100X qfnZtopicQUqfnTopicZseriesE5f60QRqdcZtypeQUqrdfsZE52esourceQRqmarsZrelevanceQNx100X qfnZtopicQUqfnTopicZseriesE5f80QRqdcZtypeQUqrdfsZE52esourceQRqmarsZrelevanceQNx100X qfnZtypeQUqfntypeZBlogContentQ qfnZtypeQUqfntypeZBlogE45ntryQ qfnZtypeQUqfntypeZCommunityContentQ qfnZtypeQUqfntypeZE52esourceQ qfnZtypeQUqfntypeZWebpageQ qfnZupdatedQDx2006E2d10E2d15X qfnZuserE5ftagQSxs60X qfnZuserE5ftagQSxseriesE2d80X qfnZuserE5ftagQSxsymbianE2dcE2bE2bX qmarsZdescriptionQSxHiE2cE20IE27mE20PaulE2cE20butE20youE20canE20alsoE20callE20meE20ToddE20andE20IE20wonE27tE20getE20upsetE2eE20PaulE2eToddE20E7cE2019E20SeptemberE2cE202006E2017E3a43E20InE20theE20firstE20partE20weE20coveredE20howE20toE20correctlyE20andE20cleanlyE20shutdownE20aE20processE2eNowE20weE20areE20goingE20toE20coverE20howE20toE20shutdownE20aE20threadE2eTypicallyE20peopleE20startE20threadsE20toE20doE20someE20formE20ofE20processingE20butE20oftenE20failE20toE20planE20howE20toE20shutdownE20aE20threadE2eIE20oftenE20heardE20theE20oldE20sayingE20E22FailE20toE20PlanE20thenE20planE20toE20failE22E2eE20ItE20isE20essentialE20toE20decideE20earlyE20onE20whatE20conditionsE20areE20necessaryE20forE20theE20threadE20toE20stoE2eE2eE2eX qmarsZlanguageQUxhttpE3aE2fE2fswE2enokiaE2ecomE2flanguageE2d1E2fenX qrdfZtypeQUqfnZE45E78cludedFromGeneralE4cistingsQ qrdfZtypeQUqfntypeZBlogContentQ qrdfZtypeQUqfntypeZBlogE45ntryQ qrdfZtypeQUqfntypeZCommunityContentQ qrdfZtypeQUqfntypeZE52esourceQ qrdfZtypeQUqfntypeZWebpageQ qrdfZtypeQUqmarsZManagedE52esourceQ qrdfZtypeQUqwebZInformationE52esourceQ qrdfZtypeQUqwebZPageQ qrdfZtypeQUqwebZE52esourceQ qrdfZtypeQUqrdfsZE52esourceQ