#include "TRegexp.h"
#include "TClonesArray.h"
#include "TObjString.h"
-#include "TSystem.h"
+#include "TString.h"
#include "TInterpreter.h"
#include "TDatime.h"
#include "TClass.h"
fBufferSizeConst(2*(sizeof(AliHLTGlobalTriggerDecision) + sizeof(AliHLTReadoutList))),
fBufferSizeMultiplier(1.),
fIncludePaths(TObjString::Class()),
- fIncludeFiles(TObjString::Class())
+ fIncludeFiles(TObjString::Class()),
+ fLibStateAtLoad()
{
// Default constructor.
}
+void AliHLTGlobalTriggerComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& list) const
+{
+ // Returns the kAliHLTDataTypeGlobalTrigger type as output.
+ list.push_back(kAliHLTDataTypeGlobalTrigger);
+}
+
+
void AliHLTGlobalTriggerComponent::GetOutputDataSize(unsigned long& constBase, double& inputMultiplier)
{
// Returns the output data size estimate.
static UInt_t lastTime=0;
TDatime time;
- if (time.Get()-lastTime>5) {
+ if (time.Get()-lastTime>60) {
lastTime=time.Get();
- PrintStatistics(fTrigger);
+ PrintStatistics(fTrigger, kHLTLogImportant);
}
// Add the input objects used to the global decision.
for (Int_t i = 0; i < symbols.GetEntriesFast(); i++)
{
AliHLTTriggerMenuSymbol* symbol = static_cast<AliHLTTriggerMenuSymbol*>( symbols.UncheckedAt(i) );
- code << " if (strcmp(symbol->Name(), \"" << symbol->Name() << "\") == 0) {" << endl;
+ code << " if (strcmp(symbol->RealName(), \"" << symbol->RealName() << "\") == 0) {" << endl;
if (fDebugMode)
{
code << " HLTDebug(Form(\"Assinging domain entry value corresponding with symbol '%s' to '%s'.\","
- " symbol->Name(), symbol->BlockType().AsString().Data()));" << endl;
+ " symbol->RealName(), symbol->BlockType().AsString().Data()));" << endl;
}
code << " " << symbol->Name() << "DomainEntry = symbol->BlockType();" << endl;
code << " continue;" << endl;
if (isTrigDecision)
{
code << "strcmp(" << symbol->Name() << "_object_->Name(), \""
- << symbol->Name() << "\") == 0 && ";
+ << symbol->RealName() << "\") == 0 && ";
}
code << symbol->Name() << "DomainEntry == _type_spec_) {" << endl;
TString fullname = symbol->Name();
}
else
{
+ // Store the library state to be checked later in UnloadTriggerClass.
+ fLibStateAtLoad = gSystem->GetLibraries();
+
// If we do not support the compiler then try interpret the class instead.
TString cmd = ".L ";
cmd += filename;
TString compiler = gSystem->GetBuildCompilerVersion();
if (fRuntimeCompile && (compiler.Contains("gcc") or compiler.Contains("icc")))
{
+ // Generate the library name.
TString libname = filename;
Ssiz_t dotpos = libname.Last('.');
if (0 <= dotpos and dotpos < libname.Length()) libname[dotpos] = '_';
libname += ".";
libname += gSystem->GetSoExt();
+ // This is a workaround for a problem with unloading shared libraries in ROOT.
+ // If the trigger logic library is loaded before the libAliHLTHOMER.so library
+ // or any other library is loaded afterwards, then during the gInterpreter->UnloadFile
+ // call all the subsequent libraries get unloded. This means that any objects created
+ // from classes implemented in the libAliHLTHOMER.so library will generate segfaults
+ // since the executable code has been unloaded.
+ // We need to check if there are any more libraries loaded after the class we
+ // are unloading and in that case don't unload the class.
+ TString libstring = gSystem->GetLibraries();
+ TString token, lastlib;
+ Ssiz_t from = 0;
+ Int_t numOfLibs = 0, posOfLib = -1;
+ while (libstring.Tokenize(token, from, " "))
+ {
+ ++numOfLibs;
+ lastlib = token;
+ if (token.Contains(libname)) posOfLib = numOfLibs;
+ }
+ if (numOfLibs != posOfLib)
+ {
+ HLTWarning(Form("ROOT limitation! Cannot properly cleanup and unload the shared"
+ " library '%s' since another library '%s' was loaded afterwards. Trying to"
+ " unload this library will remove the others and lead to serious memory faults.",
+ libname.Data(), lastlib.Data()
+ ));
+ return 0;
+ }
+
char* path = NULL;
int result = 0;
if ((path = gSystem->DynamicPathName(libname)) != NULL)
}
else
{
- // If we do not support the compiler then try interpret the class instead.
+ // This is again a workaround for the problem with unloading files in ROOT.
+ // If the trigger logic class is loaded before the libAliHLTHOMER.so library
+ // or any other library is loaded afterwards, then during the gInterpreter->UnloadFile
+ // call all the subsequent libraries get unloded.
+ // We need to check if the list of loaded libraries has changed since the last
+ // call to LoadTriggerClass. If it has then don't unload the class.
+ if (fLibStateAtLoad != gSystem->GetLibraries())
+ {
+ TString libstring = gSystem->GetLibraries();
+ TString token;
+ Ssiz_t from = 0;
+ while (libstring.Tokenize(token, from, " "))
+ {
+ if (not fLibStateAtLoad.Contains(token)) break;
+ }
+ HLTWarning(Form("ROOT limitation! Cannot properly cleanup and unload the file"
+ " '%s' since another library '%s' was loaded afterwards. Trying to unload"
+ " this file will remove the other library and lead to serious memory faults.",
+ filename, token.Data()
+ ));
+ return 0;
+ }
+
+ // If we did not compile the trigger logic then remove the interpreted class.
TString cmd = ".U ";
cmd += filename;
Int_t errorcode = TInterpreter::kNoError;
// implementation class.
// See header for more details.
+ // Note: when we build the symbol list we must use the symbol name as returned
+ // by the Name() method and not the RealName() method when using FindSymbol.
+ // This is so that we avoid problems with the generated code not compiling
+ // because names like "abc-xyz" and "abc_xyz" are synonymous.
+ // Name() returns the converted C++ symbol name as used in the generated code.
+
for (UInt_t i = 0; i < menu->NumberOfSymbols(); i++)
{
const AliHLTTriggerMenuSymbol* symbol = menu->Symbol(i);
continue;
}
- if (FindSymbol(s.Data(), list) == -1)
+ // Need to create the symbols first and check if its name is in the list
+ // before actually adding it to the symbols list.
+ AliHLTTriggerMenuSymbol newSymbol;
+ newSymbol.Name(s.Data());
+ newSymbol.Type("bool");
+ newSymbol.ObjectClass("AliHLTTriggerDecision");
+ newSymbol.AssignExpression("this->Result()");
+ newSymbol.DefaultValue("false");
+ if (FindSymbol(newSymbol.Name(), list) == -1)
{
- AliHLTTriggerMenuSymbol newSymbol;
- newSymbol.Name(s.Data());
- newSymbol.Type("bool");
- newSymbol.ObjectClass("AliHLTTriggerDecision");
- newSymbol.AssignExpression("this->Result()");
- newSymbol.DefaultValue("false");
new (list[list.GetEntriesFast()]) AliHLTTriggerMenuSymbol(newSymbol);
}
}