2 /**************************************************************************
3 * This file is property of and copyright by the ALICE HLT Project *
4 * ALICE Experiment at CERN, All rights reserved. *
6 * Primary Authors: Artur Szostak <artursz@iafrica.com> *
7 * for The ALICE HLT Project. *
9 * Permission to use, copy, modify and distribute this software and its *
10 * documentation strictly for non-commercial purposes is hereby granted *
11 * without fee, provided that the above copyright notice appears in all *
12 * copies and that both the copyright notice and this permission notice *
13 * appear in the supporting documentation. The authors make no claims *
14 * about the suitability of this software for any purpose. It is *
15 * provided "as is" without express or implied warranty. *
16 **************************************************************************/
18 /// @file AliHLTGlobalTriggerWrapper.cxx
19 /// @author Artur Szostak <artursz@iafrica.com>
21 /// @brief Implementation of the AliHLTGlobalTriggerWrapper interface class.
23 /// The AliHLTGlobalTriggerWrapper class is used to interface with an interpreted
24 /// class deriving from AliHLTGlobalTrigger. This is used when the global trigger
25 /// component is using CINT to interpret the trigger logic. The wrapper is necessary
26 /// to be able to call interpreted code from compiled code.
28 #include "AliHLTGlobalTriggerWrapper.h"
29 #include "TArrayL64.h"
31 #include "TInterpreter.h"
34 ClassImp(AliHLTGlobalTriggerWrapper)
39 /// Variable to store the error message if an error occured in CINT when interpreting code.
40 TString gCINTErrorMessage = "";
43 * This routine is the callback for the CINT interpreter when it finds a syntax error
44 * in the source code generated by the AliHLTGlobalTriggerComponent class.
46 void AliHLTOnErrorInCINT(char* message)
48 gCINTErrorMessage += message;
54 AliHLTGlobalTriggerWrapper::AliHLTGlobalTriggerWrapper(const char* classname) :
55 AliHLTGlobalTrigger(),
62 fCalculateTriggerDecisionCall(),
67 // The default constructor.
69 fClass = TClass::GetClass(classname);
72 HLTError("Could not find class information for '%s'.", classname);
75 fFillFromMenuCall.InitWithPrototype(fClass, "FillFromMenu", "const AliHLTTriggerMenu&");
76 if (not fFillFromMenuCall.IsValid())
78 HLTError("Could not initialise method call object for class '%s' and method FillFromMenu.", classname);
81 fNewEventCall.InitWithPrototype(fClass, "NewEvent", " "); // Must have single whitespace in last parameter or we get a segfault in G__interpret_func.
82 if (not fNewEventCall.IsValid())
84 HLTError("Could not initialise method call object for class '%s' and method NewEvent.", classname);
87 fAddCall.InitWithPrototype(fClass, "Add", "const TObject*, const AliHLTComponentDataType&, AliHLTUInt32_t");
88 if (not fAddCall.IsValid())
90 HLTError("Could not initialise method call object for class '%s' and method Add.", classname);
93 fCalculateTriggerDecisionCall.InitWithPrototype(fClass, "CalculateTriggerDecision", "bool&, AliHLTTriggerDomain&, TString&");
94 if (not fCalculateTriggerDecisionCall.IsValid())
96 HLTError("Could not initialise method call object for class '%s' and method CalculateTriggerDecision.", classname);
99 fGetCountersCall.InitWithPrototype(fClass, "GetCounters", " "); // Must have single whitespace in last parameter or we get a segfault in G__interpret_func.
100 if (not fGetCountersCall.IsValid())
102 HLTError("Could not initialise method call object for class '%s' and method GetCounters.", classname);
105 fSetCountersCall.InitWithPrototype(fClass, "SetCounters", "TArrayL64&");
106 if (not fSetCountersCall.IsValid())
108 HLTError("Could not initialise method call object for class '%s' and method SetCounters.", classname);
111 fObject = fClass->New();
114 HLTError("Could not create a new object of type '%s'.", classname);
117 // The following is a workaround for casting void* to void (*)(), i.e. a pointer to object to
118 // a pointer to function. Unfortunately the G__set_errmsgcallback routine interface is defined
119 // using a pointer to object so this workaround is necessary.
120 // We check that the two types are the same size. If they are not then such an operation is
121 // unsafe on the platform on which we are running and will not be performed.
125 void (*fFuncPtr)(char*);
127 fFuncPtr = AliHLTOnErrorInCINT;
128 if (sizeof(fPtr) == sizeof(fFuncPtr))
130 gInterpreter->SetErrmsgcallback(fPtr);
134 HLTWarning("On this platform a pointer to function and pointer to object are different sizes."
135 " For this reason we cannot use the G__set_errmsgcallback CINT API call in a safe way so all"
136 " error messages generated by CINT will not be captured or logged in the HLT system."
142 AliHLTGlobalTriggerWrapper::~AliHLTGlobalTriggerWrapper()
144 // Default destructor.
146 fClass->Destructor(fObject);
147 G__set_errmsgcallback(NULL);
151 void AliHLTGlobalTriggerWrapper::FillFromMenu(const AliHLTTriggerMenu& menu)
153 // Fills internal values from the trigger menu.
160 params.fMenu = &menu;
161 fFillFromMenuCall.SetParamPtrs(¶ms, 1);
162 gCINTErrorMessage = "";
163 fFillFromMenuCall.Execute(fObject);
164 if (gCINTErrorMessage != "")
167 HLTError(gCINTErrorMessage.Data());
168 HLTFatal("Error interpreting the code for class '%s' at line %d.", fClass->GetName(), G__lasterror_linenum());
173 void AliHLTGlobalTriggerWrapper::NewEvent()
175 // Clears the internal buffers for a new event.
178 gCINTErrorMessage = "";
179 fNewEventCall.Execute(fObject);
180 if (gCINTErrorMessage != "")
183 HLTError(gCINTErrorMessage.Data());
184 HLTFatal("Error interpreting the code for class '%s' at line %d.", fClass->GetName(), G__lasterror_linenum());
189 void AliHLTGlobalTriggerWrapper::Add(
190 const TObject* object, const AliHLTComponentDataType& type,
194 // Adds parameters from the object to the internal buffers and variables.
203 params.fObj = object;
204 params.fType = &type;
206 fAddCall.SetParamPtrs(¶ms, 3);
207 gCINTErrorMessage = "";
208 fAddCall.Execute(fObject);
209 if (gCINTErrorMessage != "")
212 HLTError(gCINTErrorMessage.Data());
213 HLTFatal("Error interpreting the code for class '%s' at line %d.", fClass->GetName(), G__lasterror_linenum());
218 bool AliHLTGlobalTriggerWrapper::CalculateTriggerDecision(bool& triggerResult, AliHLTTriggerDomain& domain, TString& description)
220 // Calculates the global trigger decision.
229 params.fResult = &triggerResult;
230 params.fDomain = &domain;
231 params.fDesc = &description;
232 fCalculateTriggerDecisionCall.SetParamPtrs(¶ms, 3);
234 gCINTErrorMessage = "";
235 fCalculateTriggerDecisionCall.Execute(fObject, retval);
236 if (gCINTErrorMessage != "")
239 HLTError(gCINTErrorMessage.Data());
240 HLTFatal("Error interpreting the code for class '%s' at line %d.", fClass->GetName(), G__lasterror_linenum());
247 const TArrayL64& AliHLTGlobalTriggerWrapper::GetCounters() const
249 // Returns the internal counter array.
252 gCINTErrorMessage = "";
253 fGetCountersCall.Execute(fObject, retval);
254 if (gCINTErrorMessage != "")
257 HLTError(gCINTErrorMessage.Data());
258 HLTFatal("Error interpreting the code for class '%s' at line %d.", fClass->GetName(), G__lasterror_linenum());
260 static const TArrayL64 emptyArray;
261 const TArrayL64* ptr = &emptyArray; // Make sure we do not return a NULL pointer.
262 if (retval != 0x0) ptr = reinterpret_cast<const TArrayL64*>(retval);
267 void AliHLTGlobalTriggerWrapper::SetCounters(const TArrayL64& counters)
269 // Fills the internal counter array with new values.
274 const void* fCounters;
276 params.fCounters = &counters;
277 fSetCountersCall.SetParamPtrs(¶ms, 1);
278 gCINTErrorMessage = "";
279 fSetCountersCall.Execute(fObject);
280 if (gCINTErrorMessage != "")
283 HLTError(gCINTErrorMessage.Data());
284 HLTFatal("Error interpreting the code for class '%s' at line %d.", fClass->GetName(), G__lasterror_linenum());
289 bool AliHLTGlobalTriggerWrapper::IsValid() const
291 // Checks if the wrapper class was initialised correctly.
293 return fClass != NULL and fObject != NULL and fFillFromMenuCall.IsValid()
294 and fNewEventCall.IsValid() and fAddCall.IsValid()
295 and fCalculateTriggerDecisionCall.IsValid();