int iResult=0;
if (libraryPath) {
AliHLTComponent::SetGlobalComponentHandler(this);
- AliHLTLibHandle hLib=NULL;
+ AliHLTLibHandle hLib;
#ifdef HAVE_DLFCN_H
// use interface to the dynamic linking loader
- hLib=dlopen(libraryPath, RTLD_NOW);
+ hLib.handle=dlopen(libraryPath, RTLD_NOW);
#else
// use ROOT dynamic loader
- if (gSystem->Load(libraryPath)==0) {
- // create TString object to store library path and use pointer as handle
- hLib=reinterpret_cast<AliHLTLibHandle>(new TString(libraryPath));
+ // check if the library was already loaded, as Load returns
+ // 'failure' if the library was already loaded
+ vector<AliHLTLibHandle>::iterator element=fLibraryList.begin();
+ while (element!=fLibraryList.end()) {
+ TString* name=reinterpret_cast<TString*>((*element).name);
+ if (name->CompareTo(libraryPath)==0) {
+ int* pRootHandle=reinterpret_cast<int*>((*element).handle);
+ (*pRootHandle)++;
+ HLTDebug("instance %d of library %s loaded", (*pRootHandle), libraryPath);
+ hLib.handle=pRootHandle;
+ break;
+ }
+ element++;
+ }
+
+ if (hLib.handle==NULL && gSystem->Load(libraryPath)==0) {
+ int* pRootHandle=new int;
+ if (pRootHandle) *pRootHandle=1;
+ hLib.handle=pRootHandle;
+ HLTDebug("library %s loaded via gSystem", libraryPath);
}
#endif //HAVE_DLFCN_H
- if (hLib) {
+ if (hLib.handle!=NULL) {
+ // create TString object to store library path and use pointer as handle
+ hLib.name=new TString(libraryPath);
HLTInfo("library %s loaded", libraryPath);
- fLibraryList.push_back(hLib);
+ fLibraryList.insert(fLibraryList.begin(), hLib);
iResult=RegisterScheduledComponents();
} else {
HLTError("can not load library %s", libraryPath);
int iResult=0;
vector<AliHLTLibHandle>::iterator element=fLibraryList.begin();
while (element!=fLibraryList.end()) {
+ TString* pName=reinterpret_cast<TString*>((*element).name);
#ifdef HAVE_DLFCN_H
- dlclose(*element);
+ dlclose((*element).handle);
#else
- TString* libraryPath=reinterpret_cast<TString*>(*element);
- gSystem->Unload(libraryPath->Data());
- delete libraryPath;
+ int* pCount=reinterpret_cast<int*>((*element).handle);
+ if (--(*pCount)==0) {
+ if (pName)
+ gSystem->Unload(pName->Data());
+ else {
+ HLTError("missing library name, can not unload");
+ }
+ delete pCount;
+ }
#endif //HAVE_DLFCN_H
- element++;
+ if (pName) {
+ HLTDebug("unload library %s", pName->Data());
+ delete pName;
+ } else {
+ HLTWarning("missing name for unloaded library");
+ }
+ pName=NULL;
+ fLibraryList.erase(element);
+ element=fLibraryList.begin();
}
return iResult;
}
struct AliHLTComponentEnvironment;
struct AliHLTComponentDataType;
-typedef void* AliHLTLibHandle;
-
/**
* @class AliHLTComponentHandler
* The component handler controls all the processing components available in
/**
* Create a component of the given name (ID).
- * The method tries to find a registerd component of id \em componentID and calls
- * the \em Spawn method of the template component. After successful creation of
- * a new object, the Init method is called in order to initialize the environment
- * and the component arguments. <br>
+ * The method tries to find a registerd component of id \em componentID and
+ * calls the \em Spawn method of the template component. After successful
+ * creation of a new object, the Init method is called in order to initialize
+ * the environment and the component arguments. <br>
* The environment is the same for all components, but each component can
* have an additional private parameter \em pEnvParam.<br>
- * The component arguments consist of an array of strings and the array size in the
- * usual manner of the main() function.
+ * The component arguments consist of an array of strings and the array size
+ * in the usual manner of the main() function.
* @param componentID ID of the component to create
* @param pEnvParam environment parameter for the component
* @param argc number of arguments in argv
*/
int UnloadLibraries();
+ /**
+ * Compount descriptor for component libraries
+ */
+ struct AliHLTLibHandle {
+ AliHLTLibHandle() : handle(NULL), name(NULL) {}
+ /** dlopen handle */
+ void* handle; //! transient
+ /** name of the library, casted to TString* before use */
+ void* name; //! transient
+ };
+
/** list of registered components */
vector<AliHLTComponent*> fComponentList; // see above
/** list of scheduled components */
"agent %s not found", agent);
}
} else {
- TObjLink* lnk=fgAgentList.FirstLink();
- while (lnk) {
- log.Logging(kHLTLogInfo, "AliHLTModuleAgent::PrintStatus", "module agents",
- ((AliHLTModuleAgent*)lnk->GetObject())->GetName());
- lnk=lnk->Next();
- }
+ TObjLink* lnk=fgAgentList.FirstLink();
+ log.Logging(kHLTLogInfo, "", "", "-----------------------");
+ log.Logging(kHLTLogInfo, "", "", "available module agents");
+ if (lnk==NULL)
+ log.Logging(kHLTLogInfo, "", "", " none");
+ while (lnk) {
+ TString msg;
+ msg.Form(" %s : %p", ((AliHLTModuleAgent*)lnk->GetObject())->GetName(), lnk->GetObject());
+ log.Logging(kHLTLogInfo, "", "", msg.Data());
+ lnk=lnk->Next();
+ }
+ log.Logging(kHLTLogInfo, "", "", "-----------------------");
}
}
AliHLTLogging log;
if (!pAgent) return -EINVAL;
if (fgAgentList.FindObject(pAgent)!=NULL) {
- log.Logging(kHLTLogDebug, "AliHLTModuleAgent::Unregister", "", "module agent %s (%p) removed", pAgent->GetName(), pAgent);
+ log.Logging(kHLTLogDebug, "AliHLTModuleAgent::Unregister", "", "module agent %p removed", pAgent);
fgAgentList.Remove(pAgent);
} else {
}
* @class AliHLTModuleAgent
* @brief Agent helper class for HLT sub modules, e.g. PHOS, TPC, Trigger
*
- * This class describes
+ * This class implements the agent base class for the HLT sub modules.
+ * The agent of a library gives information on the features of the module,
+ * like the configurations to run and other component libraries it depends
+ * on.
+ *
+ * All HLT component libraries are loaded on demand through the HLT steering
+ * instance (@ref AliHLTSystem). A library can implement an agent derived
+ * from this base class, and has to define one global object of this agent
+ * in the code. The agent will be registered automatically, and the features
+ * can be queried when required.
+ *
+ * This is usually done during running the AliRoot Reconstruction (see
+ * <tt>AliReconstruction</tt>. The HLT implemets the AliHLTReconstructor which
+ * holds the HLT steering object. Several flags can be specified as options
+ * via the SetOption method of AliReconstruction, including the component
+ * libraries to be loaded.
*
* There must be only one agent per module/library.
*
HLTError("HLT system in running state, can not configure");
return -EBUSY;
}
+ if (CheckFilter(kHLTLogDebug))
+ AliHLTModuleAgent::PrintStatus();
ClearStatusFlags(kConfigurationLoaded|kTaskListCreated);
iResult=LoadConfigurations(runloader);
if (iResult>=0) {
while (pAgent && iResult>=0) {
const char* deplibs=pAgent->GetRequiredComponentLibraries();
if (deplibs) {
- HLTDebug("load libraries \'%s\' %s for agent %s (%p)", deplibs, pAgent->GetName(), pAgent);
+ HLTDebug("load libraries \'%s\' for agent %s (%p)", deplibs, pAgent->GetName(), pAgent);
iResult=LoadComponentLibraries(deplibs);
}
if (iResult>=0) {