Problem reading TChains using posix threads

Hello ROOTers,

I have a serious problem concerning TChains and posix threads. I hope that someone can help me doing a workaround or give me an idea how to do it.

Let me first describe my intended application and after that the current problem.

In my main() I instanciate two classes with posix-thread support. After that both classes start a thread which adds several TFiles to a TChain, reads all the chain’s entries and passes each entry to another class for doing some analysis.

Think about an analysis on fruits. One thread reads the TChain with apples, another reads the TChain with pears. Both pass simultanious apples and pears to a FruitAnalysis-Class which inspects and counts every apple and every pear. Because my boxes (=TChains) with apples and pears are huge I’d prefer using threads instead of analysing one by one.

Surprise, surprise… the app does not work! :frowning:

I get an ugly SIGSEV when both threads try to add TFile-objects to their TChain simultaneously. (See backtrace from coredump below). All is fine if I process both Chains sequentially. My conclusion: Building TChains is not threadsafe. I would like to know, if reading two TChains simultaneously is threadsafe? Some experiences? Or did I forget to add threadsupport for my ROOT-libs?

Using ROOT, Version 4.02/00 on a Debian linux box with gcc-3.4.

Thanks for any comment!!

Cheers

H.-Gerd

// --- Snip: Backtrace from coredump ---
#0  0x0000002a95f2662e in TObject::TObject () from /usr/local/root/lib/libCore.so.4.02
#1  0x0000002a95f9b56d in THashTable::Add () from /usr/local/root/lib/libCore.so.4.02
#2  0x0000002a95fa9585 in TCint::UpdateListOfGlobals () from /usr/local/root/lib/libCore.so.4.02
#3  0x0000002a95f3dc19 in TROOT::GetListOfGlobals () from /usr/local/root/lib/libCore.so.4.02
#4  0x0000002a95fb9e0f in TDataMember::TDataMember () from /usr/local/root/lib/libCore.so.4.02
#5  0x0000002a95faa4d0 in TCint::CreateListOfDataMembers () from /usr/local/root/lib/libCore.so.4.02
#6  0x0000002a95faf5e4 in TClass::GetListOfDataMembers () from /usr/local/root/lib/libCore.so.4.02
#7  0x0000002a95faf704 in TClass::GetDataMember () from /usr/local/root/lib/libCore.so.4.02
#8  0x0000002a95fb003f in TBuildRealData::Inspect () from /usr/local/root/lib/libCore.so.4.02
#9  0x0000002a9633e9fb in TStreamerInfo::ShowMembers () from /usr/local/root/lib/libCore.so.4.02
#10 0x0000002a963480a9 in G__G__Meta_75_7_6 () from /usr/local/root/lib/libCore.so.4.02
#11 0x0000002a95adbf02 in G__CallFunc::Exec () from /usr/local/root/lib/libCint.so.4.02
#12 0x0000002a95fb42a0 in TClass::BuildRealData () from /usr/local/root/lib/libCore.so.4.02
#13 0x0000002a95fb52b4 in TClass::ReadBuffer () from /usr/local/root/lib/libCore.so.4.02
#14 0x0000002a95fd0d28 in TStreamerInfo::Streamer () from /usr/local/root/lib/libCore.so.4.02
#15 0x0000002a95fb58da in TClass::Streamer () from /usr/local/root/lib/libCore.so.4.02
#16 0x0000002a95fb58af in TClass::Streamer () from /usr/local/root/lib/libCore.so.4.02
#17 0x0000002a95ee59f9 in TBuffer::ReadObjectAny () from /usr/local/root/lib/libCore.so.4.02
#18 0x0000002a95f83c1f in operator>><TObject> () from /usr/local/root/lib/libCore.so.4.02
#19 0x0000002a95f9da4f in TList::Streamer () from /usr/local/root/lib/libCore.so.4.02
#20 0x0000002a95f04012 in TKey::ReadObj () from /usr/local/root/lib/libCore.so.4.02
#21 0x0000002a95efc759 in TFile::ReadStreamerInfo () from /usr/local/root/lib/libCore.so.4.02
#22 0x0000002a95ef7cb9 in TFile::Init () from /usr/local/root/lib/libCore.so.4.02
#23 0x0000002a95efd1b5 in TFile::TFile () from /usr/local/root/lib/libCore.so.4.02
// --- Snap ------------------------------

TChain::Add is not thread-safe. You should add Mutex/Lock around this call.
However it does not make much sense to call TChain::Add from different threads.
You better create your TChain in the main thread and process it in
different threads.

For your description, it looks like you are trying to implement something
like our PROOF system.

Rene