/**************************************************************\ Main program for the CTX G-APD HV supply, sends commands, reads and monitors status of the G-APD HV supply Sebastian Commichau, Sabrina Stark, Oliver Grimm \**************************************************************/ #include #include #include #include #include #include "ProcessIO.h" #include #include #define LOCKFILE "/tmp/CTX_HV_LOCK" // Function prototypes void HVMonitor(ProcessIO *); void DummyHandler(int); void CrashHandler(int); void ExitFunction(); // ================ // Main program // ================ int main() { char str[MAX_COM_SIZE], *Command; pthread_t thread_HVMonitor; int LockDescriptor; // Assure only one instance of the HV control program runs // The flag O_EXCL together with O_CREAT assure that the lock // file cannot be opened by another instance, i.e. there are no parallel write accesses if((LockDescriptor = open(LOCKFILE,O_WRONLY|O_CREAT|O_EXCL,S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH)) == -1) { if(errno==EEXIST) { printf("Error: Lock file already existing\n"); sprintf(str,"paste %s -s -d ' '",LOCKFILE); system(str); } else printf("Could not create lock file %s (%s)\n", LOCKFILE, strerror(errno)); exit(EXIT_FAILURE); } close(LockDescriptor); sprintf(str,"echo Created >%s; date >>%s; echo by $USER@$HOSTNAME>>%s",LOCKFILE,LOCKFILE,LOCKFILE); system(str); system("clear"); printf("\n*** Bias control (%s, %s, O. Grimm, S.Commichau, S.Stark) ***\n\n",__DATE__,__TIME__); // Install signal handler and set signal SIGUSR1 to interrupt blocking system calls signal(SIGUSR1, &DummyHandler); siginterrupt (SIGUSR1, true); // Assure lock file is deleted in case of a program crash or call to exit() signal(SIGILL, &CrashHandler); signal(SIGABRT, &CrashHandler); signal(SIGFPE, &CrashHandler); signal(SIGSEGV, &CrashHandler); signal(SIGBUS, &CrashHandler); atexit(&ExitFunction); // Construct main instance static ProcessIO M; // These signals were set during construction of EvidenceServer signal(SIGQUIT, &CrashHandler); // CTRL-Backspace signal(SIGINT, &CrashHandler); // CTRL-C signal(SIGHUP, &CrashHandler); // Terminal closed signal(SIGTERM, &CrashHandler); // Create monitor thread and make accessible for sending signal if ((pthread_create(&thread_HVMonitor, NULL, (void * (*)(void *)) HVMonitor,(void *) &M)) != 0) { M.Message(M.FATAL, "pthread_create failed with HVMonitor thread"); } M.HVMonitor = thread_HVMonitor; while (!M.ExitRequest) { // Assemble prompt if (M.NumHVBoards == 0) snprintf(M.Prompt, sizeof(M.Prompt), "\rBias> "); else { if (M.FirstBoard == M.LastBoard) snprintf(M.Prompt, sizeof(M.Prompt), "\rBias|B%d> ",M.FirstBoard); else snprintf(M.Prompt, sizeof(M.Prompt),"\rBias|B%d-%d> ",M.FirstBoard, M.LastBoard); } // Read Command Command = readline(M.Prompt); if (Command == NULL) continue; if(strlen(Command)>0) add_history(Command); // Process command (via DIM gives automatic thread serialisation) DimClient::sendCommand("Bias/Command", Command); free(Command); } // Wait for thread to quit if (pthread_join(thread_HVMonitor, NULL) != 0) { M.PrintMessage("pthread_join() failed in main()"); } } /********************************************************************\ Monitor HV board status \********************************************************************/ void HVMonitor(ProcessIO *m) { while (!m->ExitRequest) { if (m->state == active) m->Monitor(); usleep((unsigned long)floor(1000000./(m->NumHVBoards*m->fStatusRefreshRate))); } } /********************************************************************\ Signal handlers \********************************************************************/ // Remove lock file before running default signal code void CrashHandler(int Signal) { remove(LOCKFILE); printf("Caught signal number %d. Removing lockfile and performing standard signal action. Good luck.\n",Signal); signal(Signal, SIG_DFL); raise(Signal); } // Dummy signal handler to return from blocking syscalls void DummyHandler(int Signal) { return; } // This function will be implicitly called by exit() void ExitFunction() { if (remove(LOCKFILE) == -1) { printf("Could not remove lock file %s (%s)\n", LOCKFILE, strerror(errno)); } }