ATLAS Offline Software
Loading...
Searching...
No Matches
DsoRootLock Class Reference

Workaround for ROOT TClassTable locking problem. More...

Collaboration diagram for DsoRootLock:

Public Member Functions

 DsoRootLock ()
 Constructor.

Static Public Member Functions

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

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}
int ath_dso_cbk_register(ath_dso_event_cbk_t cbk, void *userdata)
static int hook(const ath_dso_event *event, void *userdata)
Acquire the ROOT core lock during library loading.

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}
#define ATLAS_THREAD_SAFE

The documentation for this class was generated from the following file: