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