Adventures With IFile and a Cast of Thousands

The Modest Beginning

Toby had deleted all geometry references from instrument.xml since such information is now handled by detModel. All that remains are certain hardware configuration parameters and so forth which can also readily be handled by detModel. The goal was to add these other parameters to the detModel input, then modify all software using instrument.xml to initialize (by means of classes xml::IFile and xml::IFileManager), and finally to get rid of instrument.xml altogether. The job broke up into these pieces:

  1. Convert all code which sets variable values via IFile, IFileManager to use detModel services instead.
  2. If version,revision are really used (as they seem to be in ResponseFile) this funcionality needs to be preserved in new scheme
  3. Everything has to get initialized, and in the right order.

It quickly became clear that the last problem had to be dealt with first. In the G4Generator package as it now stands, instrument.xml was handled in GlastSvc while all detModel-related calls were in G4Generator. It seemed logical to put the detModel building calls, those calls which extract information from the xml file into the detModel data structures, into GlastSvc while leaving other, higher-level functions specific to G4 in G4Generator.

Mulitple Singletons

The first stage of the newly-arranged code, running within GlastSvc, did its job as before, but the calls outside GlastSvc were crashing. The problem was with multiple copies of a static variable. The detModel::Manager class, which all clients use to get access to detModel services, is implemented as a singleton with a static variable holding a pointer to the one instantiated object. Applications get this pointer by calling detModel::Manager::getPointer(). However, there actually was one object per linked entity, so that the detModel structure built from GlastSvc was not available to G4Generator classes. The problem was addressed by

More Static

With the new changes, GlastSvc was still able to initialize successfully, and G4Generator classes had access to the "right" detModel::Manager object, but the code was still crashing in detModel code called from G4Generator. In particular, the IDmapBuilder visitor calls detModel::Gdd::getVolumeByName(), which crashed. When everything was moved into GlastSvc, IDmapBuilder visitor could complete successfully. The culprit appears to be a static variable, _NIL, in the Windows implementation of a tree, which is used by std::map. (The unix implementation of tree has no static variables.)

Shareables All the Way Down

Since it is impractical and undesirable to ban stl::map from our code and since there are ocassionally other legitimate reasons for using static variables, we need some way to insure that we only have a single copy of such code loaded at run time. This should be possible by linking non-Gaudi utility packages which may be called from more than one shareable into shareables also (not Gaudi components, just shareables).

After a couple tries to get requirements files to do the right thing (thank you, Alex!) and some changes to code in the xml package to move implementations accessing private static variables out of header files, I've linked the G4Generator test program using shareables from packages xml, xmlUtil and detModel. After more help from Alex it can find all the libraries it needs at run time. Specifically, I've changed requirements files as follows:

IDmap building in G4Generator::DetectorConstruction (which failed before making these shareables) now completes successfully, but the following loop over idmap (that is, over a map of positioned volumes, indexed by id) crashes with an access violation when it tries to access the 2nd object. It could have something to do with the instrument package, which also involves static variables, so work is in progress to link it into a shareable also.

Next Installments

Isolate

The instrument package has a bunch of statics (and is referred to by multiple shareables) so does itself need to be made into a shareable. However, this did not fix the above problem. I modified the detModel test program (which already made an id map) to include the failing loop, and it did also fail in this much-reduced program.

unix

At this point I moved all the new source for detModel and packages it depends on (xml and xmlUtil) to unix (but did not move the new requirements files) and built the detModel test program there. It ran successfully, but this still isn't a true comparison with the unix versionl, which was built using shareable libraries for xml, xmlUtil and detModel.

Couldn't build first shareable, libxml.so, until I changed the line above from

apply_pattern package_linkopts
to
apply_pattern package_Clinkopts
This is what the typical shareable-building requirements file has, but it seemed to cause trouble on Windows. If the "C" stands for "Component" I probably don't want it.

In fact, what finally worked for building all three shareables on Linux was to get rid of all "C" patterns. For example, for the detModel package the lines

  apply_pattern package_linkopts
  apply_pattern packageShr
  path_append LD_LIBRARY_PATH "${detModelDir}"

are in the public part of the requirements file and the following line is in the private part:

apply_pattern package_shlibflags

This didn't work for Windows (e.g. xml package couldn't resolve Xerces symbols) but did after adding the following to GlastPolicy:

### Experimental
macro shrNoCmp ""\
      WIN32 "$(use_linkopts)"

### more experimental -- try to override definition in GaudiPolicy
pattern package_shlibflags \
    macro <package>_shlibflags "$(libraryshr_linkopts) $(shrNoCmp)"

Back to GLAST Software Home

J. Bogart  Created: 12-Feb-2002 14:00 PST
Last modified: