#include <TGButton.h>
#include <TInterpreter.h>
+#include <TROOT.h>
#include <unistd.h>
#include <signal.h>
fRunList(0), fAutoRun(0), fStartButt(0), fStopButt(0), fExitButt(0),
fAutoRunTimer(0), fAutoRunScheduled(0), fAutoRunRunning(0),
fRun2PidMap(),
- fTestMode(kFALSE)
+ fTestMode(kFALSE),
+ fDoExit(kFALSE)
{
+ // Constructor.
+
// GUI components.
fRunList = new TGListBox(this);
AddFrame(fRunList, new TGLayoutHints(kLHintsNormal | kLHintsExpandX | kLHintsExpandY));
fAutoRunTimer = new TTimer(autoRunDelay * 1000l);
fAutoRunTimer->Connect("Timeout()", "AliOnlineReco", this, "AutoRunTimerTimeout()");
- // Signal handlers
+ // OS Signal handlers
// ROOT's TSignalHAndler works not SIGCHLD ...
AliChildProcTerminator::Instance()->Connect("ChildProcTerm(Int_t,Int_t)", "AliOnlineReco", this, "ChildProcTerm(Int_t,Int_t)");
+
+ // we need this by OnExit() to kill next process child after another
+ Connect("ChildProcTerm(Int_t,Int_t)", "AliOnlineReco", this, "ExitLoopChildProcTerm()");
}
AliOnlineReco::~AliOnlineReco()
{
+ // Destructor.
+
delete fAutoRunTimer;
}
Int_t AliOnlineReco::GetLastRun() const
{
+ // Returns the last started run.
+
return fRun2PidMap.empty() ? 0 : fRun2PidMap.rbegin()->first;
}
Bool_t AliOnlineReco::GetAutoRunMode() const
{
+ // Return state of auto-run flag.
+
return fAutoRun->IsOn();
}
void AliOnlineReco::SetAutoRunMode(Bool_t ar)
{
+ // Set auto-run flag.
+
if (ar == fAutoRun->IsOn())
return;
AliOnlineReco::mIntInt_i AliOnlineReco::FindMapEntryByPid(Int_t pid)
{
+ // Find run-to-pid map iterator by pid.
+ // Requires iteration over map.
+
for (mIntInt_i i = fRun2PidMap.begin(); i != fRun2PidMap.end(); ++i)
{
if (i->second == pid)
void AliOnlineReco::StartAliEve(mIntInt_i& mi)
{
+ // Start alieve to process run given my the run-pid entry.
+
Int_t run = mi->first;
if (mi->second == 0)
gCINTMutex = 0;
struct sigaction sac;
- sac.sa_handler = 0;
+ memset(&sac, 0, sizeof(sac));
+ sac.sa_handler = NULL;
sigemptyset(&sac.sa_mask);
sac.sa_flags = 0;
- sigaction(SIGCHLD, &sac, 0);
-
+
+ // The sa_restorer field is Not POSIX and obsolete.
+ // This is for compilation on other systems
+ #if defined(__linux) && \
+ (defined(__i386__) || defined(__x86_64__)) && \
+ defined(__GNUC__)
+ sac.sa_restorer= NULL;
+ #endif
+ sigaction(SIGCHLD, &sac, NULL);
+
int s;
if (fTestMode)
{
- s = execlp("alitestproc", "alitestproc", TString::Format("%d", run).Data(), (char*) 0);
+ s = execlp("alitestproc", "alitestproc", TString::Format("%d", run).Data(), (char*) 0);
}
else
{
- Int_t procPID = gSystem->GetPid();
- TString logFile = Form("%s/reco/log/run%d_%d.log",
- gSystem->Getenv("ONLINERECO_BASE_DIR"),
- run,
- (Int_t)procPID);
- Info("DoStart","Reconstruction log will be written to %s",logFile.Data());
- gSystem->RedirectOutput(logFile.Data());
-
- gSystem->cd(Form("%s/reco",gSystem->Getenv("ONLINERECO_BASE_DIR")));
-
- TString gdcs;
- if (RetrieveGRP(run,gdcs) <= 0 || gdcs.IsNull())
- gSystem->Exit(1);
-
- gSystem->Setenv("DATE_RUN_NUMBER", Form("%d", run));
- // Setting CDB
-// AliCDBManager * man = AliCDBManager::Instance();
-// man->SetDefaultStorage("local:///local/cdb");
-// man->SetSpecificStorage("GRP/GRP/Data",
-// Form("local://%s",gSystem->pwd()));
-// man->SetSpecificStorage("GRP/CTP/Config",
-// Form("local://%s",gSystem->pwd()));
-// man->SetSpecificStorage("ACORDE/Align/Data",
-// "local://$ALICE_ROOT/OCDB");
-
- gSystem->mkdir(Form("run%d_%d", run, (Int_t)procPID));
- gSystem->cd(Form("run%d_%d", run, (Int_t)procPID));
-
- TString recMacroPath(gSystem->Getenv("ONLINERECO_MACRO"));
- if (recMacroPath.IsNull()) {
- recMacroPath = "$ALICE_ROOT/MONITOR/rec.C";
- }
-
- s = execlp("alieve",
- "alieve",
- "-q",
- Form("%s(\"mem://@*:\")", gSystem->ExpandPathName(recMacroPath.Data())),
- (char*) 0);
+ Int_t procPID = gSystem->GetPid();
+ TString logFile = Form("%s/reco/log/run%d_%d.log",
+ gSystem->Getenv("ONLINERECO_BASE_DIR"),
+ run,
+ (Int_t)procPID);
+ Info("DoStart","Reconstruction log will be written to %s",logFile.Data());
+ gSystem->RedirectOutput(logFile.Data());
+
+ gSystem->cd(Form("%s/reco",gSystem->Getenv("ONLINERECO_BASE_DIR")));
+
+ TString gdcs;
+ if (RetrieveGRP(run,gdcs) <= 0 || gdcs.IsNull())
+ gSystem->Exit(1);
+
+ gSystem->Setenv("DATE_RUN_NUMBER", Form("%d", run));
+ // Setting CDB
+ // AliCDBManager * man = AliCDBManager::Instance();
+ // man->SetDefaultStorage("local:///local/cdb");
+ // man->SetSpecificStorage("GRP/GRP/Data",
+ // Form("local://%s",gSystem->pwd()));
+ // man->SetSpecificStorage("GRP/CTP/Config",
+ // Form("local://%s",gSystem->pwd()));
+ // man->SetSpecificStorage("ACORDE/Align/Data",
+ // "local://$ALICE_ROOT/OCDB");
+
+ gSystem->mkdir(Form("run%d_%d", run, (Int_t)procPID));
+ gSystem->cd(Form("run%d_%d", run, (Int_t)procPID));
+
+ TString recMacroPath(gSystem->Getenv("ONLINERECO_MACRO"));
+ if (recMacroPath.IsNull()) {
+ recMacroPath = "$ALICE_ROOT/MONITOR/rec.C";
+ }
+
+ s = execlp("alieve",
+ "alieve",
+ "-q",
+ Form("%s(\"mem://@*:\")", gSystem->ExpandPathName(recMacroPath.Data())),
+ (char*) 0);
+
}
if (s == -1)
{
- perror("execlp failed - this will not end well");
- gSystem->Exit(1);
+ perror("execlp failed - this will not end well");
+ gSystem->Exit(1);
}
}
}
void AliOnlineReco::KillPid(Int_t pid)
{
+ // Terminate process given by pid.
+
// Send terminate signal to process ...
if (fTestMode)
void AliOnlineReco::StopAutoRunTimer()
{
+ // Stop auto-run timer.
+
fAutoRunTimer->TurnOff();
fAutoRunScheduled = 0;
}
void AliOnlineReco::AutoRunTimerTimeout()
{
+ // Slot called on auto-timer timeout.
+
Int_t run = fAutoRunScheduled;
StopAutoRunTimer();
void AliOnlineReco::StartOfRun(Int_t run)
{
+ // Slot called from DIM handler on start of run.
+
mIntInt_i i = fRun2PidMap.find(run);
if (i == fRun2PidMap.end())
{
void AliOnlineReco::EndOfRun(Int_t run)
{
+ // Slot called from DIM handler on stop of run.
+
mIntInt_i i = fRun2PidMap.find(run);
if (i != fRun2PidMap.end())
{
void AliOnlineReco::ChildProcTerm(Int_t pid, Int_t status)
{
+ // Slot called on termination of child process.
+
printf("child process termination pid=%d, status=%d...\n", pid, status);
mIntInt_i i = FindMapEntryByPid(pid);
{
Int_t run = i->first;
fRunList->RemoveEntry(run);
+
+ // clean (remove) run's reconstructed directory
+ gSystem->Exec(Form("rm -rf %s/reco/run%d_%d",gSystem->Getenv("ONLINERECO_BASE_DIR"),run,pid));
+
if (status == 0)
{
fRunList->AddEntrySort(TString::Format("%-20d -- PROCESSED", run), run);
fRunList->AddEntrySort(TString::Format("%-20d -- PROCESSED [%d]", run, status), run);
}
fRunList->Layout();
- i->second = 0;
+ fRun2PidMap.erase(i);
if (fAutoRunRunning == run && fAutoRun->IsOn())
{
{
Warning("ChildProcTerm", "Process with pid=%d not registered.", pid);
}
+
+ Emit("ChildProcTerm(Int_t, Int_t)");
+}
+
+void AliOnlineReco::ExitLoopChildProcTerm()
+{
+ if(fDoExit)
+ DoExit();
}
//------------------------------------------------------------------------------
void AliOnlineReco::DoAutoRun()
{
+ // Slot called from auto-run check-box.
+
Bool_t autoRun = fAutoRun->IsOn();
if (autoRun)
void AliOnlineReco::DoStart()
{
+ // Slot called from Start button.
+
Int_t run = fRunList->GetSelected();
mIntInt_i i = fRun2PidMap.find(run);
void AliOnlineReco::DoStop()
{
+ // Slot called from Stop button.
+
Int_t run = fRunList->GetSelected();
mIntInt_i i = fRun2PidMap.find(run);
void AliOnlineReco::DoExit()
{
- gSystem->ExitLoop();
+ // Slot called from Exit button or CloseWindow.
+
+ // kill all started processes
+ Int_t pid;
+
+ // disable all widgets & AutoRunTimer
+ // so that user does not initiate other GUI signals
+ if(!fDoExit){
+ fAutoRun->SetEnabled(kFALSE);
+ fStartButt->SetEnabled(kFALSE);
+ fStopButt->SetEnabled(kFALSE);
+ fExitButt->SetEnabled(kFALSE);
+
+ StopAutoRunTimer();
+ fDoExit = kTRUE;
+ gROOT->SetInterrupt(kTRUE);
+ }
+
+ gSystem->ProcessEvents();
+
+ // clear runs std::map
+ for(mIntInt_i i = fRun2PidMap.begin(); i != fRun2PidMap.end(); i++)
+ {
+ pid = i->second;
+
+ if(pid==0)
+ {
+ fRun2PidMap.erase(i); // if process is not started just remove it from map
+ }
+ else
+ {
+ // send kill signal to started process
+ KillPid(pid);
+
+ // we need to exit loop to let ROOT process events list
+ // after kill signal above, process pid starts signal AliChildProcTerminator::ChildProcTerm(int, int)
+ // and arrives in AliOnlineReco::ChildProcTerm(int, int)
+ // after this we return in DoExit() to process next run
+ break;
+ }
+
+ }
+
+ // we can exit after we killed all processes
+ if(fRun2PidMap.empty() ) gSystem->ExitLoop();
}
void AliOnlineReco::CloseWindow()
{
- gSystem->ExitLoop();
+ // Virtual method called when window-manager close-window button is pressed.
+
+ DoExit();
+
}
-Int_t AliOnlineReco::RetrieveGRP(UInt_t run, TString &gdc) {
+Int_t AliOnlineReco::RetrieveGRP(UInt_t run, TString &gdc)
+{
+ // Retrieve GRP entry for given run from aldaqdb.
+
+ TString dbHost = gSystem->Getenv("ONLINERECO_DB_HOST");
+ if (dbHost.IsNull())
+ {
+ dbHost = "aldaqdb";
+ }
+
+ TString dbPort = gSystem->Getenv("ONLINERECO_DB_PORT");
+ if (dbPort.IsNull())
+ {
+ dbPort = "0";
+ }
+
+ TString dbName = gSystem->Getenv("ONLINERECO_DB_NAME");
+ if (dbName.IsNull())
+ {
+ dbName = "LOGBOOK";
+ }
+
+ TString user = gSystem->Getenv("ONLINERECO_DB_USER");
+ if (user.IsNull())
+ {
+ user = "logbook";
+ }
+
+ TString password = gSystem->Getenv("ONLINERECO_DB_PASSWORD");
+ if (password.IsNull())
+ {
+ password = "alice";
+ }
+
+ Int_t ret=AliGRPPreprocessor::ReceivePromptRecoParameters(run, dbHost.Data(),
+ dbPort.Atoi(), dbName.Data(),
+ user.Data(), password.Data(),
+ Form("local://%s",gSystem->pwd()),
+ gdc);
- Int_t ret=AliGRPPreprocessor::ReceivePromptRecoParameters(run, "aldaqdb", 0, "LOGBOOK", "logbook", "alice",
- Form("local://%s",gSystem->pwd()),
- gdc);
if(ret>0) Info("RetrieveGRP","Last run of the same type is: %d",ret);
else if(ret==0) Warning("RetrieveGRP","No previous run of the same type found");
else if(ret<0) Error("Retrieve","Error code while retrieving GRP parameters returned: %d",ret);