Re: TThread and ROOT-5.08 (fwd)

From: Diego Faso <faso_at_to.infn.it>
Date: Wed, 8 Feb 2006 17:09:08 +0100 (MET)


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