|
This is a promised summary of what had been said
in an exchange of mails between various interested people
about the threading problem when mixing X11/Xt/Motif, ROOT and Geant4.
The problem :
-----------
Problem araised from a user crash when running a main
using Geant4 kernel, G4UIXm and AFTER using ROOT to create a TCanvas.
People quickly discovered that ROOT, and its X11 driver,
in this particular case, had been compiled with the thread options
and in particular that the Geant4 G4UIXm code did a XOpenDisplay prior to
an XInitThread done somehwere in ROOT.
As mentionned in the X11 doc, if the threading of X11
is used, a XInitThreads() should be done before ANY invocation
of any X11 functions.
The crash in the user application came from a non respect
of this X11 recommendation. In the main(), a call to XInitThreads()
prior everything cured the problem.
Doing something in Geant4 ?
-------------------------
Ok, fine. But some suggested that we should perhpas instrument
the Geant4 code related to X11 in order to take the X11 threading
into account. The proposal was to put in various X11 related places
something like :
#idef _REENTRANT
XInitThreads()
#endif
On problem is that Geant4 is NOT an application. It is first
of all a toolkit (a set of libraries) and it is in charge of a user
to build a program with the Geant4 kernel, plus some of the G4UI,
some of the G4 vis drivers and perhpas by mixing with other products
and tools around.
It appears that X11, in Geant4, is indirectly present in various
GUI "sessions" and various visualization drivers ; each of them
may be put or not in a program quite indepandantly.
Moreover all these drivers may rely on products that may be or may
be not constructed to support thread on the user platform.
This being said, it seems more natural to let the Geant4 X11 related
code "clean" related the threading and let the assembler programmer
of an application using Geant4 to decide to put in its main() an
XInitThread() according to what he is going to use in his application.
Then, at least in the Geant4-7.0 release, it had been decided to NOT
put the upper code in G4Xt.cc, G4OpenGLXm.cc, G4OpenInventorXt.cc, etc...
(Moreover this problem came very lately concerning the release process
for the 7.0).
Geant4 had not been forseen to be multi thread for the moment :
-------------------------------------------------------------
And a direct consequence of that is that there is no threading options
in the G4 makefile system for the moment. So, even if we had decided
to put the upper #ifdef _REENTRANT in the UI and vis X11 codes, we had no way
for the moment to raise the threading compilation options at the level of the
Geant4 make system.
(Clearly the idea here is to say ; let first Geant4 kernel be threadable
and then see to be sure to have the UI and vis drivers be threadable).
Some recommendations :
--------------------
This being said, it appears that the mixing of Geant4 + ROOT-threaded +
Geant4 UI Motif session worked and from various user experiences we can anyway
come with some simple guidelines :
- first check that the various used producted are thread safe
(X11 is ok from X11R6, Motif is ok from 2.1 and recent XFree86/OpenGL
are ok too).
- be sure that the various products had been built with
thread options on the targeted running machine.
(for example, if using Qt, it is not because Qt is thread safe
that you have linked your application with -lqt-mt !!!).
- for X11, then check that a XInitThreads() is done prior
to any direct or indirect X11 call. Note that at least if using
XFree86 implementation, someone can call multiple time XInitThreads() ;
only the first one count.
- take care of the hidden X11 calls ; for example there is
X11/Motif behind java/awt or tcl/tk !!!
At least, for what concerns X11/Xt/Motif/OpenGL, someone can
in principle, by pairing attention to the uppers, build now a
thread safe program with them ; and the author is quite confident
that most of the G4 UI and vis X11 related drivers are in fact already
thread safe.
|