MIDAS
Loading...
Searching...
No Matches
TMFrontend Class Reference

#include <tmfe.h>

Inheritance diagram for TMFrontend:
Collaboration diagram for TMFrontend:

Public Member Functions

 TMFrontend ()
 
virtual ~TMFrontend ()
 
int FeMain (int argc, char *argv[])
 
int FeMain (const std::vector< std::string > &args)
 
void FeUsage (const char *argv0)
 
virtual TMFeResult HandleArguments (const std::vector< std::string > &args)
 
virtual void HandleUsage ()
 
virtual TMFeResult HandleFrontendInit (const std::vector< std::string > &args)
 
virtual TMFeResult HandleFrontendReady (const std::vector< std::string > &args)
 
virtual void HandleFrontendExit ()
 
void FeSetName (const char *program_name)
 
TMFeResult FeAddEquipment (TMFeEquipment *eq)
 
TMFeResult FeRemoveEquipment (TMFeEquipment *eq)
 
TMFeResult FeInitEquipments (const std::vector< std::string > &args)
 
void FeDeleteEquipments ()
 
void FeStopEquipmentPollThreads ()
 
double FePeriodicTasks ()
 
double FePollTasks (double next_periodic_time)
 
TMFeResult FeInit (const std::vector< std::string > &args)
 
void FeMainLoop ()
 
void FeShutdown ()
 
void FePollMidas (double sleep_sec)
 
void FePeriodicThread ()
 
void FeStartPeriodicThread ()
 
void FeStopPeriodicThread ()
 

Public Attributes

TMFEfMfe = NULL
 
TMFrontendRpcHelperfFeRpcHelper = NULL
 
int fFeIndex = 0
 
bool fFeIfRunningCallExit = false
 
bool fFeIfRunningCallBeginRun = true
 
std::mutex fFeMutex
 
std::vector< TMFeEquipment * > fFeEquipments
 
std::thread * fFePeriodicThread = NULL
 
std::atomic_bool fFePeriodicThreadStarting {false}
 
std::atomic_bool fFePeriodicThreadRunning {false}
 
std::atomic_bool fFePeriodicThreadShutdownRequested {false}
 
double fFeFlushWriteCachePeriodSec = 0.5
 
double fFeFlushWriteCacheNextCallTime = 0
 

Detailed Description

Definition at line 306 of file tmfe.h.

Constructor & Destructor Documentation

◆ TMFrontend()

TMFrontend::TMFrontend ( )

Definition at line 1540 of file tmfe.cxx.

1541{
1542 fMfe = TMFE::Instance();
1543}
static TMFE * Instance()
Definition tmfe.cxx:57
TMFE * fMfe
Definition tmfe.h:309
Here is the call graph for this function:

◆ ~TMFrontend()

TMFrontend::~TMFrontend ( )
virtual

Definition at line 1545 of file tmfe.cxx.

1546{
1547 if (fFeRpcHelper) {
1549 delete fFeRpcHelper;
1551 }
1552 // poison all pointers
1553 fMfe = NULL;
1554}
void RemoveRpcHandler(TMFeRpcHandlerInterface *)
Definition tmfe.cxx:1531
TMFrontendRpcHelper * fFeRpcHelper
Definition tmfe.h:310
TH1X EXPRT * h1_book(const char *name, const char *title, int bins, double min, double max)
Definition rmidas.h:24
Here is the call graph for this function:

Member Function Documentation

◆ FeAddEquipment()

TMFeResult TMFrontend::FeAddEquipment ( TMFeEquipment eq)

Definition at line 1600 of file tmfe.cxx.

1601{
1602 // NOTE: not thread-safe, we modify the fEquipments object. K.O.
1603
1604 // NOTE: should not use range-based for() loop, it uses an iterator and it not thread-safe. K.O.
1605 for (unsigned i=0; i<fFeEquipments.size(); i++) {
1606 if (!fFeEquipments[i])
1607 continue;
1608 if (fFeEquipments[i] == eq) {
1609 fprintf(stderr, "TMFE::AddEquipment: Fatal error: Equipment \"%s\" is already registered, bye...\n", fFeEquipments[i]->fEqName.c_str());
1610 fMfe->Disconnect();
1611 exit(1);
1612 //return TMFeErrorMessage(msprintf("TMFE::AddEquipment: Equipment \"%s\" is already registered", fFeEquipments[i]->fEqName.c_str()));
1613 }
1614 if (fFeEquipments[i]->fEqName == eq->fEqName) {
1615 fprintf(stderr, "TMFE::AddEquipment: Fatal error: Duplicate equipment name \"%s\", bye...\n", eq->fEqName.c_str());
1616 fMfe->Disconnect();
1617 exit(1);
1618 //return TMFeErrorMessage(std::string("TMFE::AddEquipment: Duplicate equipment name \"") + eq->fEqName + "\"");
1619 }
1620 }
1621
1622 eq->fFe = this;
1623
1624 // NOTE: fEquipments must be protected again multithreaded access here. K.O.
1625 fFeEquipments.push_back(eq);
1626
1627 return TMFeOk();
1628}
TMFeResult Disconnect()
Definition tmfe.cxx:154
std::vector< TMFeEquipment * > fFeEquipments
Definition tmfe.h:343
INT i
Definition mdump.cxx:32
std::vector< FMT_ID > eq
Definition mdump.cxx:55
TMFeResult TMFeOk()
Definition tmfe.h:106
Here is the call graph for this function:
Here is the caller graph for this function:

◆ FeDeleteEquipments()

void TMFrontend::FeDeleteEquipments ( )

Definition at line 1581 of file tmfe.cxx.

1582{
1583 // NOTE: this is thread-safe: we do not modify the fEquipments object. K.O.
1584 // NOTE: this is not thread-safe, we will race against ourselves and do multiple delete of fEquipents[i]. K.O.
1585
1586 // NOTE: should not use range-based for() loop, it uses an iterator and it not thread-safe. K.O.
1587 for (unsigned i=0; i<fFeEquipments.size(); i++) {
1588 if (!fFeEquipments[i])
1589 continue;
1590 //printf("delete equipment [%s]\n", fFeEquipments[i]->fEqName.c_str());
1592 delete fFeEquipments[i];
1593 fFeEquipments[i] = NULL;
1594 }
1595
1598}
TMFeResult EventBufferCloseAll()
Definition tmfe.cxx:484
TMFeResult EventBufferFlushCacheAll(bool wait=true)
Definition tmfe.cxx:448
Here is the call graph for this function:
Here is the caller graph for this function:

◆ FeInit()

TMFeResult TMFrontend::FeInit ( const std::vector< std::string > &  args)

Definition at line 2289 of file tmfe.cxx.

2290{
2291 setbuf(stdout, NULL);
2292 setbuf(stderr, NULL);
2293
2295
2296 std::vector<std::string> eq_args;
2297
2298 bool help = false;
2299 std::string exptname;
2300 std::string hostname;
2301 bool daemon0 = false;
2302 bool daemon1 = false;
2303
2304 for (unsigned int i=1; i<args.size(); i++) { // loop over the commandline options
2305 //printf("argv[%d] is %s\n", i, args[i].c_str());
2306 if (args[i] == "--") {
2307 // remaining arguments are passed to equipment Init()
2308 for (unsigned j=i+1; j<args.size(); j++)
2309 eq_args.push_back(args[j]);
2310 break;
2311 } else if (args[i] == "-v") {
2312 TMFE::gfVerbose = true;
2313 } else if (args[i] == "-D") {
2314 daemon0 = true;
2315 } else if (args[i] == "-O") {
2316 daemon1 = true;
2317 } else if (args[i] == "-h") {
2318 i++;
2319 if (i >= args.size()) { help = true; break; }
2320 hostname = args[i];
2321 } else if (args[i] == "-e") {
2322 i++;
2323 if (i >= args.size()) { help = true; break; }
2324 exptname = args[i];
2325 } else if (args[i] == "-i") {
2326 i++;
2327 if (i >= args.size()) { help = true; break; }
2328 fFeIndex = atoi(args[i].c_str());
2329 } else if (args[i] == "--help") {
2330 help = true;
2331 break;
2332 } else if (args[i][0] == '-') {
2333 help = true;
2334 break;
2335 } else {
2336 help = true;
2337 break;
2338 }
2339 }
2340
2341 //
2342 // daemonize...
2343 //
2344
2345 if (daemon0) {
2346 printf("Becoming a daemon...\n");
2348 } else if (daemon1) {
2349 printf("Becoming a daemon...\n");
2351 }
2352
2353 //
2354 // apply frontend index to indexed frontend
2355 //
2356
2357 if (fMfe->fProgramName.find("%") != std::string::npos) {
2359 }
2360
2361 TMFeResult r;
2362
2363 // call arguments handler before calling the usage handlers. Otherwise,
2364 // if the arguments handler creates new equipments,
2365 // we will never see their Usage(). K.O.
2367
2368 if (r.error_flag) {
2369 fprintf(stderr, "Fatal error: arguments handler error: %s, bye.\n", r.error_message.c_str());
2370 fMfe->Disconnect();
2371 exit(1);
2372 }
2373
2374 if (help) {
2375 FeUsage(args[0].c_str());
2376 HandleUsage();
2377 fMfe->Disconnect();
2378 exit(1);
2379 }
2380
2381 r = fMfe->Connect(NULL, hostname.c_str(), exptname.c_str());
2382
2383 if (r.error_flag) {
2384 fprintf(stderr, "Fatal error: cannot connect to MIDAS, error: %s, bye.\n", r.error_message.c_str());
2385 fMfe->Disconnect();
2386 exit(1);
2387 }
2388
2390
2391 if (r.error_flag) {
2392 fprintf(stderr, "Fatal error: frontend init error: %s, bye.\n", r.error_message.c_str());
2393 fMfe->Disconnect();
2394 exit(1);
2395 }
2396
2399
2400 //mfe->SetWatchdogSec(0);
2401 //mfe->SetTransitionSequenceStart(910);
2402 //mfe->SetTransitionSequenceStop(90);
2403 //mfe->DeregisterTransitionPause();
2404 //mfe->DeregisterTransitionResume();
2405 //mfe->RegisterTransitionStartAbort();
2406
2408
2409 if (r.error_flag) {
2410 fprintf(stderr, "Cannot initialize equipments, error message: %s, bye.\n", r.error_message.c_str());
2411 fMfe->Disconnect();
2412 exit(1);
2413 }
2414
2416
2417 if (r.error_flag) {
2418 fprintf(stderr, "Fatal error: frontend post-init error: %s, bye.\n", r.error_message.c_str());
2419 fMfe->Disconnect();
2420 exit(1);
2421 }
2422
2423 if (fMfe->fStateRunning) {
2425 fprintf(stderr, "Fatal error: Cannot start frontend, run is in progress!\n");
2426 fMfe->Disconnect();
2427 exit(1);
2428 } else if (fFeIfRunningCallBeginRun) {
2429 char errstr[TRANSITION_ERROR_STRING_LENGTH];
2430 tr_start(fMfe->fRunNumber, errstr);
2431 }
2432 }
2433
2434 return TMFeOk();
2435}
#define FALSE
Definition cfortran.h:309
bool fStateRunning
run state is running or paused
Definition tmfe.h:402
void AddRpcHandler(TMFeRpcHandlerInterface *)
Definition tmfe.cxx:1526
static bool gfVerbose
Definition tmfe.h:424
TMFeResult Connect(const char *progname=NULL, const char *hostname=NULL, const char *exptname=NULL)
Definition tmfe.cxx:65
std::string fProgramName
frontend program name
Definition tmfe.h:387
int fRunNumber
current run number
Definition tmfe.h:401
bool error_flag
Definition tmfe.h:89
std::string error_message
Definition tmfe.h:91
bool fFeIfRunningCallBeginRun
Definition tmfe.h:316
int fFeIndex
Definition tmfe.h:313
TMFeResult FeInitEquipments(const std::vector< std::string > &args)
Definition tmfe.cxx:1556
void FeUsage(const char *argv0)
Definition tmfe.cxx:2250
virtual TMFeResult HandleArguments(const std::vector< std::string > &args)
Definition tmfe.h:331
virtual TMFeResult HandleFrontendInit(const std::vector< std::string > &args)
Definition tmfe.h:333
bool fFeIfRunningCallExit
Definition tmfe.h:315
virtual TMFeResult HandleFrontendReady(const std::vector< std::string > &args)
Definition tmfe.h:334
virtual void HandleUsage()
Definition tmfe.h:332
INT ss_daemon_init(BOOL keep_stdout)
Definition system.cxx:2001
INT tr_start(INT rn, char *error)
Definition mana.cxx:2014
void help()
Definition mh2sql.cxx:244
std::string msprintf(const char *format,...)
Definition midas.cxx:410
#define TRUE
Definition midas.h:182
#define TRANSITION_ERROR_STRING_LENGTH
Definition midas.h:280
INT j
Definition odbhist.cxx:40
Here is the call graph for this function:
Here is the caller graph for this function:

◆ FeInitEquipments()

TMFeResult TMFrontend::FeInitEquipments ( const std::vector< std::string > &  args)

Definition at line 1556 of file tmfe.cxx.

1557{
1558 // NOTE: cannot use range-based for() loop, it uses an iterator and will crash if HandleInit() modifies fEquipments. K.O.
1559 for (unsigned i=0; i<fFeEquipments.size(); i++) {
1560 if (!fFeEquipments[i])
1561 continue;
1562 if (!fFeEquipments[i]->fEqConfEnabled)
1563 continue;
1564 TMFeResult r = fFeEquipments[i]->EqInit(args);
1565 if (r.error_flag)
1566 return r;
1567 }
1568 return TMFeOk();
1569}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ FeMain() [1/2]

int TMFrontend::FeMain ( const std::vector< std::string > &  args)

Definition at line 2454 of file tmfe.cxx.

2455{
2456 TMFeResult r = FeInit(args);
2457
2458 if (r.error_flag) {
2459 fprintf(stderr, "Fatal error: frontend init error: %s, bye.\n", r.error_message.c_str());
2460 fMfe->Disconnect();
2461 exit(1);
2462 }
2463
2464 FeMainLoop();
2465 FeShutdown();
2466
2467 return 0;
2468}
void FeShutdown()
Definition tmfe.cxx:2444
void FeMainLoop()
Definition tmfe.cxx:2437
TMFeResult FeInit(const std::vector< std::string > &args)
Definition tmfe.cxx:2289
Here is the call graph for this function:

◆ FeMain() [2/2]

int TMFrontend::FeMain ( int  argc,
char argv[] 
)

Definition at line 2279 of file tmfe.cxx.

2280{
2281 std::vector<std::string> args;
2282 for (int i=0; i<argc; i++) {
2283 args.push_back(argv[i]);
2284 }
2285
2286 return FeMain(args);
2287}
int FeMain(int argc, char *argv[])
Definition tmfe.cxx:2279
Here is the call graph for this function:
Here is the caller graph for this function:

◆ FeMainLoop()

void TMFrontend::FeMainLoop ( )

Definition at line 2437 of file tmfe.cxx.

2438{
2439 while (!fMfe->fShutdownRequested) {
2440 FePollMidas(0.100);
2441 }
2442}
std::atomic_bool fShutdownRequested
shutdown was requested by Ctrl-C or by RPC command
Definition tmfe.h:398
void FePollMidas(double sleep_sec)
Definition tmfe.cxx:745
Here is the call graph for this function:
Here is the caller graph for this function:

◆ FePeriodicTasks()

double TMFrontend::FePeriodicTasks ( )

Definition at line 507 of file tmfe.cxx.

508{
509 double now = TMFE::GetTime();
510
511 double next_periodic = now + 60;
512
513 int n = fFeEquipments.size();
514 for (int i=0; i<n; i++) {
516 if (!eq)
517 continue;
518 if (!eq->fEqConfEnabled)
519 continue;
520 if (!eq->fEqConfEnablePeriodic)
521 continue;
522 double period = eq->fEqConfPeriodMilliSec/1000.0;
523 if (period <= 0)
524 continue;
525 if (eq->fEqPeriodicNextCallTime == 0)
526 eq->fEqPeriodicNextCallTime = now + 0.5; // we are off by 0.5 sec with updating of statistics
527 //printf("periodic[%d] period %f, last call %f, next call %f (%f)\n", i, period, eq->fEqPeriodicLastCallTime, eq->fEqPeriodicNextCallTime, now - eq->fEqPeriodicNextCallTime);
528 if (now >= eq->fEqPeriodicNextCallTime) {
529 eq->fEqPeriodicNextCallTime += period;
530
531 if (eq->fEqPeriodicNextCallTime < now) {
532 if (TMFE::gfVerbose)
533 printf("TMFE::EquipmentPeriodicTasks: periodic equipment \"%s\" skipped some beats!\n", eq->fEqName.c_str());
534 fMfe->Msg(MERROR, "TMFE::EquipmentPeriodicTasks", "Equipment \"%s\" skipped some beats!", eq->fEqName.c_str());
535 while (eq->fEqPeriodicNextCallTime < now) {
536 eq->fEqPeriodicNextCallTime += period;
537 }
538 }
539
540 if (fMfe->fStateRunning || !eq->fEqConfReadOnlyWhenRunning) {
541 eq->fEqPeriodicLastCallTime = now;
542 //printf("handler %d eq [%s] call HandlePeriodic()\n", i, h->fEq->fName.c_str());
543 eq->HandlePeriodic();
544 }
545
546 now = TMFE::GetTime();
547 }
548
549 if (eq->fEqPeriodicNextCallTime < next_periodic)
550 next_periodic = eq->fEqPeriodicNextCallTime;
551 }
552
553 now = TMFE::GetTime();
554
555 // update statistics
556 for (auto eq : fFeEquipments) {
557 if (!eq)
558 continue;
559 if (!eq->fEqConfEnabled)
560 continue;
561 double next = eq->fEqStatNextWrite; // NOTE: this is not thread-safe, possible torn read of "double"
562 if (now > next) {
563 eq->EqWriteStatistics();
564 next = eq->fEqStatNextWrite; // NOTE: this is not thread-safe, possible torn read of "double"
565 }
566 if (next < next_periodic)
567 next_periodic = next;
568 }
569
570 now = TMFE::GetTime();
571
572 // flush write cache
578 }
579
580 return next_periodic;
581}
static double GetTime()
return current time in seconds, with micro-second precision
Definition tmfe.cxx:1011
void Msg(int message_type, const char *filename, int line, const char *routine, const char *format,...) MATTRPRINTF(6
Definition tmfe.cxx:991
int fEqConfPeriodMilliSec
Definition tmfe.h:178
double fFeFlushWriteCacheNextCallTime
Definition tmfe.h:376
double fFeFlushWriteCachePeriodSec
Definition tmfe.h:375
DWORD n[4]
Definition mana.cxx:247
#define MERROR
Definition tmfe.h:72
Here is the call graph for this function:
Here is the caller graph for this function:

◆ FePeriodicThread()

void TMFrontend::FePeriodicThread ( )

Definition at line 883 of file tmfe.cxx.

884{
885 if (TMFE::gfVerbose)
886 printf("TMFE::PeriodicThread: periodic thread started\n");
887
891 double now = TMFE::GetTime();
892 double sleep = next_periodic_time - now;
893 //printf("TMFrontend::FePeriodicThread: now %.6f next %.6f, sleep %.6f\n", now, next_periodic_time, sleep);
894 if (sleep >= 1.0)
895 sleep = 1.0;
897 }
898 if (TMFE::gfVerbose)
899 printf("TMFE::PeriodicThread: periodic thread stopped\n");
901}
static void Sleep(double sleep_time_sec)
sleep, with micro-second precision
Definition tmfe.cxx:1019
std::atomic_bool fFePeriodicThreadRunning
Definition tmfe.h:371
double FePeriodicTasks()
Definition tmfe.cxx:507
std::atomic_bool fFePeriodicThreadShutdownRequested
Definition tmfe.h:372
#define sleep(ms)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ FePollMidas()

void TMFrontend::FePollMidas ( double  sleep_sec)

Definition at line 745 of file tmfe.cxx.

746{
747 assert(sleep_sec >= 0);
748 bool debug = false;
749 double now = TMFE::GetTime();
750 double sleep_start = now;
751 double sleep_end = now + sleep_sec;
752 int count_yield_loops = 0;
753
754 while (!fMfe->fShutdownRequested) {
755 double next_periodic_time = 0;
756 double poll_sleep = 1.0;
757
761 } else {
763 }
764
765 if (fMfe->fRunStopRequested) {
766 fMfe->StopRun();
767 continue;
768 }
769
770 now = TMFE::GetTime();
771
773 fMfe->StartRun();
774 continue;
775 }
776
777 double sleep_time = sleep_end - now;
778
781 }
782
783 int s = 0;
784 if (sleep_time > 0)
785 s = 1 + sleep_time*1000.0;
786
787 if (poll_sleep*1000.0 < s) {
788 s = 0;
789 }
790
791 if (debug) {
792 printf("now %.6f, sleep_end %.6f, next_periodic %.6f, sleep_time %.6f, cm_yield(%d), poll period %.6f\n", now, sleep_end, next_periodic_time, sleep_time, s, poll_sleep);
793 }
794
795 int status = cm_yield(s);
796
797 if (status == RPC_SHUTDOWN || status == SS_ABORT) {
798 fMfe->fShutdownRequested = true;
799 if (TMFE::gfVerbose) {
800 fprintf(stderr, "TMFE::PollMidas: cm_yield(%d) status %d, shutdown requested...\n", s, status);
801 }
802 }
803
804 now = TMFE::GetTime();
805 double sleep_more = sleep_end - now;
806 if (sleep_more <= 0)
807 break;
808
810
811 if (poll_sleep < sleep_more) {
813 }
814 }
815
816 if (debug) {
817 printf("TMFE::PollMidas: sleep %.1f msec, actual %.1f msec, %d loops\n", sleep_sec * 1000.0, (now - sleep_start) * 1000.0, count_yield_loops);
818 }
819}
bool fRunStopRequested
run stop was requested by equipment
Definition tmfe.h:444
double fRunStartTime
start a new run at this time
Definition tmfe.h:445
void StopRun()
Definition tmfe.cxx:687
void StartRun()
Definition tmfe.cxx:714
double FePollTasks(double next_periodic_time)
Definition tmfe.cxx:583
INT cm_yield(INT millisec)
Definition midas.cxx:5642
#define SS_ABORT
Definition midas.h:677
#define RPC_SHUTDOWN
Definition midas.h:707
BOOL debug
debug printouts
Definition mana.cxx:254
DWORD status
Definition odbhist.cxx:39
Here is the call graph for this function:
Here is the caller graph for this function:

◆ FePollTasks()

double TMFrontend::FePollTasks ( double  next_periodic_time)

Definition at line 583 of file tmfe.cxx.

584{
585 //printf("poll %f next %f diff %f\n", TMFE::GetTime(), next_periodic_time, next_periodic_time - TMFE::GetTime());
586
587 double poll_sleep_sec = 9999.0;
588 while (!fMfe->fShutdownRequested) {
589 bool poll_again = false;
590 // NOTE: ok to use range-based for() loop, there will be a crash if HandlePoll() or HandlePollRead() modify fEquipments, so they should not do that. K.O.
591 for (auto eq : fFeEquipments) {
592 if (!eq)
593 continue;
594 if (!eq->fEqConfEnabled)
595 continue;
596 if (eq->fEqConfEnablePoll && !eq->fEqPollThreadRunning && !eq->fEqPollThreadStarting) {
597 if (fMfe->fStateRunning || !eq->fEqConfReadOnlyWhenRunning) {
598 if (eq->fEqConfPollSleepSec < poll_sleep_sec)
599 poll_sleep_sec = eq->fEqConfPollSleepSec;
600 bool poll = eq->HandlePoll();
601 if (poll) {
602 poll_again = true;
603 eq->HandlePollRead();
604 }
605 }
606 }
607 }
608 if (!poll_again)
609 break;
610
611 if (next_periodic_time) {
612 // stop polling if we need to run periodic activity
613 double now = TMFE::TMFE::GetTime();
614 if (now >= next_periodic_time)
615 break;
616 }
617 }
618 return poll_sleep_sec;
619}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ FeRemoveEquipment()

TMFeResult TMFrontend::FeRemoveEquipment ( TMFeEquipment eq)

Definition at line 1630 of file tmfe.cxx.

1631{
1632 // NOTE: this is thread-safe, we do not modify the fEquipments object. K.O.
1633
1634 // NOTE: should not use range-based for() loop, it uses an iterator and it not thread-safe. K.O.
1635 for (unsigned i=0; i<fFeEquipments.size(); i++) {
1636 if (!fFeEquipments[i])
1637 continue;
1638 if (fFeEquipments[i] == eq) {
1639 fFeEquipments[i] = NULL;
1640 return TMFeOk();
1641 }
1642 }
1643
1644 return TMFeErrorMessage(msprintf("TMFE::RemoveEquipment: Cannot find equipment \"%s\"", eq->fEqName.c_str()));
1645}
TMFeResult TMFeErrorMessage(const std::string &message)
Definition tmfe.cxx:29
Here is the call graph for this function:

◆ FeSetName()

void TMFrontend::FeSetName ( const char program_name)

Definition at line 1647 of file tmfe.cxx.

1648{
1649 assert(program_name != NULL);
1651}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ FeShutdown()

void TMFrontend::FeShutdown ( )

Definition at line 2444 of file tmfe.cxx.

2445{
2451 fMfe->Disconnect();
2452}
void StopRpcThread()
Definition tmfe.cxx:935
void FeDeleteEquipments()
Definition tmfe.cxx:1581
virtual void HandleFrontendExit()
Definition tmfe.h:335
void FeStopEquipmentPollThreads()
Definition tmfe.cxx:1571
void FeStopPeriodicThread()
Definition tmfe.cxx:963
Here is the call graph for this function:
Here is the caller graph for this function:

◆ FeStartPeriodicThread()

void TMFrontend::FeStartPeriodicThread ( )

Definition at line 919 of file tmfe.cxx.

920{
921 // NOTE: this is thread safe
922
923 std::lock_guard<std::mutex> guard(fFeMutex);
924
926 if (TMFE::gfVerbose)
927 printf("TMFE::StartPeriodicThread: periodic thread already running\n");
928 return;
929 }
930
932 fFePeriodicThread = new std::thread(&TMFrontend::FePeriodicThread, this);
933}
std::thread * fFePeriodicThread
Definition tmfe.h:369
void FePeriodicThread()
Definition tmfe.cxx:883
std::mutex fFeMutex
Definition tmfe.h:319
std::atomic_bool fFePeriodicThreadStarting
Definition tmfe.h:370
Here is the call graph for this function:

◆ FeStopEquipmentPollThreads()

void TMFrontend::FeStopEquipmentPollThreads ( )

Definition at line 1571 of file tmfe.cxx.

1572{
1573 // NOTE: should not use range-based for() loop, it uses an iterator and it not thread-safe. K.O.
1574 for (unsigned i=0; i<fFeEquipments.size(); i++) {
1575 if (!fFeEquipments[i])
1576 continue;
1577 fFeEquipments[i]->EqStopPollThread();
1578 }
1579}
Here is the caller graph for this function:

◆ FeStopPeriodicThread()

void TMFrontend::FeStopPeriodicThread ( )

Definition at line 963 of file tmfe.cxx.

964{
965 // NOTE: this is thread safe
966
969
970 for (int i=0; i<60; i++) {
972 std::lock_guard<std::mutex> guard(fFeMutex);
973 if (fFePeriodicThread) {
974 fFePeriodicThread->join();
975 delete fFePeriodicThread;
977 if (TMFE::gfVerbose)
978 printf("TMFE::StopPeriodicThread: periodic thread stopped\n");
979 }
980 return;
981 }
982 if (i>5) {
983 fprintf(stderr, "TMFE::StopPeriodicThread: waiting for periodic thread to stop\n");
984 }
985 ::sleep(1);
986 }
987
988 fprintf(stderr, "TMFE::StopPeriodicThread: timeout waiting for periodic thread to stop\n");
989}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ FeUsage()

void TMFrontend::FeUsage ( const char argv0)

Definition at line 2250 of file tmfe.cxx.

2251{
2252 fprintf(stderr, "\n");
2253 fprintf(stderr, "Usage: %s args... [-- equipment args...]\n", argv0);
2254 fprintf(stderr, "\n");
2255 fprintf(stderr, " --help -- print this help message\n");
2256 fprintf(stderr, " -h -- print this help message\n");
2257 fprintf(stderr, " -v -- report all activities\n");
2258 fprintf(stderr, "\n");
2259 fprintf(stderr, " -h hostname[:tcpport] -- connect to MIDAS mserver on given host and tcp port number\n");
2260 fprintf(stderr, " -e exptname -- connect to given MIDAS experiment\n");
2261 fprintf(stderr, "\n");
2262 fprintf(stderr, " -D -- Become a daemon\n");
2263 fprintf(stderr, " -O -- Become a daemon but keep stdout for saving in a log file: frontend -O >file.log 2>&1\n");
2264 fprintf(stderr, "\n");
2265 fprintf(stderr, " -i NNN -- Set frontend index number\n");
2266 fprintf(stderr, "\n");
2267
2268 // NOTE: cannot use range-based for() loop, it uses an iterator and will crash if HandleUsage() modifies fEquipments. K.O.
2269 for (unsigned i=0; i<fFeEquipments.size(); i++) {
2270 if (!fFeEquipments[i])
2271 continue;
2272 fprintf(stderr, "Usage of equipment \"%s\":\n", fFeEquipments[i]->fEqName.c_str());
2273 fprintf(stderr, "\n");
2274 fFeEquipments[i]->HandleUsage();
2275 fprintf(stderr, "\n");
2276 }
2277}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ HandleArguments()

virtual TMFeResult TMFrontend::HandleArguments ( const std::vector< std::string > &  args)
inlinevirtual

Reimplemented in FeTest, and FeEverything.

Definition at line 331 of file tmfe.h.

331{ return TMFeOk(); };
Here is the call graph for this function:
Here is the caller graph for this function:

◆ HandleFrontendExit()

virtual void TMFrontend::HandleFrontendExit ( )
inlinevirtual

Reimplemented in FeTest, FeEverything, and FeExample.

Definition at line 335 of file tmfe.h.

335{ };
Here is the caller graph for this function:

◆ HandleFrontendInit()

virtual TMFeResult TMFrontend::HandleFrontendInit ( const std::vector< std::string > &  args)
inlinevirtual

Reimplemented in FeTest, FeEverything, and FeExample.

Definition at line 333 of file tmfe.h.

333{ return TMFeOk(); };
Here is the call graph for this function:
Here is the caller graph for this function:

◆ HandleFrontendReady()

virtual TMFeResult TMFrontend::HandleFrontendReady ( const std::vector< std::string > &  args)
inlinevirtual

Reimplemented in FeTest, FeEverything, and FeExample.

Definition at line 334 of file tmfe.h.

334{ return TMFeOk(); };
Here is the call graph for this function:
Here is the caller graph for this function:

◆ HandleUsage()

virtual void TMFrontend::HandleUsage ( )
inlinevirtual

Reimplemented in FeTest, and FeEverything.

Definition at line 332 of file tmfe.h.

332{ };
Here is the caller graph for this function:

Member Data Documentation

◆ fFeEquipments

std::vector<TMFeEquipment*> TMFrontend::fFeEquipments

Definition at line 343 of file tmfe.h.

◆ fFeFlushWriteCacheNextCallTime

double TMFrontend::fFeFlushWriteCacheNextCallTime = 0

Definition at line 376 of file tmfe.h.

◆ fFeFlushWriteCachePeriodSec

double TMFrontend::fFeFlushWriteCachePeriodSec = 0.5

Definition at line 375 of file tmfe.h.

◆ fFeIfRunningCallBeginRun

bool TMFrontend::fFeIfRunningCallBeginRun = true

Definition at line 316 of file tmfe.h.

◆ fFeIfRunningCallExit

bool TMFrontend::fFeIfRunningCallExit = false

Definition at line 315 of file tmfe.h.

◆ fFeIndex

int TMFrontend::fFeIndex = 0

Definition at line 313 of file tmfe.h.

◆ fFeMutex

std::mutex TMFrontend::fFeMutex

Definition at line 319 of file tmfe.h.

◆ fFePeriodicThread

std::thread* TMFrontend::fFePeriodicThread = NULL

Definition at line 369 of file tmfe.h.

◆ fFePeriodicThreadRunning

std::atomic_bool TMFrontend::fFePeriodicThreadRunning {false}

Definition at line 371 of file tmfe.h.

371{false};

◆ fFePeriodicThreadShutdownRequested

std::atomic_bool TMFrontend::fFePeriodicThreadShutdownRequested {false}

Definition at line 372 of file tmfe.h.

372{false};

◆ fFePeriodicThreadStarting

std::atomic_bool TMFrontend::fFePeriodicThreadStarting {false}

Definition at line 370 of file tmfe.h.

370{false};

◆ fFeRpcHelper

TMFrontendRpcHelper* TMFrontend::fFeRpcHelper = NULL

Definition at line 310 of file tmfe.h.

◆ fMfe

TMFE* TMFrontend::fMfe = NULL

Definition at line 309 of file tmfe.h.


The documentation for this class was generated from the following files: