Thanks for the info on join(), but I guess I prefer the "manual control" feeling I get by waiting in my own loop. Good to know about join() though.

Paul Martz
Skew Matrix Software LLC
_http://www.skew-matrix.com_ <http://www.skew-matrix.com/>
+1 303 859 9466



Thibault Genessay wrote:
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


_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to