ATLAS Offline Software
Public Member Functions | Static Public Member Functions | List of all members
DsoRootLock Class Reference

Workaround for ROOT TClassTable locking problem. More...

Collaboration diagram for DsoRootLock:

Public Member Functions

 DsoRootLock ()
 Constructor. More...
 

Static Public Member Functions

static int hook (const ath_dso_event *event, void *userdata)
 Acquire the ROOT core lock during library loading. More...
 

Detailed Description

Workaround for ROOT TClassTable locking problem.

TClassTable is an internal ROOT structure used to hold information about all classes known to ROOT, whether or not full dictionary information has been built. This is effectively a singleton; however, TClassTable itself contains no locking. Rather, it relies on the caller already having acquired the ROOT core mutex. In most cases, that happens. However, when a shared object containing ROOT dictionaries is loaded, calls are made to TClassTable to record the classes present in that dictionary. But, in that case, the core mutex is not acquired, resulting in a potential race.

This would be best addressed inside ROOT, by acquiring the lock in TGenericClassInfo::Init. As a temporary workaround, however, use the existing DSO hooks to acquire the root lock around all shared library loads.

Definition at line 35 of file DsoRootLock.cxx.

Constructor & Destructor Documentation

◆ DsoRootLock()

DsoRootLock::DsoRootLock ( )

Constructor.

Register the hook.

Definition at line 54 of file DsoRootLock.cxx.

55 {
56  ath_dso_cbk_register (hook, nullptr);
57 }

Member Function Documentation

◆ hook()

int DsoRootLock::hook ( const ath_dso_event event,
void *  userdata 
)
static

Acquire the ROOT core lock during library loading.

Definition at line 63 of file DsoRootLock.cxx.

64 {
65  // Skip for Xrd libraries --- otherwise we can deadlock.
66  if (event->fname && strncmp (event->fname, "libXrd", 6) == 0) return 0;
67 
68  // If the core mutex has been created, acquire it before loading
69  // a library and release it on completion.
70  // Hope these are always properly nested!
71  ROOT::TVirtualRWMutex* m ATLAS_THREAD_SAFE = ROOT::gCoreMutex;
72  if (m) {
73  if (event->step == 0) {
74  m->WriteLock();
75  }
76  else if (event->step == 1)
77  {
78  m->WriteUnLock(nullptr);
79  }
80  }
81  return 0;
82 }

The documentation for this class was generated from the following file:
python.SystemOfUnits.m
int m
Definition: SystemOfUnits.py:91
DsoRootLock::hook
static int hook(const ath_dso_event *event, void *userdata)
Acquire the ROOT core lock during library loading.
Definition: DsoRootLock.cxx:63
event
POOL::TEvent event(POOL::TEvent::kClassAccess)
ath_dso_cbk_register
int ath_dso_cbk_register(ath_dso_event_cbk_t cbk, void *userdata)
ATLAS_THREAD_SAFE
#define ATLAS_THREAD_SAFE
Definition: checker_macros.h:211