Hi folks

I've tested the code (latest SVN) and get also get a crash when
start() is called the scond time.
Recreating the thread object indeed solves the problem, so it looks
like there is actually something going wrong when a cancelled thread
is restarted.

Slightly OT w.r.t. Paul's remark, I fail to see how waiting in a loop
can be "better" than joining, the latter being based on a
synchronization primitive that should, imho, be more efficient than
polling the thread for its isRunning flag. I always use join() to make
sure workers are finished and never saw an issue with this. Of course,
you can sometimes have a worker thread that does not testCancel() and
thus, do something like:

void cancelWithTimeOut(OpenThreads::Thread* thread, unsigned int timeout)
{
  thread->cancel();
  unsigned int timer = 0;
  while (thread->isRunning() && timer < timeout)
  {
    OpenThreads::Thread::microSleep(10000);
    timer += 10000;
  }
  if (thread->isRunning())
  {
    thread->setCancelModeAsynchronous();
    thread->cancel();
  }
}

And instead of:

mythread->start();
mythread->cancel(); // Assume that the thread is polite and will terminate ASAP
mythread->join();

do:

mythread->start();
cancelWithTimeOut(mythread, 3000000); // Assume that the thread is
probably not willing to terminate on its own
mythread->join();

to kill the thread after 3 seconds, whatever the data loss/corruption
that may occur.
My 2 cents.

I'll investigate further if the "Restarting a cancelled thread causes
crash" thing is a bug in OpenThreads.

Cheers

Thibault

On Mon, Sep 7, 2009 at 11:47 PM, Michael Guerrero<[email protected]> wrote:
> Thanks for the reply Paul.  I was calling join because i wanted the main 
> calling
> thread to block until myThread was finished.  I know it doesn't make much 
> sense
> to do it that way in this contrived example but in my actual application it
> would be nice to do this between scenario teardown and setup/restart.
>
> Per your suggestion I modified my main to this:
> void main()
> {
>   OpenThreadObject* myThread = new OpenThreadObject;
>   myThread->start();
>   myThread->cancel();
>
>   // I assume the "!" in your example was an error?
>   while (myThread ->isRunning())
>   {
>      OpenThreads::Thread::microSleep(100);
>   }
>
>   myThread->start();
>
>   while (myThread->isRunning())
>   {
>      OpenThreads::Thread::microSleep(100);
>   }
> }
>
> Unfortunately it dies the same as before.  One around this that I've found is
> not use "cancel()" at all but to create my own cancel mechanise like this 
> (from
> my actual app):
>
> void DatabaseThread::TerminateThread()
> {
>   if (OpenThreads::Thread::CurrentThread() != this)
>   {
>      // Block until the thread is canceled
>      if (isRunning())
>      {
>         // mShouldTerminate is an atomic var that is checked
>         // periodically inside run() to know when to bail out
>
>         ++mShouldTerminate;
>         join();
>         --mShouldTerminate;
>
>         // Cleaning up personal data
>         mPublicActorList.clear();
>         mPrivateActorList.clear();
>      }
>   }
>   else
>   {
>      LOG_ERROR("Trying to terminate self.");
>   }
> }
>
> I would prefer to do this the "right" way whatever that may be.
>
> Thanks,
> Michael
>
> _______________________________________________
> osg-users mailing list
> [email protected]
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to