Locking in JANA
From GlueXWiki
Contents
[hide]Plugin Processor Variables
- Do not place use any locks in JEventProcessor::init() or ::fini(): they are unnecessary, and a waste of time.
- JANA is guaranteed to be single-threaded in these functions.
- Do not use or modify any global variables, unless you are in a lock.
- Or even better, don't have any in the first place. It's terrible programming practice.
- Do NOT use or modify any class member-variables that you define for your JEventProcessor (i.e. in header file), unless you are in a lock (or in init(), fini()). These variables can be modified by other threads.
- This ESPECIALLY includes data saved in brun(), that is read in evnt().
- Or even better, don't have any in the first place: Reduce the amount of time spent in locks if at all possible. Use function-scope (local) variables instead.
- Where possible of course. E.g. you can't avoid it with histograms, but you need to lock to fill those anyway.
Creating Histograms or TTrees
- If you are creating histograms or trees (outside of JEventProcessor::init()): Use the global ROOT JANA lock functions below.
- This is because they depend on gDirectory being constant.
japp->RootWriteLock(); //ACQUIRE ROOT LOCK japp->RootUnLock(); //RELEASE ROOT LOCK
Filling Histograms
- If you are filling histograms, you do NOT need to grab the global ROOT JANA lock functions. Try to instead grab a lock with a smaller scope, so that other threads can write to other histograms that don't interfere with yours.
- In you are directly in the plugin processor, there's a special function to do this, that locks for the current plugin only. It is:
japp->RootFillLock(this); //ACQUIRE ROOT FILL LOCK //this: JEventProcessor pointer japp->RootFillUnLock(this); //RELEASE ROOT FILL LOCK //this: JEventProcessor pointer
Filling TTrees
- If you are filling TTrees to the global ROOT file (i.e. hd_root.root), write to the TTrees with the global ROOT JANA lock functions below:
- This is because TTree::Fill() periodically writes to the file, modifying it.
japp->RootWriteLock(); //ACQUIRE ROOT LOCK japp->RootUnLock(); //RELEASE ROOT LOCK
- If you are filling TTrees to a local ROOT file (i.e. NOT hd_root.root), you do NOT need to grab the global ROOT JANA lock functions. Try to instead grab a lock with a smaller scope, so that other threads can write to other trees that don't interfere with yours.
- Grab the same for every tree that is written to the same output file. This is because TTree::Fill() periodically writes to the file, modifying it.
- This can be done with:
japp->WriteLock("MyFileName"); //ACQUIRE FILE LOCK japp->Unlock("MyFileName"); //RELEASE FILE LOCK