ATLAS Offline Software
PyROOTTypePatch.cxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration.
3  */
13 
15 #include "Rtypes.h"
16 #include "TGenericClassInfo.h"
17 #include "TClass.h"
18 #include "TROOT.h"
19 #include "TError.h"
20 #include "TClassTable.h"
21 #include <ctype.h>
22 #include <cassert>
23 
24 
25 using ROOT::Internal::TInitBehavior;
26 using ROOT::Internal::TDefaultInitBehavior;
27 using ROOT::Internal::DefineBehavior;
28 
29 
30 //****************************************************************************
31 // This is the class creation hook.
32 //
33 
34 
35 namespace {
36 
37 
41 class TypePatchInitBehavior
42  : public TDefaultInitBehavior
43 {
44 public:
45  virtual TClass *CreateClass(const char *cname, Version_t id,
46  const std::type_info &info, TVirtualIsAProxy *isa,
47  const char *dfil, const char *ifil,
48  Int_t dl, Int_t il) const;
49 
50  static TDefaultInitBehavior oldBehavior;
51  static TDefaultInitBehavior* oldBehaviorPtr;
52 };
53 TDefaultInitBehavior TypePatchInitBehavior::oldBehavior;
54 TDefaultInitBehavior* TypePatchInitBehavior::oldBehaviorPtr = 0;
55 
56 
61 TClass* TypePatchInitBehavior::CreateClass(const char *cname,
62  Version_t id,
63  const std::type_info &info,
64  TVirtualIsAProxy *isa,
65  const char *dfil,
66  const char *ifil,
67  Int_t dl,
68  Int_t il) const
69 {
70  // Do the default root behavior.
71  TClass* cl = oldBehaviorPtr->CreateClass(cname, id, info, isa,
72  dfil, ifil, dl, il);
73 
74  // Scan the new class.
76 
77  // Return it.
78  return cl;
79 }
80 
81 
82 } // anonymous namespace
83 
84 
85 //****************************************************************************
86 // Local helper functions.
87 //
88 
89 
90 namespace {
91 
92 
97 bool name_is_pair (const char* clsname)
98 {
99  return (strncmp (clsname, "pair<", 5) == 0 ||
100  strncmp (clsname, "std::pair<", 10) == 0);
101 }
102 
103 
107 void scan_for_pair()
108 {
109  // Should hold the ROOT mutex before using TClassTable.
110  R__WRITE_LOCKGUARD (ROOT::gCoreMutex);
111 
113  while (const char* clsname = TClassTable::Next()) {
114  if (name_is_pair (clsname)) {
115  TClass* cls = gROOT->GetClass (clsname, kFALSE);
116  if (cls)
117  cls->GetListOfBases()->Clear();
118  }
119  }
120 }
121 
122 
123 } // anonymous namespace
124 
125 
126 namespace RootUtils {
127 
128 
135 {
136  // Return if we've already initialized.
137  static bool initialized = false;
138  if (initialized) return;
139  initialized = true;
140 
141  // Scan all classes.
142  scan_for_pair();
143 
144  // Register ourselves as a hook,
145  // to be called in the future on class creation.
146  TypePatchInitBehavior::oldBehaviorPtr = &TypePatchInitBehavior::oldBehavior;
147  TInitBehavior* ib =
148  const_cast<TInitBehavior*>(DefineBehavior(0,0));
149  assert (sizeof(TDefaultInitBehavior) == sizeof (TypePatchInitBehavior));
150  memcpy ((char*)&TypePatchInitBehavior::oldBehavior, (char*)ib,
151  sizeof(TDefaultInitBehavior));
152  static TypePatchInitBehavior sfaib;
153  memcpy ((char*)ib, (char*)&sfaib, sizeof(TDefaultInitBehavior));
154 
155  // Make sure the TClass's for these are built.
156  // Otherwise, CreateClass can get called while global dtors are running.
157  gROOT->GetClass("TObjString");
158  gROOT->GetClass("TTreeCache");
159 }
160 
161 
167 {
168  if (name_is_pair (cls->GetName())) {
169  cls->GetListOfBases()->Clear();
170  }
171 }
172 
173 
174 } // namespace RootUtils
grepfile.info
info
Definition: grepfile.py:38
PlotCalibFromCool.il
il
Definition: PlotCalibFromCool.py:381
RootUtils
Definition: ILogger.h:20
TestSUSYToolsAlg.dl
dl
Definition: TestSUSYToolsAlg.py:83
RootUtils::PyROOTTypePatch::initialize
static void initialize()
Initialize the workaround.
Definition: PyROOTTypePatch.cxx:134
PlotCalibFromCool.ib
ib
Definition: PlotCalibFromCool.py:419
CaloClusterListBadChannel.cls
cls
Definition: CaloClusterListBadChannel.py:8
ATLAS_NO_CHECK_FILE_THREAD_SAFETY
ATLAS_NO_CHECK_FILE_THREAD_SAFETY
Definition: PyROOTTypePatch.cxx:12
PyROOTTypePatch.h
Work around pyroot problem with __pair_base.
checker_macros.h
Define macros for attributes used to control the static checker.
RootUtils::PyROOTTypePatch::scan_one
static void scan_one(TClass *cls)
Scan a single class.
Definition: PyROOTTypePatch.cxx:166
dq_make_web_display.cl
cl
print [x.__class__ for x in toList(dqregion.getSubRegions()) ]
Definition: dq_make_web_display.py:26
xAOD::Init
StatusCode Init(const char *appname)
Function initialising ROOT/PyROOT for using the ATLAS EDM.
Definition: Init.cxx:31