Logo ROOT  
Reference Guide
TThread.cxx
Go to the documentation of this file.
1 // @(#)root/thread:$Id$
2 // Author: Fons Rademakers 02/07/97
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 //////////////////////////////////////////////////////////////////////////
13 // //
14 // TThread //
15 // //
16 // This class implements threads. A thread is an execution environment //
17 // much lighter than a process. A single process can have multiple //
18 // threads. The actual work is done via the TThreadImp class (either //
19 // TPosixThread or TWin32Thread). //
20 // //
21 //////////////////////////////////////////////////////////////////////////
22 
23 #include "RConfigure.h"
24 
25 #include "TThread.h"
26 #include "TThreadImp.h"
27 #include "TThreadFactory.h"
28 #include "TROOT.h"
29 #include "TCondition.h"
30 #include "TApplication.h"
31 #include "TVirtualPad.h"
32 #include "TMethodCall.h"
33 #include "TMutex.h"
34 #include "TTimeStamp.h"
35 #include "TInterpreter.h"
36 #include "TError.h"
37 #include "TSystem.h"
38 #include "Varargs.h"
39 #include "ThreadLocalStorage.h"
40 #include "TThreadSlots.h"
41 #include "TRWMutexImp.h"
42 #include "snprintf.h"
43 
46 TThread *TThread::fgMain = nullptr;
48 char *volatile TThread::fgXAct = nullptr;
49 TMutex *TThread::fgXActMutex = nullptr;
51 void **volatile TThread::fgXArr = nullptr;
52 volatile Int_t TThread::fgXAnb = 0;
53 volatile Int_t TThread::fgXArt = 0;
54 
55 static void CINT_alloc_lock() { gGlobalMutex->Lock(); }
56 static void CINT_alloc_unlock() { gGlobalMutex->UnLock(); }
57 
58 static TMutex *gMainInternalMutex = nullptr;
59 
62 
64 
65 extern "C" void ROOT_TThread_Initialize()
66 {
68 };
69 
70 //------------------------------------------------------------------------------
71 
72 // Set gGlobalMutex to 0 when Thread library gets unloaded
73 class TThreadTearDownGuard {
74 public:
75  TThreadTearDownGuard() { fgIsTearDown = kFALSE; }
76  ~TThreadTearDownGuard() {
77  // Note: we could insert here a wait for all thread to be finished.
78  // this is questionable though as we need to balance between fixing a
79  // user error (the thread was let lose and the caller did not explicit wait)
80  // and the risk that we can not terminate a failing process.
81 
84  gGlobalMutex = 0;
85  delete m;
88  delete imp;
89  }
90 };
91 static TThreadTearDownGuard gTearDownGuard;
92 
93 //------------------------------------------------------------------------------
94 
95 class TJoinHelper {
96 private:
97  TThread *fT;
98  TThread *fH;
99  void **fRet;
100  Long_t fRc;
101  TMutex *fM;
102  TCondition *fC;
103  Bool_t fJoined;
104 
105  static void* JoinFunc(void *p);
106 
107 public:
108  TJoinHelper(TThread *th, void **ret);
109  ~TJoinHelper();
110 
111  Int_t Join();
112 };
113 
114 ////////////////////////////////////////////////////////////////////////////////
115 /// Constructor of Thread helper class.
116 
117 TJoinHelper::TJoinHelper(TThread *th, void **ret)
118  : fT(th), fRet(ret), fRc(0), fM(new TMutex), fC(new TCondition(fM)), fJoined(kFALSE)
119 {
120  fH = new TThread("JoinHelper", JoinFunc, this);
121 }
122 
123 ////////////////////////////////////////////////////////////////////////////////
124 /// Destructor.
125 
126 TJoinHelper::~TJoinHelper()
127 {
128  delete fC;
129  delete fM;
130  delete fH;
131 }
132 
133 ////////////////////////////////////////////////////////////////////////////////
134 /// Static method which runs in a separate thread to handle thread
135 /// joins without blocking the main thread.
136 /// Return a value (zero) so that it makes a joinable thread.
137 
138 void* TJoinHelper::JoinFunc(void *p)
139 {
140  TJoinHelper *jp = (TJoinHelper*)p;
141 
142  jp->fRc = jp->fT->Join(jp->fRet);
143 
144  jp->fM->Lock();
145  jp->fJoined = kTRUE;
146  jp->fC->Signal();
147  jp->fM->UnLock();
148 
149  TThread::Exit(0);
150 
151  return 0;
152 }
153 
154 ////////////////////////////////////////////////////////////////////////////////
155 /// Thread join function.
156 
157 Int_t TJoinHelper::Join()
158 {
159  fM->Lock();
160  fH->Run();
161 
162  while (kTRUE) {
163  // TimedWaitRelative will release the mutex (i.e. equivalent to fM->Unlock),
164  // then block on the condition variable. Upon return it will lock the mutex.
165  int r = fC->TimedWaitRelative(100); // 100 ms
166 
167  // From the man page from pthread_ond_timedwait:
168 
169  // When using condition variables there is always a Boolean predicate
170  // involving shared variables associated with each condition wait that
171  // is true if the thread should proceed. Spurious wakeups from the
172  // pthread_cond_timedwait() or pthread_cond_wait() functions may occur.
173  // Since the return from pthread_cond_timedwait() or pthread_cond_wait()
174  // does not imply anything about the value of this predicate, the
175  // predicate should be re-evaluated upon such return.
176 
177  if (r == 0 || r == 1) {
178  // If we received the signal or timed out, let's check the value
179  if (fJoined) break;
180  } else {
181  // If any other error occured, there is no point in trying again
182  break;
183  }
184 
186  }
187 
188  fM->UnLock();
189 
190  // And wait for the help to finish to avoid the risk that it is still
191  // running when the main tread is finished (and the thread library unloaded!)
192  TThread::fgThreadImp->Join(fH, 0);
193 
194  return fRc;
195 }
196 
197 
198 //------------------------------------------------------------------------------
199 
201 
202 
203 ////////////////////////////////////////////////////////////////////////////////
204 /// Create a thread. Specify the function or static class method
205 /// to be executed by the thread and a pointer to the argument structure.
206 /// The user function should return a void*. To start the thread call Run().
207 
208 TThread::TThread(VoidRtnFunc_t fn, void *arg, EPriority pri)
209  : TNamed("<anon>", "")
210 {
211  fDetached = kFALSE;
212  fFcnVoid = 0;
213  fFcnRetn = fn;
214  fPriority = pri;
215  fThreadArg = arg;
216  Constructor();
217  fNamed = kFALSE;
218 }
219 
220 ////////////////////////////////////////////////////////////////////////////////
221 /// Create a detached thread. Specify the function or static class method
222 /// to be executed by the thread and a pointer to the argument structure.
223 /// To start the thread call Run().
224 
225 TThread::TThread(VoidFunc_t fn, void *arg, EPriority pri)
226  : TNamed("<anon>", "")
227 {
228  fDetached = kTRUE;
229  fFcnRetn = 0;
230  fFcnVoid = fn;
231  fPriority = pri;
232  fThreadArg = arg;
233  Constructor();
234  fNamed = kFALSE;
235 }
236 
237 ////////////////////////////////////////////////////////////////////////////////
238 /// Create thread with a name. Specify the function or static class method
239 /// to be executed by the thread and a pointer to the argument structure.
240 /// The user function should return a void*. To start the thread call Run().
241 
242 TThread::TThread(const char *thname, VoidRtnFunc_t fn, void *arg,
243  EPriority pri) : TNamed(thname, "")
244 {
245  fDetached = kFALSE;
246  fFcnVoid = 0;
247  fFcnRetn = fn;
248  fPriority = pri;
249  fThreadArg = arg;
250  Constructor();
251  fNamed = kTRUE;
252 }
253 
254 ////////////////////////////////////////////////////////////////////////////////
255 /// Create a detached thread with a name. Specify the function or static
256 /// class method to be executed by the thread and a pointer to the argument
257 /// structure. To start the thread call Run().
258 
259 TThread::TThread(const char *thname, VoidFunc_t fn, void *arg,
260  EPriority pri) : TNamed(thname, "")
261 {
262  fDetached = kTRUE;
263  fFcnRetn = 0;
264  fFcnVoid = fn;
265  fPriority = pri;
266  fThreadArg = arg;
267  Constructor();
268  fNamed = kTRUE;
269 }
270 
271 ////////////////////////////////////////////////////////////////////////////////
272 /// Create a TThread for a already running thread.
273 
275 {
276  fDetached = kTRUE;
277  fFcnRetn = 0;
278  fFcnVoid = 0;
280  fThreadArg = 0;
281  Constructor();
282 
283  // Changing the id must be protected as it will be look at by multiple
284  // threads (see TThread::GetThread)
286  fNamed = kFALSE;
287  fId = (id ? id : SelfId());
290 
291  if (gDebug)
292  Info("TThread::TThread", "TThread attached to running thread");
293 }
294 
295 ////////////////////////////////////////////////////////////////////////////////
296 /// Initialize the Thread package. This initializes the TThread and ROOT
297 /// global mutexes to make parts of ROOT thread safe/aware. This call is
298 /// implicit in case a TThread is created.
299 
301 {
302  Init();
303 }
304 
305 ////////////////////////////////////////////////////////////////////////////////
306 /// Return true, if the TThread objects have been initialize. If false,
307 /// the process is (from ROOT's point of view) single threaded.
308 
310 {
311  if (fgThreadImp)
312  return kTRUE;
313  return kFALSE;
314 }
315 
316 ////////////////////////////////////////////////////////////////////////////////
317 /// Initialize global state and variables once.
318 
320 {
321  if (fgThreadImp || fgIsTearDown) return;
322 
323 #if !defined (_REENTRANT) && !defined (WIN32)
324  // Not having it means (See TVirtualMutext.h) that the LOCKGUARD macro are empty.
325  ::Fatal("Init","_REENTRANT must be #define-d for TThread to work properly.");
326 #endif
327 
328  // 'Insure' gROOT is created before initializing the Thread safe behavior
329  // (to make sure we do not have two attempting to create it).
330  ROOT::GetROOT();
331 
334 
336  fgMainMutex = new TMutex(kTRUE);
339 
340 
341  // Create the single global mutex
342  gGlobalMutex = new TMutex(kTRUE);
343  // We need to make sure that gCling is initialized.
346 
347  // To avoid deadlocks, gInterpreterMutex and gROOTMutex need
348  // to point at the same instance.
349  // Both are now deprecated in favor of ROOT::gCoreMutex
350  {
352  if (!ROOT::gCoreMutex) {
353  // To avoid dead locks, caused by shared library opening and/or static initialization
354  // taking the same lock as 'tls_get_addr_tail', we can not use UniqueLockRecurseCount.
356  }
359  }
360 }
361 
362 ////////////////////////////////////////////////////////////////////////////////
363 /// Common thread constructor.
364 
366 {
367  fHolder = 0;
368  fClean = 0;
369  fState = kNewState;
370 
371  fId = -1;
372  fHandle= 0;
373  if (!fgThreadImp) Init();
374 
375  SetComment("Constructor: MainInternalMutex Locking");
377  SetComment("Constructor: MainInternalMutex Locked");
378 
379  if (fgMain) fgMain->fPrev = this;
380  fNext = fgMain; fPrev = 0; fgMain = this;
381 
383  SetComment();
384 
385  // thread is set up in initialisation routine or Run().
386 }
387 
388 ////////////////////////////////////////////////////////////////////////////////
389 /// Cleanup the thread.
390 
392 {
393  if (gDebug)
394  Info("TThread::~TThread", "thread deleted");
395 
396  // Disconnect thread instance
397 
398  SetComment("Destructor: MainInternalMutex Locking");
400  SetComment("Destructor: MainInternalMutex Locked");
401 
402  if (fPrev) fPrev->fNext = fNext;
403  if (fNext) fNext->fPrev = fPrev;
404  if (fgMain == this) fgMain = fNext;
405 
407  SetComment();
408  if (fHolder) *fHolder = 0;
409 }
410 
411 ////////////////////////////////////////////////////////////////////////////////
412 /// Static method to delete the specified thread.
413 /// Returns -1 in case the thread was running and has been killed. Returns
414 /// 0 in case the thread has been Delete and Cleaned up. The th pointer is
415 /// not valid anymore in that case.
416 
418 {
419  if (!th) return 0;
420  th->fHolder = &th;
421 
422  if (th->fState == kRunningState) { // Cancel if running
423  th->fState = kDeletingState;
424 
425  if (gDebug)
426  th->Info("TThread::Delete", "deleting thread");
427 
428  th->Kill();
429  return -1;
430  }
431 
432  CleanUp();
433  return 0;
434 }
435 
436 ////////////////////////////////////////////////////////////////////////////////
437 /// Static method to check if threads exist.
438 /// Returns the number of running threads.
439 
441 {
443 
444  Int_t num = 0;
445  for (TThread *l = fgMain; l; l = l->fNext)
446  num++; //count threads
447 
449 
450  return num;
451 }
452 
453 ////////////////////////////////////////////////////////////////////////////////
454 /// Set thread priority.
455 
457 {
458  fPriority = pri;
459 }
460 
461 ////////////////////////////////////////////////////////////////////////////////
462 /// Static method to find a thread by id.
463 
465 {
466  TThread *myTh;
467 
469 
470  for (myTh = fgMain; myTh && (myTh->fId != id); myTh = myTh->fNext) { }
471 
473 
474  return myTh;
475 }
476 
477 ////////////////////////////////////////////////////////////////////////////////
478 /// Static method to find a thread by name.
479 
481 {
482  TThread *myTh;
483 
485 
486  for (myTh = fgMain; myTh && (strcmp(name, myTh->GetName())); myTh = myTh->fNext) { }
487 
489 
490  return myTh;
491 }
492 
493 ////////////////////////////////////////////////////////////////////////////////
494 /// Static method returning pointer to current thread.
495 
497 {
498  TTHREAD_TLS(TThread*) self = 0;
499 
500  if (!self || fgIsTearDown) {
501  if (fgIsTearDown) self = 0;
502  self = GetThread(SelfId());
503  }
504  return self;
505 }
506 
507 
508 ////////////////////////////////////////////////////////////////////////////////
509 /// Join this thread.
510 
512 {
513  if (fId == -1) {
514  Error("Join", "thread not running");
515  return -1;
516  }
517 
518  if (fDetached) {
519  Error("Join", "cannot join detached thread");
520  return -1;
521  }
522 
523  if (SelfId() != fgMainId)
524  return fgThreadImp->Join(this, ret);
525 
526  // do not block the main thread, use helper thread
527  TJoinHelper helper(this, ret);
528 
529  return helper.Join();
530 }
531 
532 ////////////////////////////////////////////////////////////////////////////////
533 /// Static method to join a thread by id.
534 
535 Long_t TThread::Join(Long_t jid, void **ret)
536 {
537  TThread *myTh = GetThread(jid);
538 
539  if (!myTh) {
540  ::Error("TThread::Join", "cannot find thread 0x%lx", jid);
541  return -1L;
542  }
543 
544  return myTh->Join(ret);
545 }
546 
547 ////////////////////////////////////////////////////////////////////////////////
548 /// Static method returning the id for the current thread.
549 
551 {
552  if (fgIsTearDown) return -1;
553  if (!fgThreadImp) Init();
554 
555  return fgThreadImp->SelfId();
556 }
557 
558 ////////////////////////////////////////////////////////////////////////////////
559 /// Start the thread. This starts the static method TThread::Function()
560 /// which calls the user function specified in the TThread ctor with
561 /// the arg argument. Returns 0 on success, otherwise an error number will
562 /// be returned.
563 
564 Int_t TThread::Run(void *arg)
565 {
566  if (arg) fThreadArg = arg;
567 
568  SetComment("Run: MainInternalMutex locking");
570  SetComment("Run: MainMutex locked");
571 
572  int iret = fgThreadImp->Run(this);
573 
575 
576  if (gDebug)
577  Info("TThread::Run", "thread run requested");
578 
580  SetComment();
581  return iret;
582 }
583 
584 ////////////////////////////////////////////////////////////////////////////////
585 /// Kill this thread. Returns 0 on success, otherwise an error number will
586 /// be returned.
587 
589 {
590  if (fState != kRunningState && fState != kDeletingState) {
591  if (gDebug)
592  Warning("TThread::Kill", "thread is not running");
593  return 13;
594  } else {
596  return fgThreadImp->Kill(this);
597  }
598 }
599 
600 ////////////////////////////////////////////////////////////////////////////////
601 /// Static method to kill the thread by id. Returns 0 on success, otherwise
602 /// an error number will be returned.
603 
605 {
606  TThread *th = GetThread(id);
607  if (th) {
608  return fgThreadImp->Kill(th);
609  } else {
610  if (gDebug)
611  ::Warning("TThread::Kill(Long_t)", "thread 0x%lx not found", id);
612  return 13;
613  }
614 }
615 
616 ////////////////////////////////////////////////////////////////////////////////
617 /// Static method to kill thread by name. Returns 0 on success, otherwise
618 /// an error number will be returned.
619 
621 {
622  TThread *th = GetThread(name);
623  if (th) {
624  return fgThreadImp->Kill(th);
625  } else {
626  if (gDebug)
627  ::Warning("TThread::Kill(const char*)", "thread %s not found", name);
628  return 13;
629  }
630 }
631 
632 ////////////////////////////////////////////////////////////////////////////////
633 /// Static method to turn off thread cancellation. Returns 0 on success,
634 /// otherwise an error number will be returned.
635 
637 {
638  return fgThreadImp ? fgThreadImp->SetCancelOff() : -1;
639 }
640 
641 ////////////////////////////////////////////////////////////////////////////////
642 /// Static method to turn on thread cancellation. Returns 0 on success,
643 /// otherwise an error number will be returned.
644 
646 {
647  return fgThreadImp ? fgThreadImp->SetCancelOn() : -1;
648 }
649 
650 ////////////////////////////////////////////////////////////////////////////////
651 /// Static method to set the cancellation response type of the calling thread
652 /// to asynchronous, i.e. cancel as soon as the cancellation request
653 /// is received.
654 
656 {
658 }
659 
660 ////////////////////////////////////////////////////////////////////////////////
661 /// Static method to set the cancellation response type of the calling thread
662 /// to deferred, i.e. cancel only at next cancellation point.
663 /// Returns 0 on success, otherwise an error number will be returned.
664 
666 {
667  return fgThreadImp ? fgThreadImp->SetCancelDeferred() : -1;
668 }
669 
670 ////////////////////////////////////////////////////////////////////////////////
671 /// Static method to set a cancellation point. Returns 0 on success, otherwise
672 /// an error number will be returned.
673 
675 {
676  return fgThreadImp ? fgThreadImp->CancelPoint() : -1;
677 }
678 
679 ////////////////////////////////////////////////////////////////////////////////
680 /// Static method which pushes thread cleanup method on stack.
681 /// Returns 0 in case of success and -1 in case of error.
682 
683 Int_t TThread::CleanUpPush(void *free, void *arg)
684 {
685  TThread *th = Self();
686  if (th)
687  return fgThreadImp->CleanUpPush(&(th->fClean), free, arg);
688  return -1;
689 }
690 
691 ////////////////////////////////////////////////////////////////////////////////
692 /// Static method which pops thread cleanup method off stack.
693 /// Returns 0 in case of success and -1 in case of error.
694 
696 {
697  TThread *th = Self();
698  if (th)
699  return fgThreadImp->CleanUpPop(&(th->fClean), exe);
700  return -1;
701 }
702 
703 ////////////////////////////////////////////////////////////////////////////////
704 /// Static method to cleanup the calling thread.
705 
707 {
708  TThread *th = Self();
709  if (!th) return 13;
710 
711  fgThreadImp->CleanUp(&(th->fClean));
712  fgMainMutex->CleanUp();
713  if (fgXActMutex)
714  fgXActMutex->CleanUp();
715 
717 
718  if (th->fHolder)
719  delete th;
720 
721  return 0;
722 }
723 
724 ////////////////////////////////////////////////////////////////////////////////
725 /// Static method which is called after the thread has been canceled.
726 
728 {
729  if (th) {
730  th->fState = kCanceledState;
731  if (gDebug)
732  th->Info("TThread::AfterCancel", "thread is canceled");
733  } else
734  ::Error("TThread::AfterCancel", "zero thread pointer passed");
735 }
736 
737 ////////////////////////////////////////////////////////////////////////////////
738 /// Static method which terminates the execution of the calling thread.
739 
741 {
742  return fgThreadImp ? fgThreadImp->Exit(ret) : -1;
743 }
744 
745 ////////////////////////////////////////////////////////////////////////////////
746 /// Static method to sleep the calling thread.
747 
749 {
750  UInt_t ms = UInt_t(secs * 1000) + UInt_t(nanos / 1000000);
751  if (gSystem) gSystem->Sleep(ms);
752  return 0;
753 }
754 
755 ////////////////////////////////////////////////////////////////////////////////
756 /// Static method to get the current time. Returns
757 /// the number of seconds.
758 
759 Int_t TThread::GetTime(ULong_t *absSec, ULong_t *absNanoSec)
760 {
761  TTimeStamp t;
762  if (absSec) *absSec = t.GetSec();
763  if (absNanoSec) *absNanoSec = t.GetNanoSec();
764  return t.GetSec();
765 }
766 
767 ////////////////////////////////////////////////////////////////////////////////
768 /// Static method to lock the main thread mutex.
769 
771 {
772  return (fgMainMutex ? fgMainMutex->Lock() : 0);
773 }
774 
775 ////////////////////////////////////////////////////////////////////////////////
776 /// Static method to try to lock the main thread mutex.
777 
779 {
780  return (fgMainMutex ? fgMainMutex->TryLock() : 0);
781 }
782 
783 ////////////////////////////////////////////////////////////////////////////////
784 /// Static method to unlock the main thread mutex.
785 
787 {
788  return (fgMainMutex ? fgMainMutex->UnLock() : 0);
789 }
790 
791 ////////////////////////////////////////////////////////////////////////////////
792 /// Static method which is called by the system thread function and
793 /// which in turn calls the actual user function.
794 
795 void *TThread::Function(void *ptr)
796 {
797  TThread *th;
798  void *ret, *arg;
799 
800  TThreadCleaner dummy;
801 
802  th = (TThread *)ptr;
803 
804  // Default cancel state is OFF
805  // Default cancel type is DEFERRED
806  // User can change it by call SetCancelOn() and SetCancelAsynchronous()
807  SetCancelOff();
809  CleanUpPush((void *)&AfterCancel, th); // Enable standard cancelling function
810 
811  if (gDebug)
812  th->Info("TThread::Function", "thread is running");
813 
814  arg = th->fThreadArg;
815  th->fState = kRunningState;
816 
817  if (th->fDetached) {
818  //Detached, non joinable thread
819  (th->fFcnVoid)(arg);
820  ret = 0;
821  th->fState = kFinishedState;
822  } else {
823  //UnDetached, joinable thread
824  ret = (th->fFcnRetn)(arg);
825  th->fState = kTerminatedState;
826  }
827 
828  CleanUpPop(1); // Disable standard canceling function
829 
830  if (gDebug)
831  th->Info("TThread::Function", "thread has finished");
832 
833  TThread::Exit(ret);
834 
835  return ret;
836 }
837 
838 ////////////////////////////////////////////////////////////////////////////////
839 /// Static method listing the existing threads.
840 
842 {
843  TThread *l;
844  int i;
845 
846  if (!fgMain) {
847  ::Info("TThread::Ps", "no threads have been created");
848  return;
849  }
850 
852 
853  int num = 0;
854  for (l = fgMain; l; l = l->fNext)
855  num++;
856 
857  char cbuf[256];
858  printf(" Thread State\n");
859  for (l = fgMain; l; l = l->fNext) { // loop over threads
860  memset(cbuf, ' ', sizeof(cbuf));
861  snprintf(cbuf, sizeof(cbuf), "%3d %s:0x%lx", num--, l->GetName(), l->fId);
862  i = strlen(cbuf);
863  if (i < 30)
864  cbuf[i] = ' ';
865  cbuf[30] = 0;
866  printf("%30s", cbuf);
867 
868  switch (l->fState) { // print states
869  case kNewState: printf("Idle "); break;
870  case kRunningState: printf("Running "); break;
871  case kTerminatedState: printf("Terminated "); break;
872  case kFinishedState: printf("Finished "); break;
873  case kCancelingState: printf("Canceling "); break;
874  case kCanceledState: printf("Canceled "); break;
875  case kDeletingState: printf("Deleting "); break;
876  default: printf("Invalid ");
877  }
878  if (l->fComment[0]) printf(" // %s", l->fComment);
879  printf("\n");
880  } // end of loop
881 
883 }
884 
885 ////////////////////////////////////////////////////////////////////////////////
886 /// Static method returning a pointer to thread specific data container
887 /// of the calling thread.
888 /// k should be between 0 and kMaxUserThreadSlot for user application.
889 /// (and between kMaxUserThreadSlot and kMaxThreadSlot for ROOT libraries).
890 /// See ROOT::EThreadSlotReservation
891 
892 void **TThread::Tsd(void *dflt, Int_t k)
893 {
894  if (TThread::SelfId() == fgMainId) { //Main thread
895  return (void**)dflt;
896  } else {
897  return GetTls(k);
898  }
899 }
900 
901 ////////////////////////////////////////////////////////////////////////////////
902 /// Static method that initializes the TLS array of a thread and returns the
903 /// reference to a given position in that array.
904 
906  TTHREAD_TLS_ARRAY(void*, ROOT::kMaxThreadSlot, tls);
907 
908  // In order for the thread 'gDirectory' value to be properly
909  // initialized we set it now (otherwise it defaults
910  // to zero which is 'unexpected')
911  // We initialize it to gROOT rather than gDirectory, since
912  // TFile are currently expected to not be shared by two threads.
913  if (k == ROOT::kDirectoryThreadSlot && tls[k] == nullptr)
914  tls[k] = gROOT;
915 
916  return &(tls[k]);
917 }
918 
919 ////////////////////////////////////////////////////////////////////////////////
920 /// Static method providing a thread safe printf. Appends a newline.
921 
922 void TThread::Printf(const char *va_(fmt), ...)
923 {
924  va_list ap;
925  va_start(ap,va_(fmt));
926 
927  Int_t buf_size = 2048;
928  char *buf;
929 
930 again:
931  buf = new char[buf_size];
932 
933  int n = vsnprintf(buf, buf_size, va_(fmt), ap);
934  // old vsnprintf's return -1 if string is truncated new ones return
935  // total number of characters that would have been written
936  if (n == -1 || n >= buf_size) {
937  buf_size *= 2;
938  delete [] buf;
939  goto again;
940  }
941 
942  va_end(ap);
943 
944  void *arr[2];
945  arr[1] = (void*) buf;
946  if (XARequest("PRTF", 2, arr, 0)) return;
947 
948  printf("%s\n", buf);
949  fflush(stdout);
950 
951  delete [] buf;
952 }
953 
954 ////////////////////////////////////////////////////////////////////////////////
955 /// Thread specific error handler function.
956 /// It calls the user set error handler in the main thread.
957 
958 void TThread::ErrorHandler(int level, const char *location, const char *fmt,
959  va_list ap) const
960 {
961  Int_t buf_size = 2048;
962  char *buf, *bp;
963 
964 again:
965  buf = new char[buf_size];
966 
967  int n = vsnprintf(buf, buf_size, fmt, ap);
968  // old vsnprintf's return -1 if string is truncated new ones return
969  // total number of characters that would have been written
970  if (n == -1 || n >= buf_size) {
971  buf_size *= 2;
972  delete [] buf;
973  goto again;
974  }
975  if (level >= kSysError && level < kFatal) {
976  char *buf1 = new char[buf_size + strlen(gSystem->GetError()) + 5];
977  sprintf(buf1, "%s (%s)", buf, gSystem->GetError());
978  bp = buf1;
979  delete [] buf;
980  } else
981  bp = buf;
982 
983  void *arr[4];
984  arr[1] = (void*) Long_t(level);
985  arr[2] = (void*) location;
986  arr[3] = (void*) bp;
987  if (XARequest("ERRO", 4, arr, 0)) return;
988 
989  if (level != kFatal)
990  ::GetErrorHandler()(level, level >= gErrorAbortLevel, location, bp);
991  else
992  ::GetErrorHandler()(level, kTRUE, location, bp);
993 
994  delete [] bp;
995 }
996 
997 ////////////////////////////////////////////////////////////////////////////////
998 /// Interface to ErrorHandler. User has to specify the class name as
999 /// part of the location, just like for the global Info(), Warning() and
1000 /// Error() functions.
1001 
1002 void TThread::DoError(int level, const char *location, const char *fmt,
1003  va_list va) const
1004 {
1005  char *loc = 0;
1006 
1007  if (location) {
1008  loc = new char[strlen(location) + strlen(GetName()) + 32];
1009  sprintf(loc, "%s %s:0x%lx", location, GetName(), fId);
1010  } else {
1011  loc = new char[strlen(GetName()) + 32];
1012  sprintf(loc, "%s:0x%lx", GetName(), fId);
1013  }
1014 
1015  ErrorHandler(level, loc, fmt, va);
1016 
1017  delete [] loc;
1018 }
1019 
1020 ////////////////////////////////////////////////////////////////////////////////
1021 /// Static method used to allow commands to be executed by the main thread.
1022 
1023 Int_t TThread::XARequest(const char *xact, Int_t nb, void **ar, Int_t *iret)
1024 {
1025  if (!gApplication || !gApplication->IsRunning()) return 0;
1026 
1027  // The first time, create the related static vars
1028  if (!fgXActMutex && gGlobalMutex) {
1029  gGlobalMutex->Lock();
1030  if (!fgXActMutex) {
1031  fgXActMutex = new TMutex(kTRUE);
1032  fgXActCondi = new TCondition;
1033  new TThreadTimer;
1034  }
1035  gGlobalMutex->UnLock();
1036  }
1037 
1038  TThread *th = Self();
1039  if (th && th->fId != fgMainId) { // we are in the thread
1040  th->SetComment("XARequest: XActMutex Locking");
1041  fgXActMutex->Lock();
1042  th->SetComment("XARequest: XActMutex Locked");
1043 
1045  TMutexImp *condmutex = fgXActCondi->GetMutex()->fMutexImp;
1046 
1047  // Lock now, so the XAction signal will wait
1048  // and never come before the wait
1049  condmutex->Lock();
1050 
1051  fgXAnb = nb;
1052  fgXArr = ar;
1053  fgXArt = 0;
1054  fgXAct = (char*) xact;
1055  th->SetComment(fgXAct);
1056 
1057  if (condimp) condimp->Wait();
1058  condmutex->UnLock();
1059 
1060  if (iret) *iret = fgXArt;
1061  fgXActMutex->UnLock();
1062  th->SetComment();
1063  return 1997;
1064  } else //we are in the main thread
1065  return 0;
1066 }
1067 
1068 ////////////////////////////////////////////////////////////////////////////////
1069 /// Static method called via the thread timer to execute in the main
1070 /// thread certain commands. This to avoid sophisticated locking and
1071 /// possible deadlocking.
1072 
1074 {
1076  TMutexImp *condmutex = fgXActCondi->GetMutex()->fMutexImp;
1077  condmutex->Lock();
1078 
1079  char const acts[] = "PRTF CUPD CANV CDEL PDCD METH ERRO";
1080  enum { kPRTF = 0, kCUPD = 5, kCANV = 10, kCDEL = 15,
1081  kPDCD = 20, kMETH = 25, kERRO = 30 };
1082  int iact = strstr(acts, fgXAct) - acts;
1083  char *cmd = 0;
1084 
1085  switch (iact) {
1086 
1087  case kPRTF:
1088  printf("%s\n", (const char*)fgXArr[1]);
1089  fflush(stdout);
1090  break;
1091 
1092  case kERRO:
1093  {
1094  int level = (int)Long_t(fgXArr[1]);
1095  const char *location = (const char*)fgXArr[2];
1096  char *mess = (char*)fgXArr[3];
1097  if (level != kFatal)
1098  GetErrorHandler()(level, level >= gErrorAbortLevel, location, mess);
1099  else
1100  GetErrorHandler()(level, kTRUE, location, mess);
1101  delete [] mess;
1102  }
1103  break;
1104 
1105  case kCUPD:
1106  //((TCanvas *)fgXArr[1])->Update();
1107  union CastFromFuncToVoidPtr_t {
1108  void (*fFuncPtr)(void*);
1109  void* fVoidPtr;
1110  } castFromFuncToVoidPtr;
1111  castFromFuncToVoidPtr.fVoidPtr = fgXArr[2];
1112  (*castFromFuncToVoidPtr.fFuncPtr)(fgXArr[1]); // aka TCanvas::Update()
1113  break;
1114 
1115  case kCANV:
1116 
1117  switch(fgXAnb) { // Over TCanvas constructors
1118 
1119  case 2:
1120  //((TCanvas*)fgXArr[1])->Constructor();
1121  cmd = Form("((TCanvas *)0x%lx)->Constructor();",(Long_t)fgXArr[1]);
1122  gROOT->ProcessLine(cmd);
1123  break;
1124 
1125  case 5:
1126  //((TCanvas*)fgXArr[1])->Constructor(
1127  // (char*)fgXArr[2],
1128  // (char*)fgXArr[3],
1129  // *((Int_t*)(fgXArr[4])));
1130  cmd = Form("((TCanvas *)0x%lx)->Constructor((char*)0x%lx,(char*)0x%lx,*((Int_t*)(0x%lx)));",(Long_t)fgXArr[1],(Long_t)fgXArr[2],(Long_t)fgXArr[3],(Long_t)fgXArr[4]);
1131  gROOT->ProcessLine(cmd);
1132  break;
1133  case 6:
1134  //((TCanvas*)fgXArr[1])->Constructor(
1135  // (char*)fgXArr[2],
1136  // (char*)fgXArr[3],
1137  // *((Int_t*)(fgXArr[4])),
1138  // *((Int_t*)(fgXArr[5])));
1139  cmd = Form("((TCanvas *)0x%lx)->Constructor((char*)0x%lx,(char*)0x%lx,*((Int_t*)(0x%lx)),*((Int_t*)(0x%lx)));",(Long_t)fgXArr[1],(Long_t)fgXArr[2],(Long_t)fgXArr[3],(Long_t)fgXArr[4],(Long_t)fgXArr[5]);
1140  gROOT->ProcessLine(cmd);
1141  break;
1142 
1143  case 8:
1144  //((TCanvas*)fgXArr[1])->Constructor(
1145  // (char*)fgXArr[2],
1146  // (char*)fgXArr[3],
1147  // *((Int_t*)(fgXArr[4])),
1148  // *((Int_t*)(fgXArr[5])),
1149  // *((Int_t*)(fgXArr[6])),
1150  // *((Int_t*)(fgXArr[7])));
1151  cmd = Form("((TCanvas *)0x%lx)->Constructor((char*)0x%lx,(char*)0x%lx,*((Int_t*)(0x%lx)),*((Int_t*)(0x%lx)),*((Int_t*)(0x%lx)),*((Int_t*)(0x%lx)));",(Long_t)fgXArr[1],(Long_t)fgXArr[2],(Long_t)fgXArr[3],(Long_t)fgXArr[4],(Long_t)fgXArr[5],(Long_t)fgXArr[6],(Long_t)fgXArr[7]);
1152  gROOT->ProcessLine(cmd);
1153  break;
1154 
1155  }
1156  break;
1157 
1158  case kCDEL:
1159  //((TCanvas*)fgXArr[1])->Destructor();
1160  cmd = Form("((TCanvas *)0x%lx)->Destructor();",(Long_t)fgXArr[1]);
1161  gROOT->ProcessLine(cmd);
1162  break;
1163 
1164  case kPDCD:
1165  ((TVirtualPad*) fgXArr[1])->Divide( *((Int_t*)(fgXArr[2])),
1166  *((Int_t*)(fgXArr[3])),
1167  *((Float_t*)(fgXArr[4])),
1168  *((Float_t*)(fgXArr[5])),
1169  *((Int_t*)(fgXArr[6])));
1170  break;
1171  case kMETH:
1172  ((TMethodCall *) fgXArr[1])->Execute((void*)(fgXArr[2]),(const char*)(fgXArr[3]));
1173  break;
1174 
1175  default:
1176  ::Error("TThread::XAction", "wrong case");
1177  }
1178 
1179  fgXAct = 0;
1180  if (condimp) condimp->Signal();
1181  condmutex->UnLock();
1182 }
1183 
1184 
1185 //////////////////////////////////////////////////////////////////////////
1186 // //
1187 // TThreadTimer //
1188 // //
1189 //////////////////////////////////////////////////////////////////////////
1190 
1191 ////////////////////////////////////////////////////////////////////////////////
1192 /// Create thread timer.
1193 
1195 {
1196  gSystem->AddTimer(this);
1197 }
1198 
1199 ////////////////////////////////////////////////////////////////////////////////
1200 /// Periodically execute the TThread::XAxtion() method in the main thread.
1201 
1203 {
1204  if (TThread::fgXAct) { TThread::XAction(); }
1205  Reset();
1206 
1207  return kFALSE;
1208 }
1209 
1210 
1211 //////////////////////////////////////////////////////////////////////////
1212 // //
1213 // TThreadCleaner //
1214 // //
1215 //////////////////////////////////////////////////////////////////////////
1216 
1217 ////////////////////////////////////////////////////////////////////////////////
1218 /// Call user clean up routines.
1219 
1221 {
1222  TThread::CleanUp();
1223 }
kSysError
const Int_t kSysError
Definition: TError.h:50
l
auto * l
Definition: textangle.C:4
TThread::fNext
TThread * fNext
Definition: TThread.h:74
m
auto * m
Definition: textangle.C:8
kFatal
const Int_t kFatal
Definition: TError.h:51
n
const Int_t n
Definition: legend1.C:16
TThreadImp::CancelPoint
virtual Int_t CancelPoint()=0
TThread
Definition: TThread.h:40
kTRUE
const Bool_t kTRUE
Definition: RtypesCore.h:91
TThreadFactory::CreateThreadImp
virtual TThreadImp * CreateThreadImp()=0
ThreadInternalUnLock
static void ThreadInternalUnLock()
Definition: TThread.cxx:61
TInterpreter::Instance
static TInterpreter * Instance()
returns gInterpreter global
Definition: TInterpreter.cxx:58
TMutexImp::UnLock
virtual Int_t UnLock()=0
snprintf
#define snprintf
Definition: civetweb.c:1540
TCondition::fConditionImp
TConditionImp * fConditionImp
Definition: TCondition.h:37
TThread::TJoinHelper
friend class TJoinHelper
Definition: TThread.h:48
TMutex::CleanUp
Int_t CleanUp()
Clean up of mutex.
Definition: TMutex.cxx:76
TThread::Tsd
static void ** Tsd(void *dflt, Int_t k)
Static method returning a pointer to thread specific data container of the calling thread.
Definition: TThread.cxx:892
TRWMutexImp.h
TMutexImp::Lock
virtual Int_t Lock()=0
TThread::fFcnVoid
VoidFunc_t fFcnVoid
Definition: TThread.h:85
TTimeStamp.h
TMutex::Lock
Int_t Lock()
Lock the mutex.
Definition: TMutex.cxx:46
TThread::SetPriority
void SetPriority(EPriority pri)
Set thread priority.
Definition: TThread.cxx:456
TThread::Exit
static Int_t Exit(void *ret=0)
Static method which terminates the execution of the calling thread.
Definition: TThread.cxx:740
TThread::DoError
void DoError(Int_t level, const char *location, const char *fmt, va_list va) const
Interface to ErrorHandler.
Definition: TThread.cxx:1002
ClassImp
#define ClassImp(name)
Definition: Rtypes.h:364
Form
char * Form(const char *fmt,...)
GetErrorHandler
ErrorHandlerFunc_t GetErrorHandler()
Returns the current error handler function.
Definition: TError.cxx:102
r
ROOT::R::TRInterface & r
Definition: Object.C:4
TCondition.h
TThreadTimer::Notify
Bool_t Notify()
Periodically execute the TThread::XAxtion() method in the main thread.
Definition: TThread.cxx:1202
TTimeStamp::GetSec
time_t GetSec() const
Definition: TTimeStamp.h:135
TObject::Info
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:864
TObject::Error
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:890
TThread::GetThread
static TThread * GetThread(Long_t id)
Static method to find a thread by id.
Definition: TThread.cxx:464
TInterpreter::SetAlloclockfunc
virtual void SetAlloclockfunc(void(*)()) const
Definition: TInterpreter.h:264
TThread::fPrev
TThread * fPrev
Definition: TThread.h:75
TThread::fState
EState fState
Definition: TThread.h:78
TThread::fNamed
Bool_t fNamed
Definition: TThread.h:83
TThreadImp::CleanUp
virtual Int_t CleanUp(void **main)=0
TThread::CancelPoint
static Int_t CancelPoint()
Static method to set a cancellation point.
Definition: TThread.cxx:674
TThread::TryLock
static Int_t TryLock()
Static method to try to lock the main thread mutex.
Definition: TThread.cxx:778
TThread::fgMainMutex
static TMutex * fgMainMutex
Definition: TThread.h:97
Float_t
float Float_t
Definition: RtypesCore.h:57
TThread::TThreadTimer
friend class TThreadTimer
Definition: TThread.h:44
TThread::fPriority
EPriority fPriority
Definition: TThread.h:77
TThreadImp::CleanUpPop
virtual Int_t CleanUpPop(void **main, Int_t exe)=0
TObject::Fatal
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition: TObject.cxx:918
Int_t
int Int_t
Definition: RtypesCore.h:45
TVirtualMutex
This class implements a mutex interface.
Definition: TVirtualMutex.h:32
TCondition
Definition: TCondition.h:32
TSystem::GetError
virtual const char * GetError()
Return system error string.
Definition: TSystem.cxx:251
va_
#define va_(arg)
Definition: Varargs.h:41
TThread::fgXArr
static void **volatile fgXArr
Definition: TThread.h:92
CINT_alloc_unlock
static void CINT_alloc_unlock()
Definition: TThread.cxx:56
ROOT::gCoreMutex
R__EXTERN TVirtualRWMutex * gCoreMutex
Definition: TVirtualRWMutex.h:32
TThread::UnLock
static Int_t UnLock()
Static method to unlock the main thread mutex.
Definition: TThread.cxx:786
ROOT::GetROOT
TROOT * GetROOT()
Definition: TROOT.cxx:465
TMutex::UnLock
Int_t UnLock()
Unlock the mutex.
Definition: TMutex.cxx:68
TThread::Ps
static void Ps()
Static method listing the existing threads.
Definition: TThread.cxx:841
TThread::kCanceledState
@ kCanceledState
Definition: TThread.h:69
Varargs.h
gGlobalMutex
R__EXTERN TVirtualMutex * gGlobalMutex
Definition: TVirtualMutex.h:27
Bool_t
bool Bool_t
Definition: RtypesCore.h:63
TThread::fgMain
static TThread * fgMain
Definition: TThread.h:96
TSystem::AddTimer
virtual void AddTimer(TTimer *t)
Add timer to list of system timers.
Definition: TSystem.cxx:472
TThreadFactory.h
bool
TThreadSlots.h
TThreadImp::CleanUpPush
virtual Int_t CleanUpPush(void **main, void *free, void *arg)=0
id
XFontStruct * id
Definition: TGX11.cxx:109
TApplication::IsRunning
Bool_t IsRunning() const
Definition: TApplication.h:148
TThread::fgXAnb
static volatile Int_t fgXAnb
Definition: TThread.h:93
TROOT.h
TThread::SetComment
void SetComment(const char *txt=0)
Definition: TThread.h:103
TThread::Delete
void Delete(Option_t *option="")
Delete this object.
Definition: TThread.h:127
TThread::Join
Long_t Join(void **ret=0)
Join this thread.
Definition: TThread.cxx:511
TThread::Run
Int_t Run(void *arg=0)
Start the thread.
Definition: TThread.cxx:564
TThread::~TThread
virtual ~TThread()
Cleanup the thread.
Definition: TThread.cxx:391
TApplication.h
TThread::fgXActMutex
static TMutex * fgXActMutex
Definition: TThread.h:98
TInterpreter::SetAllocunlockfunc
virtual void SetAllocunlockfunc(void(*)()) const
Definition: TInterpreter.h:265
TThread::GetTls
static void ** GetTls(Int_t k)
Static method that initializes the TLS array of a thread and returns the reference to a given positio...
Definition: TThread.cxx:905
gTearDownGuard
static TThreadTearDownGuard gTearDownGuard
Definition: TThread.cxx:91
TThread::SetCancelDeferred
static Int_t SetCancelDeferred()
Static method to set the cancellation response type of the calling thread to deferred,...
Definition: TThread.cxx:665
TTimer
Handles synchronous and a-synchronous timer events.
Definition: TTimer.h:51
ROOT::TRWMutexImp
Definition: TRWMutexImp.h:22
TThread::kDeletingState
@ kDeletingState
Definition: TThread.h:70
gThreadFactory
R__EXTERN TThreadFactory * gThreadFactory
Definition: TThreadFactory.h:45
TThread::CleanUpPush
static Int_t CleanUpPush(void *free, void *arg=0)
Static method which pushes thread cleanup method on stack.
Definition: TThread.cxx:683
TConditionImp::Signal
virtual Int_t Signal()=0
TSystem.h
gInterpreterMutex
R__EXTERN TVirtualMutex * gInterpreterMutex
Definition: TInterpreter.h:44
TTimeStamp::GetNanoSec
Int_t GetNanoSec() const
Definition: TTimeStamp.h:136
TThread::fId
Long_t fId
Definition: TThread.h:80
TThread::fgXActCondi
static TCondition * fgXActCondi
Definition: TThread.h:99
gROOTMutex
R__EXTERN TVirtualMutex * gROOTMutex
Definition: TROOT.h:61
TThread::Self
static TThread * Self()
Static method returning pointer to current thread.
Definition: TThread.cxx:496
CINT_alloc_lock
static void CINT_alloc_lock()
Definition: TThread.cxx:55
TThread::kNormalPriority
@ kNormalPriority
Definition: TThread.h:57
TMutex::fMutexImp
TMutexImp * fMutexImp
Definition: TMutex.h:36
TThread::kTerminatedState
@ kTerminatedState
Definition: TThread.h:65
TThreadImp::SelfId
virtual Long_t SelfId()=0
TMutex.h
TConditionImp::Wait
virtual Int_t Wait()=0
TThread::AfterCancel
static void AfterCancel(TThread *th)
Static method which is called after the thread has been canceled.
Definition: TThread.cxx:727
TThread::Function
static void * Function(void *ptr)
Static method which is called by the system thread function and which in turn calls the actual user f...
Definition: TThread.cxx:795
ROOT::kMaxThreadSlot
@ kMaxThreadSlot
Definition: TThreadSlots.h:35
TThread::SetCancelAsynchronous
static Int_t SetCancelAsynchronous()
Static method to set the cancellation response type of the calling thread to asynchronous,...
Definition: TThread.cxx:655
TNamed
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
TMutex::TryLock
Int_t TryLock()
Try to lock mutex.
Definition: TMutex.cxx:57
TThread::fHolder
TThread ** fHolder
Definition: TThread.h:76
kFALSE
const Bool_t kFALSE
Definition: RtypesCore.h:92
TThread::Exists
static Int_t Exists()
Static method to check if threads exist.
Definition: TThread.cxx:440
ThreadInternalLock
static void ThreadInternalLock()
Definition: TThread.cxx:60
TThread::XAction
static void XAction()
Static method called via the thread timer to execute in the main thread certain commands.
Definition: TThread.cxx:1073
TThread::GetTime
static Int_t GetTime(ULong_t *absSec, ULong_t *absNanoSec)
Static method to get the current time.
Definition: TThread.cxx:759
Long_t
long Long_t
Definition: RtypesCore.h:54
TThread::fgXArt
static volatile Int_t fgXArt
Definition: TThread.h:94
TThread::fDetached
Bool_t fDetached
Definition: TThread.h:82
ROOT_TThread_Initialize
void ROOT_TThread_Initialize()
Definition: TThread.cxx:65
gApplication
R__EXTERN TApplication * gApplication
Definition: TApplication.h:166
TThread::kInvalidState
@ kInvalidState
Definition: TThread.h:62
TThreadCleaner::~TThreadCleaner
~TThreadCleaner()
Call user clean up routines.
Definition: TThread.cxx:1220
gDebug
Int_t gDebug
Definition: TROOT.cxx:590
R__LOCKGUARD
#define R__LOCKGUARD(mutex)
Definition: TVirtualMutex.h:104
TVirtualPad.h
TVirtualMutex::Lock
virtual Int_t Lock()=0
UInt_t
unsigned int UInt_t
Definition: RtypesCore.h:46
TThread::fgXAct
static char *volatile fgXAct
Definition: TThread.h:91
TThread::SetCancelOn
static Int_t SetCancelOn()
Static method to turn on thread cancellation.
Definition: TThread.cxx:645
TThread::fFcnRetn
VoidRtnFunc_t fFcnRetn
Definition: TThread.h:84
ULong_t
unsigned long ULong_t
Definition: RtypesCore.h:55
fgIsTearDown
static Bool_t fgIsTearDown(kFALSE)
TSystem::Sleep
virtual void Sleep(UInt_t milliSec)
Sleep milliSec milli seconds.
Definition: TSystem.cxx:438
gErrorAbortLevel
R__EXTERN Int_t gErrorAbortLevel
Definition: TError.h:130
TThread::fgMainId
static Long_t fgMainId
Definition: TThread.h:95
TObject::Warning
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:876
TThread::ErrorHandler
void ErrorHandler(int level, const char *location, const char *fmt, va_list ap) const
Thread specific error handler function.
Definition: TThread.cxx:958
TThreadImp
Definition: TThreadImp.h:31
void
typedef void((*Func_t)())
TThread::Sleep
static Int_t Sleep(ULong_t secs, ULong_t nanos=0)
Static method to sleep the calling thread.
Definition: TThread.cxx:748
unsigned int
TThread::Initialize
static void Initialize()
Initialize the Thread package.
Definition: TThread.cxx:300
ROOT::kDirectoryThreadSlot
@ kDirectoryThreadSlot
Definition: TThreadSlots.h:31
gSystem
R__EXTERN TSystem * gSystem
Definition: TSystem.h:559
TThread.h
TThread::fThreadArg
void * fThreadArg
Definition: TThread.h:86
TThread::kCancelingState
@ kCancelingState
Definition: TThread.h:68
TThreadImp::Join
virtual Int_t Join(TThread *th, void **ret)=0
TVirtualPad
TVirtualPad is an abstract base class for the Pad and Canvas classes.
Definition: TVirtualPad.h:51
TVirtualMutex::UnLock
virtual Int_t UnLock()=0
TThreadImp::SetCancelDeferred
virtual Int_t SetCancelDeferred()=0
TThread::Init
static void Init()
Initialize global state and variables once.
Definition: TThread.cxx:319
TConditionImp
Definition: TConditionImp.h:26
TThread::SetCancelOff
static Int_t SetCancelOff()
Static method to turn off thread cancellation.
Definition: TThread.cxx:636
TInterpreter.h
TThreadImp::SetCancelOff
virtual Int_t SetCancelOff()=0
gCling
R__EXTERN TInterpreter * gCling
Definition: TInterpreter.h:561
TThread::fHandle
Long_t fHandle
Definition: TThread.h:81
gMainInternalMutex
static TMutex * gMainInternalMutex
Definition: TThread.cxx:58
TThread::Printf
static void Printf(const char *fmt,...)
Static method providing a thread safe printf. Appends a newline.
Definition: TThread.cxx:922
TMutexImp
Definition: TMutexImp.h:27
TThread::IsInitialized
static Bool_t IsInitialized()
Return true, if the TThread objects have been initialize.
Definition: TThread.cxx:309
name
char name[80]
Definition: TGX11.cxx:110
TThread::kFinishedState
@ kFinishedState
Definition: TThread.h:67
TThreadImp::Kill
virtual Int_t Kill(TThread *th)=0
TThread::SelfId
static Long_t SelfId()
Static method returning the id for the current thread.
Definition: TThread.cxx:550
gThreadTsd
R__EXTERN void **(* gThreadTsd)(void *, Int_t)
Definition: TThreadSlots.h:40
TThread::fgThreadImp
static TThreadImp * fgThreadImp
Definition: TThread.h:90
TThreadImp.h
TThread::EPriority
EPriority
Definition: TThread.h:55
TThreadImp::Exit
virtual Int_t Exit(void *ret)=0
TMethodCall
Method or function calling interface.
Definition: TMethodCall.h:37
TGeant4Unit::ms
static constexpr double ms
Definition: TGeant4SystemOfUnits.h:163
TThread::XARequest
static Int_t XARequest(const char *xact, Int_t nb, void **ar, Int_t *iret)
Static method used to allow commands to be executed by the main thread.
Definition: TThread.cxx:1023
TThread::Lock
static Int_t Lock()
Static method to lock the main thread mutex.
Definition: TThread.cxx:770
TNamed::GetName
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
gThreadXAR
R__EXTERN Int_t(* gThreadXAR)(const char *xact, Int_t nb, void **ar, Int_t *iret)
Definition: TVirtualPad.h:289
TThread::kRunningState
@ kRunningState
Definition: TThread.h:64
free
#define free
Definition: civetweb.c:1539
TTimeStamp
The TTimeStamp encapsulates seconds and ns since EPOCH.
Definition: TTimeStamp.h:71
TThread::Constructor
void Constructor()
Common thread constructor.
Definition: TThread.cxx:365
TTimer::Reset
void Reset()
Reset the timer.
Definition: TTimer.cxx:157
TThread::TThread
TThread(const TThread &)
TMutex
Definition: TMutex.h:30
TThreadImp::SetCancelOn
virtual Int_t SetCancelOn()=0
TThreadImp::Run
virtual Int_t Run(TThread *th)=0
TThreadTimer::TThreadTimer
TThreadTimer(Long_t ms=kItimerResolution+10)
Create thread timer.
Definition: TThread.cxx:1194
TSystem::ProcessEvents
virtual Bool_t ProcessEvents()
Process pending events (GUI, timers, sockets).
Definition: TSystem.cxx:417
ThreadLocalStorage.h
TThread::Kill
Int_t Kill()
Kill this thread.
Definition: TThread.cxx:588
TThreadCleaner
Definition: TThread.h:190
TThread::CleanUp
static Int_t CleanUp()
Static method to cleanup the calling thread.
Definition: TThread.cxx:706
TThread::kNewState
@ kNewState
Definition: TThread.h:63
TThreadImp::SetCancelAsynchronous
virtual Int_t SetCancelAsynchronous()=0
gROOT
#define gROOT
Definition: TROOT.h:406
int
TThread::fClean
void * fClean
Definition: TThread.h:87
Error
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition: TError.cxx:187
TThread::CleanUpPop
static Int_t CleanUpPop(Int_t exe=0)
Static method which pops thread cleanup method off stack.
Definition: TThread.cxx:695
TError.h
TCondition::GetMutex
TMutex * GetMutex() const
Get internally created mutex.
Definition: TCondition.cxx:65
TMethodCall.h