]>
Commit | Line | Data |
---|---|---|
c6d78c69 | 1 | // @(#)root/eve:$Id$ |
2 | // Author: Matevz Tadel 2007 | |
3 | ||
4 | /************************************************************************** | |
5 | * Copyright(c) 1998-2008, ALICE Experiment at CERN, all rights reserved. * | |
6 | * See http://aliceinfo.cern.ch/Offline/AliRoot/License.html for * | |
7 | * full copyright notice. * | |
8 | **************************************************************************/ | |
9 | ||
10 | #include "AliOnlineReco.h" | |
11 | #include "AliChildReaper.h" | |
12 | #include "AliDimIntNotifier.h" | |
13 | ||
14 | #include <TGListBox.h> | |
15 | #include <TGButton.h> | |
16 | ||
17 | #include <unistd.h> | |
18 | #include <signal.h> | |
19 | ||
20 | //______________________________________________________________________________ | |
21 | // Full description of AliOnlineReco | |
22 | // | |
23 | ||
24 | ClassImp(AliOnlineReco) | |
25 | ||
26 | AliOnlineReco::AliOnlineReco() : | |
27 | TGMainFrame(gClient->GetRoot(), 400, 400), | |
28 | ||
29 | fRunList(0), fStartButt(0), fStopButt(0), fXyzzButt(0), | |
30 | ||
31 | fSOR(new AliDimIntNotifier("/LOGBOOK/SUBSCRIBE/DAQ_SOR_PHYSICS")), | |
32 | fEOR(new AliDimIntNotifier("/LOGBOOK/SUBSCRIBE/DAQ_EOR_PHYSICS")), | |
33 | ||
34 | fTestMode(kFALSE) | |
35 | { | |
36 | // GUI components. | |
37 | fRunList = new TGListBox(this); | |
38 | AddFrame(fRunList, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY)); | |
39 | ||
40 | TGHorizontalFrame *hf = new TGHorizontalFrame(this, 1, 20); | |
41 | ||
42 | fStartButt = new TGTextButton(hf, "Start"); | |
43 | hf->AddFrame(fStartButt, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY)); | |
44 | fStartButt->Connect("Clicked()", "AliOnlineReco", this, "DoStart()"); | |
45 | ||
46 | fStopButt = new TGTextButton(hf, "Stop"); | |
47 | hf->AddFrame(fStopButt, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY)); | |
48 | fStopButt->Connect("Clicked()", "AliOnlineReco", this, "DoStop()"); | |
49 | ||
50 | fXyzzButt = new TGTextButton(hf, "Exit"); | |
51 | hf->AddFrame(fXyzzButt, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY)); | |
52 | fXyzzButt->Connect("Clicked()", "AliOnlineReco", this, "DoXyzz()"); | |
53 | ||
54 | AddFrame(hf, new TGLayoutHints(kLHintsNormal | kLHintsExpandX)); | |
55 | ||
56 | MapSubwindows(); | |
57 | Layout(); | |
58 | SetWindowName("Alice Online Reconstruction"); | |
59 | ||
60 | // DIM interface. | |
61 | fSOR->Connect("DimMessage(Int_t)", "AliOnlineReco", this, "StartOfRun(Int_t)"); | |
62 | fEOR->Connect("DimMessage(Int_t)", "AliOnlineReco", this, "EndOfRun(Int_t)"); | |
63 | ||
64 | // Signal handlers | |
65 | // ROOT's TSignalHAndler works not SIGCHLD ... | |
66 | AliChildReaper::Instance()->Connect("ChildDeath(Int_t,Int_t)", "AliOnlineReco", this, "ChildDeath(Int_t,Int_t)"); | |
67 | } | |
68 | ||
69 | AliOnlineReco::mIntInt_i AliOnlineReco::FindMapEntryByPid(Int_t pid) | |
70 | { | |
71 | for (mIntInt_i i = fRun2PidMap.begin(); i != fRun2PidMap.end(); ++i) | |
72 | { | |
73 | if (i->second == pid) | |
74 | return i; | |
75 | } | |
76 | ||
77 | return fRun2PidMap.end(); | |
78 | } | |
79 | ||
80 | //------------------------------------------------------------------------------ | |
81 | // Handlers of DIM signals. | |
82 | //------------------------------------------------------------------------------ | |
83 | ||
84 | void AliOnlineReco::StartOfRun(Int_t run) | |
85 | { | |
86 | mIntInt_i i = fRun2PidMap.find(run); | |
87 | if (i == fRun2PidMap.end()) | |
88 | { | |
89 | fRun2PidMap[run] = 0; | |
90 | fRunList->AddEntrySort(TString::Format("%d", run), run); | |
91 | fRunList->Layout(); | |
92 | } | |
93 | else | |
94 | { | |
95 | Error("StartOfRun", "Run %d already registered.", run); | |
96 | } | |
97 | } | |
98 | ||
99 | void AliOnlineReco::EndOfRun(Int_t run) | |
100 | { | |
101 | mIntInt_i i = fRun2PidMap.find(run); | |
102 | if (i != fRun2PidMap.end()) | |
103 | { | |
104 | Int_t pid = i->second; | |
105 | fRunList->RemoveEntry(run); | |
106 | fRunList->Layout(); | |
107 | fRun2PidMap.erase(i); | |
108 | if (pid) | |
109 | { | |
110 | // Send terminate signal to process ... | |
111 | if (fTestMode) | |
112 | { | |
113 | kill(pid, SIGTERM); | |
114 | } | |
115 | else | |
116 | { | |
117 | // alieve will auto-destruct on SIGUSR1 | |
118 | kill(pid, SIGUSR1); | |
119 | } | |
120 | } | |
121 | gClient->NeedRedraw(fRunList); | |
122 | } | |
123 | else | |
124 | { | |
125 | Error("EndOfRun", "Run %d not registered.", run); | |
126 | } | |
127 | } | |
128 | ||
129 | //------------------------------------------------------------------------------ | |
130 | // Handlers of OS signals. | |
131 | //------------------------------------------------------------------------------ | |
132 | ||
133 | void AliOnlineReco::ChildDeath(Int_t pid, Int_t status) | |
134 | { | |
135 | printf("child death pid=%d, statues=%d...\n", pid, status); | |
136 | ||
137 | mIntInt_i i = FindMapEntryByPid(pid); | |
138 | if (i != fRun2PidMap.end()) | |
139 | { | |
140 | Int_t run = i->first; | |
141 | fRunList->RemoveEntry(run); | |
142 | if (status == 0) | |
143 | { | |
144 | fRunList->AddEntrySort(TString::Format("%-20d -- FINISHED", run), run); | |
145 | } | |
146 | else | |
147 | { | |
148 | fRunList->AddEntrySort(TString::Format("%-20d -- CRASHED [%d]", run, status), run); | |
149 | } | |
150 | fRunList->Layout(); | |
151 | i->second = 0; | |
152 | } | |
153 | else | |
154 | { | |
155 | Warning("ChildDeath", "Process with pid=%d not registered.", pid); | |
156 | } | |
157 | } | |
158 | ||
159 | //------------------------------------------------------------------------------ | |
160 | // Handlers of button signals. | |
161 | //------------------------------------------------------------------------------ | |
162 | ||
163 | void AliOnlineReco::DoStart() | |
164 | { | |
165 | Int_t run = fRunList->GetSelected(); | |
166 | mIntInt_i i = fRun2PidMap.find(run); | |
167 | ||
168 | if (i == fRun2PidMap.end()) | |
169 | { | |
170 | Error("DoStart", "no selection"); | |
171 | return; | |
172 | } | |
173 | ||
174 | if (i->second == 0) | |
175 | { | |
176 | pid_t pid = fork(); | |
177 | if (pid == -1) | |
178 | { | |
179 | perror("DoStart -- Fork failed"); | |
180 | return; | |
181 | } | |
182 | ||
183 | if (pid) | |
184 | { | |
185 | i->second = pid; | |
186 | fRunList->RemoveEntry(run); | |
187 | fRunList->AddEntrySort(TString::Format("%-20d -- RUNNING", run), run); | |
188 | fRunList->Layout(); | |
189 | } | |
190 | else | |
191 | { | |
192 | int s; | |
193 | if (fTestMode) | |
194 | { | |
195 | s = execlp("alitestproc", "alitestproc", TString::Format("%d", run).Data(), (char*) 0); | |
196 | } | |
197 | else | |
198 | { | |
199 | // !!!! Cvetan, add proper args here ... | |
200 | s = execlp("alieve", "alieve", TString::Format("%d", run).Data(), (char*) 0); | |
201 | } | |
202 | ||
203 | if (s == -1) | |
204 | { | |
205 | perror("execlp failed - this will not end well"); | |
206 | gSystem->Exit(1); | |
207 | } | |
208 | } | |
209 | } | |
210 | else | |
211 | { | |
212 | Error("DoStart", "Process already running."); | |
213 | } | |
214 | } | |
215 | ||
216 | void AliOnlineReco::DoStop() | |
217 | { | |
218 | Int_t run = fRunList->GetSelected(); | |
219 | mIntInt_i i = fRun2PidMap.find(run); | |
220 | ||
221 | if (i == fRun2PidMap.end()) | |
222 | { | |
223 | Error("DoStop", "no selection"); | |
224 | return; | |
225 | } | |
226 | ||
227 | Int_t pid = i->second; | |
228 | if (pid) | |
229 | { | |
230 | if (fTestMode) | |
231 | { | |
232 | kill(pid, SIGTERM); | |
233 | } | |
234 | else | |
235 | { | |
236 | // alieve will auto-destruct on SIGUSR1 | |
237 | kill(pid, SIGUSR1); | |
238 | } | |
239 | } | |
240 | else | |
241 | { | |
242 | Error("DoStop", "Process not running."); | |
243 | } | |
244 | } | |
245 | ||
246 | void AliOnlineReco::DoXyzz() | |
247 | { | |
248 | gSystem->ExitLoop(); | |
249 | } | |
250 | ||
251 | void AliOnlineReco::CloseWindow() | |
252 | { | |
253 | gSystem->ExitLoop(); | |
254 | } |