]>
Commit | Line | Data |
---|---|---|
81d62bb4 | 1 | // $Id: $ |
2 | /************************************************************************** | |
3 | * This file is property of and copyright by the ALICE HLT Project * | |
4 | * ALICE Experiment at CERN, All rights reserved. * | |
5 | * * | |
6 | * Primary Authors: Artur Szostak <artursz@iafrica.com> * | |
7 | * for The ALICE HLT Project. * | |
8 | * * | |
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 | **************************************************************************/ | |
17 | ||
18 | /// @file AliHLTGlobalTriggerWrapper.cxx | |
19 | /// @author Artur Szostak <artursz@iafrica.com> | |
20 | /// @date 28 Oct 2009 | |
21 | /// @brief Implementation of the AliHLTGlobalTriggerWrapper interface class. | |
22 | /// | |
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. | |
27 | ||
28 | #include "AliHLTGlobalTriggerWrapper.h" | |
29 | #include "TArrayL64.h" | |
30 | #include "TClass.h" | |
31 | #include "TInterpreter.h" | |
1b820a65 | 32 | #include "TCint.h" |
81d62bb4 | 33 | |
34 | ClassImp(AliHLTGlobalTriggerWrapper) | |
35 | ||
36 | ||
325e5e42 | 37 | namespace |
38 | { | |
39 | /// Variable to store the error message if an error occured in CINT when interpreting code. | |
40 | TString gCINTErrorMessage = ""; | |
41 | ||
42 | /** | |
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. | |
45 | */ | |
46 | void AliHLTOnErrorInCINT(char* message) | |
47 | { | |
48 | gCINTErrorMessage += message; | |
49 | } | |
50 | ||
51 | } // end of namespace | |
52 | ||
53 | ||
81d62bb4 | 54 | AliHLTGlobalTriggerWrapper::AliHLTGlobalTriggerWrapper(const char* classname) : |
55 | AliHLTGlobalTrigger(), | |
56 | AliHLTLogging(), | |
57 | fClass(NULL), | |
58 | fObject(NULL), | |
59 | fFillFromMenuCall(), | |
60 | fNewEventCall(), | |
61 | fAddCall(), | |
62 | fCalculateTriggerDecisionCall(), | |
63 | fGetCountersCall(), | |
325e5e42 | 64 | fSetCountersCall(), |
65 | fCallFailed(false) | |
81d62bb4 | 66 | { |
67 | // The default constructor. | |
68 | ||
69 | fClass = TClass::GetClass(classname); | |
70 | if (fClass == NULL) | |
71 | { | |
72 | HLTError("Could not find class information for '%s'.", classname); | |
73 | return; | |
74 | } | |
75 | fFillFromMenuCall.InitWithPrototype(fClass, "FillFromMenu", "const AliHLTTriggerMenu&"); | |
76 | if (not fFillFromMenuCall.IsValid()) | |
77 | { | |
78 | HLTError("Could not initialise method call object for class '%s' and method FillFromMenu.", classname); | |
79 | return; | |
80 | } | |
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()) | |
83 | { | |
84 | HLTError("Could not initialise method call object for class '%s' and method NewEvent.", classname); | |
85 | return; | |
86 | } | |
87 | fAddCall.InitWithPrototype(fClass, "Add", "const TObject*, const AliHLTComponentDataType&, AliHLTUInt32_t"); | |
88 | if (not fAddCall.IsValid()) | |
89 | { | |
90 | HLTError("Could not initialise method call object for class '%s' and method Add.", classname); | |
91 | return; | |
92 | } | |
f925a066 | 93 | fCalculateTriggerDecisionCall.InitWithPrototype(fClass, "CalculateTriggerDecision", "bool&, AliHLTTriggerDomain&, TString&"); |
81d62bb4 | 94 | if (not fCalculateTriggerDecisionCall.IsValid()) |
95 | { | |
96 | HLTError("Could not initialise method call object for class '%s' and method CalculateTriggerDecision.", classname); | |
97 | return; | |
98 | } | |
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()) | |
101 | { | |
102 | HLTError("Could not initialise method call object for class '%s' and method GetCounters.", classname); | |
103 | return; | |
104 | } | |
105 | fSetCountersCall.InitWithPrototype(fClass, "SetCounters", "TArrayL64&"); | |
106 | if (not fSetCountersCall.IsValid()) | |
107 | { | |
108 | HLTError("Could not initialise method call object for class '%s' and method SetCounters.", classname); | |
109 | return; | |
110 | } | |
111 | fObject = fClass->New(); | |
112 | if (fObject == NULL) | |
113 | { | |
114 | HLTError("Could not create a new object of type '%s'.", classname); | |
115 | } | |
325e5e42 | 116 | |
f2655396 | 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. | |
122 | union | |
123 | { | |
124 | void* fPtr; | |
125 | void (*fFuncPtr)(char*); | |
126 | }; | |
127 | fFuncPtr = AliHLTOnErrorInCINT; | |
128 | if (sizeof(fPtr) == sizeof(fFuncPtr)) | |
129 | { | |
1b820a65 | 130 | gInterpreter->SetErrmsgcallback(fPtr); |
f2655396 | 131 | } |
132 | else | |
133 | { | |
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." | |
137 | ); | |
138 | } | |
81d62bb4 | 139 | } |
140 | ||
141 | ||
142 | AliHLTGlobalTriggerWrapper::~AliHLTGlobalTriggerWrapper() | |
143 | { | |
144 | // Default destructor. | |
145 | ||
146 | fClass->Destructor(fObject); | |
f0da6a36 | 147 | G__set_errmsgcallback(NULL); |
81d62bb4 | 148 | } |
149 | ||
150 | ||
151 | void AliHLTGlobalTriggerWrapper::FillFromMenu(const AliHLTTriggerMenu& menu) | |
152 | { | |
153 | // Fills internal values from the trigger menu. | |
154 | ||
325e5e42 | 155 | fCallFailed = false; |
81d62bb4 | 156 | struct Params |
157 | { | |
158 | const void* fMenu; | |
159 | } params; | |
160 | params.fMenu = &menu; | |
161 | fFillFromMenuCall.SetParamPtrs(¶ms, 1); | |
325e5e42 | 162 | gCINTErrorMessage = ""; |
81d62bb4 | 163 | fFillFromMenuCall.Execute(fObject); |
325e5e42 | 164 | if (gCINTErrorMessage != "") |
81d62bb4 | 165 | { |
325e5e42 | 166 | fCallFailed = true; |
167 | HLTError(gCINTErrorMessage.Data()); | |
168 | HLTFatal("Error interpreting the code for class '%s' at line %d.", fClass->GetName(), G__lasterror_linenum()); | |
81d62bb4 | 169 | } |
170 | } | |
171 | ||
172 | ||
173 | void AliHLTGlobalTriggerWrapper::NewEvent() | |
174 | { | |
175 | // Clears the internal buffers for a new event. | |
176 | ||
325e5e42 | 177 | fCallFailed = false; |
178 | gCINTErrorMessage = ""; | |
81d62bb4 | 179 | fNewEventCall.Execute(fObject); |
325e5e42 | 180 | if (gCINTErrorMessage != "") |
81d62bb4 | 181 | { |
325e5e42 | 182 | fCallFailed = true; |
183 | HLTError(gCINTErrorMessage.Data()); | |
184 | HLTFatal("Error interpreting the code for class '%s' at line %d.", fClass->GetName(), G__lasterror_linenum()); | |
81d62bb4 | 185 | } |
186 | } | |
187 | ||
188 | ||
189 | void AliHLTGlobalTriggerWrapper::Add( | |
190 | const TObject* object, const AliHLTComponentDataType& type, | |
191 | AliHLTUInt32_t spec | |
192 | ) | |
193 | { | |
194 | // Adds parameters from the object to the internal buffers and variables. | |
195 | ||
325e5e42 | 196 | fCallFailed = false; |
81d62bb4 | 197 | struct Params |
198 | { | |
199 | const void* fObj; | |
200 | const void* fType; | |
201 | long fSpec; | |
202 | } params; | |
203 | params.fObj = object; | |
204 | params.fType = &type; | |
205 | params.fSpec = spec; | |
206 | fAddCall.SetParamPtrs(¶ms, 3); | |
325e5e42 | 207 | gCINTErrorMessage = ""; |
81d62bb4 | 208 | fAddCall.Execute(fObject); |
325e5e42 | 209 | if (gCINTErrorMessage != "") |
81d62bb4 | 210 | { |
325e5e42 | 211 | fCallFailed = true; |
212 | HLTError(gCINTErrorMessage.Data()); | |
213 | HLTFatal("Error interpreting the code for class '%s' at line %d.", fClass->GetName(), G__lasterror_linenum()); | |
81d62bb4 | 214 | } |
215 | } | |
216 | ||
217 | ||
f925a066 | 218 | bool AliHLTGlobalTriggerWrapper::CalculateTriggerDecision(bool& triggerResult, AliHLTTriggerDomain& domain, TString& description) |
81d62bb4 | 219 | { |
220 | // Calculates the global trigger decision. | |
221 | ||
325e5e42 | 222 | fCallFailed = false; |
81d62bb4 | 223 | struct Params |
224 | { | |
f925a066 | 225 | const void* fResult; |
81d62bb4 | 226 | const void* fDomain; |
227 | const void* fDesc; | |
228 | } params; | |
f925a066 | 229 | params.fResult = &triggerResult; |
81d62bb4 | 230 | params.fDomain = &domain; |
231 | params.fDesc = &description; | |
f925a066 | 232 | fCalculateTriggerDecisionCall.SetParamPtrs(¶ms, 3); |
81d62bb4 | 233 | Long_t retval; |
325e5e42 | 234 | gCINTErrorMessage = ""; |
81d62bb4 | 235 | fCalculateTriggerDecisionCall.Execute(fObject, retval); |
325e5e42 | 236 | if (gCINTErrorMessage != "") |
81d62bb4 | 237 | { |
325e5e42 | 238 | fCallFailed = true; |
239 | HLTError(gCINTErrorMessage.Data()); | |
240 | HLTFatal("Error interpreting the code for class '%s' at line %d.", fClass->GetName(), G__lasterror_linenum()); | |
241 | return false; | |
81d62bb4 | 242 | } |
243 | return bool(retval); | |
244 | } | |
245 | ||
246 | ||
247 | const TArrayL64& AliHLTGlobalTriggerWrapper::GetCounters() const | |
248 | { | |
249 | // Returns the internal counter array. | |
250 | ||
251 | Long_t retval = 0x0; | |
325e5e42 | 252 | gCINTErrorMessage = ""; |
81d62bb4 | 253 | fGetCountersCall.Execute(fObject, retval); |
325e5e42 | 254 | if (gCINTErrorMessage != "") |
81d62bb4 | 255 | { |
325e5e42 | 256 | fCallFailed = true; |
257 | HLTError(gCINTErrorMessage.Data()); | |
258 | HLTFatal("Error interpreting the code for class '%s' at line %d.", fClass->GetName(), G__lasterror_linenum()); | |
81d62bb4 | 259 | } |
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); | |
263 | return *ptr; | |
264 | } | |
265 | ||
266 | ||
267 | void AliHLTGlobalTriggerWrapper::SetCounters(const TArrayL64& counters) | |
268 | { | |
269 | // Fills the internal counter array with new values. | |
270 | ||
325e5e42 | 271 | fCallFailed = false; |
81d62bb4 | 272 | struct Params |
273 | { | |
274 | const void* fCounters; | |
275 | } params; | |
276 | params.fCounters = &counters; | |
277 | fSetCountersCall.SetParamPtrs(¶ms, 1); | |
325e5e42 | 278 | gCINTErrorMessage = ""; |
81d62bb4 | 279 | fSetCountersCall.Execute(fObject); |
325e5e42 | 280 | if (gCINTErrorMessage != "") |
81d62bb4 | 281 | { |
325e5e42 | 282 | fCallFailed = true; |
283 | HLTError(gCINTErrorMessage.Data()); | |
284 | HLTFatal("Error interpreting the code for class '%s' at line %d.", fClass->GetName(), G__lasterror_linenum()); | |
81d62bb4 | 285 | } |
286 | } | |
287 | ||
288 | ||
289 | bool AliHLTGlobalTriggerWrapper::IsValid() const | |
290 | { | |
291 | // Checks if the wrapper class was initialised correctly. | |
292 | ||
293 | return fClass != NULL and fObject != NULL and fFillFromMenuCall.IsValid() | |
294 | and fNewEventCall.IsValid() and fAddCall.IsValid() | |
295 | and fCalculateTriggerDecisionCall.IsValid(); | |
296 | } | |
297 |