Hi, I tried to change the last part of my macro in order not to call
"delete th1", as in the following lines:
  TThread::Printf("Now deleting");
  TThread::Delete(th1);
  //  delete th1; // not really needed
  //  th1 = 0;
  //  TThread::Printf("Bye bye...");
but I still have the same problem when I quit root. Anyway this should
depend on some changes from root-5.06 to root-5.08.
I hope this will help.
Best Regards.
Diego
On Wed, 8 Feb 2006, Joern Adamczewski wrote:
> Hallo ROOT TThread users,
>
> maybe the problem you observe is related to some crucial part of the
> ROOT TThread classes concerning the TThread::Delete and Cleanup() methods.
>
> We observed a similar case last year, but it seemed to depend on the
> compiler/system environment and the application if this causes a crash. I must
> admit that I did not report and discuss this with ROOT team more early,
> sorry...
>
> In dtor of your example code you do:
> > > >   TThread::Printf("Now deleting");
> > > >   TThread::Delete(th1);
> > > >   delete th1; // not really needed
> Actually, the outside pointer th1 (to TThread*) is not necessarily reset to 0
> by TThread::Delete (which invokes TThread::CleanUp() and TThread destructor)
> So delete th1 should not be used after Delete!
> The reason is some slight problem when passing the pointer th1 over to TThread
> classes (please correct me if I totally misunderstood this):
>
> In method:
> Int_t TThread::Delete(TThread *th)
> {
>    // Static method to delete the specified thread.
>
>    if (!th) return 0;
>    th->fHolder = &th;
> ...
> }
> the address of the pointer th is passed to member fHolder; this variable is
> later used in CleanUp and TThread dtor:
>
> Int_t TThread::CleanUp()
> {
>    // Static method to cleanup the calling thread.
>
>    TThread *th = Self();
>    if (!th) return 13;
>    fgThreadImp->CleanUp(&(th->fClean));
>    fgMainMutex->CleanUp();
>    fgXActMutex->CleanUp();
>    if (th->fHolder)
>       delete th;
>
>    return 0;
> }
> If CleanUp is called and fHolder is existing, thread object is deleted. OK.
> (note that pointer th here is different from th in Delete()!)
>
> Now the dtor as executed in delete:
>
> TThread::~TThread()
> {
>    // Cleanup the thread.
>
> .....
> .....
>    if (fHolder) *fHolder = 0;
> }
> The last line intends to reset outside pointer, so outside "delete th1"
> will see 0 and knows that thread is already gone.
> However, fHolder has address of local variable th in TThread::Delete, but
> is not necessarily pointing to outside variable (in your example th1)!.
> By passing arguments to methods, just the values are copied, i.e. th has
> the same value as th1, but is not the identical pointer! So I guess
> the last line of thread dtor will fail here.
>
> To achieve what I think was intended here, the Delete method should better
> look like:
> -------
> TThread::Delete(TThread** pptr)
> {
>         TThread* th=*pptr;
>         th->fHolder=pptr;
> ...
> }
> ----
> However, this would require a change of the TThread API itself. All users
> would then be forced to write
> TThread::Delete(&th1) instead TThread::Delete(th1)
> (for your example). This would affect all existing code.
>
> Perhaps somebody else has another idea what to do here?
>
> For now, best advice maybe is to recommend not deleting threads manually
> after calling the TThread::Delete...
>
> Best regards,
>
> Joern
>
> --
> /////////////////////////////////////////////////////////////////////
> // Dr. J"orn Adamczewski                    (J.Adamczewski_at_gsi.de) //
> // GO4 project team / data processing group Tel: +49-6159-71-1337  //
> // Experiment Electronics department (EE)   FAX: +49-6159-71-2986  //
> // Ges. f. SchwerIonenforschung, Planckstr.1,  D-64291 Darmstadt   //
>
Received on Wed Feb 08 2006 - 17:09:02 MET
This archive was generated by hypermail 2.2.0 : Mon Jan 01 2007 - 16:31:57 MET