Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TObjectSpy.cxx
Go to the documentation of this file.
1 // @(#)root/base:$Id$
2 // Author: Matevz Tadel 16/08/2006
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2006, 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 #include "TObjectSpy.h"
13 #include "TROOT.h"
14 #include "TVirtualMutex.h"
15 
16 /** \class TObjectRefSpy
17  \class TObjectSpy
18 \ingroup Base
19 
20 Monitors objects for deletion and reflects the deletion by reverting
21 the internal pointer to zero. When this pointer is zero we know the
22 object has been deleted. This avoids the unsafe TestBit(kNotDeleted)
23 hack. The spied object must have the kMustCleanup bit set otherwise
24 you will get an error.
25 */
26 
27 ClassImp(TObjectSpy);
28 ClassImp(TObjectRefSpy);
29 
30 ////////////////////////////////////////////////////////////////////////////////
31 /// Register the object that must be spied. The object must have the
32 /// kMustCleanup bit set. If the object has been deleted during a
33 /// RecusiveRemove() operation, GetObject() will return 0.
34 
35 TObjectSpy::TObjectSpy(TObject *obj, Bool_t fixMustCleanupBit) :
36  TObject(), fObj(obj), fResetMustCleanupBit(kFALSE)
37 {
38  {
39  R__LOCKGUARD(gROOTMutex);
40  gROOT->GetListOfCleanups()->Add(this);
41  }
42  if (fObj && !fObj->TestBit(kMustCleanup)) {
43  if (fixMustCleanupBit) {
44  fResetMustCleanupBit = kTRUE;
45  fObj->SetBit(kMustCleanup, kTRUE);
46  } else {
47  Error("TObjectSpy", "spied object must have the kMustCleanup bit set");
48  }
49  }
50 }
51 
52 ////////////////////////////////////////////////////////////////////////////////
53 /// Cleanup.
54 
55 TObjectSpy::~TObjectSpy()
56 {
57  if (fObj && fResetMustCleanupBit)
58  fObj->SetBit(kMustCleanup, kFALSE);
59  R__LOCKGUARD(gROOTMutex);
60  gROOT->GetListOfCleanups()->Remove(this);
61 }
62 
63 ////////////////////////////////////////////////////////////////////////////////
64 /// Sets the object pointer to zero if the object is deleted in the
65 /// RecursiveRemove() operation.
66 
67 void TObjectSpy::RecursiveRemove(TObject *obj)
68 {
69  if (obj == fObj) {
70  fObj = nullptr;
71  fResetMustCleanupBit = kFALSE;
72  }
73 }
74 
75 ////////////////////////////////////////////////////////////////////////////////
76 /// Set obj as the spy target.
77 
78 void TObjectSpy::SetObject(TObject *obj, Bool_t fixMustCleanupBit)
79 {
80  if (fObj && fResetMustCleanupBit)
81  fObj->SetBit(kMustCleanup, kFALSE);
82  fResetMustCleanupBit = kFALSE;
83 
84  fObj = obj;
85 
86  if (fObj && !fObj->TestBit(kMustCleanup)) {
87  if (fixMustCleanupBit) {
88  fResetMustCleanupBit = kTRUE;
89  fObj->SetBit(kMustCleanup, kTRUE);
90  } else {
91  Error("TObjectSpy", "spied object must have the kMustCleanup bit set");
92  }
93  }
94 }
95 
96 
97 ////////////////////////////////////////////////////////////////////////////////
98 /// Register the object that must be spied. The object must have the
99 /// kMustCleanup bit set. If the object has been deleted during a
100 /// RecusiveRemove() operation, GetObject() will return 0.
101 
102 TObjectRefSpy::TObjectRefSpy(TObject *&obj, Bool_t fixMustCleanupBit) :
103  fObj(obj), fResetMustCleanupBit(kFALSE)
104 {
105  {
106  R__LOCKGUARD(gROOTMutex);
107  gROOT->GetListOfCleanups()->Add(this);
108  }
109  if (fObj && !fObj->TestBit(kMustCleanup)) {
110  if (fixMustCleanupBit) {
111  fResetMustCleanupBit = kTRUE;
112  fObj->SetBit(kMustCleanup, kTRUE);
113  } else {
114  Error("TObjectSpy", "spied object must have the kMustCleanup bit set");
115  }
116  }
117 }
118 
119 ////////////////////////////////////////////////////////////////////////////////
120 /// Cleanup.
121 
122 TObjectRefSpy::~TObjectRefSpy()
123 {
124  if (fObj && fResetMustCleanupBit)
125  fObj->SetBit(kMustCleanup, kFALSE);
126  R__LOCKGUARD(gROOTMutex);
127  gROOT->GetListOfCleanups()->Remove(this);
128 }
129 
130 ////////////////////////////////////////////////////////////////////////////////
131 /// Sets the object pointer to zero if the object is deleted in the
132 /// RecursiveRemove() operation.
133 
134 void TObjectRefSpy::RecursiveRemove(TObject *obj)
135 {
136  if (obj == fObj) {
137  fObj = nullptr;
138  fResetMustCleanupBit = kFALSE;
139  }
140 }