source: hvcontrol/hvcontrol.cpp@ 827

Last change on this file since 827 was 264, checked in by ogrimm, 14 years ago
Removed mutex locking in hvcontrol, use lockf() in Communicate()
File size: 4.5 KB
Line 
1
2/**************************************************************\
3
4 Main program for the CTX G-APD HV supply, sends commands,
5 reads and monitors status of the G-APD HV supply
6
7 Sebastian Commichau, Sabrina Stark, Oliver Grimm
8
9\**************************************************************/
10
11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14#include <pthread.h>
15#include <signal.h>
16
17#include "ProcessIO.h"
18
19#include <readline/readline.h>
20#include <readline/history.h>
21
22#define LOCKFILE "/tmp/CTX_HV_LOCK"
23
24// Function prototypes
25void HVMonitor(ProcessIO *);
26void DummyHandler(int);
27void CrashHandler(int);
28void ExitFunction();
29
30// ================
31// Main program
32// ================
33
34int main() {
35
36 char str[MAX_COM_SIZE], *Command;
37 pthread_t thread_HVMonitor;
38 int LockDescriptor;
39
40 // Assure only one instance of the HV control program runs
41 // The flag O_EXCL together with O_CREAT assure that the lock
42 // file cannot be opened by another instance, i.e. there are no parallel write accesses
43 if((LockDescriptor = open(LOCKFILE,O_WRONLY|O_CREAT|O_EXCL,S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH)) == -1) {
44 if(errno==EEXIST) {
45 printf("Error: Lock file already existing\n");
46 sprintf(str,"paste %s -s -d ' '",LOCKFILE);
47 system(str);
48 }
49 else printf("Could not create lock file %s (%s)\n", LOCKFILE, strerror(errno));
50 exit(EXIT_FAILURE);
51 }
52 close(LockDescriptor);
53 sprintf(str,"echo Created >%s; date >>%s; echo by $USER@$HOSTNAME>>%s",LOCKFILE,LOCKFILE,LOCKFILE);
54 system(str);
55
56 system("clear");
57 printf("\n*** Bias control (%s, %s, O. Grimm, S.Commichau, S.Stark) ***\n\n",__DATE__,__TIME__);
58
59 // Install signal handler and set signal SIGUSR1 to interrupt blocking system calls
60 signal(SIGUSR1, &DummyHandler);
61 siginterrupt (SIGUSR1, true);
62
63 // Assure lock file is deleted in case of a program crash or call to exit()
64 signal(SIGILL, &CrashHandler);
65 signal(SIGABRT, &CrashHandler);
66 signal(SIGFPE, &CrashHandler);
67 signal(SIGSEGV, &CrashHandler);
68 signal(SIGBUS, &CrashHandler);
69 atexit(&ExitFunction);
70
71 // Construct main instance
72 static ProcessIO M;
73
74 // These signals were set during construction of EvidenceServer
75 signal(SIGQUIT, &CrashHandler); // CTRL-Backspace
76 signal(SIGINT, &CrashHandler); // CTRL-C
77 signal(SIGHUP, &CrashHandler); // Terminal closed
78 signal(SIGTERM, &CrashHandler);
79
80 // Create monitor thread and make accessible for sending signal
81 if ((pthread_create(&thread_HVMonitor, NULL, (void * (*)(void *)) HVMonitor,(void *) &M)) != 0) {
82 M.Message(M.FATAL, "pthread_create failed with HVMonitor thread");
83 }
84 M.HVMonitor = thread_HVMonitor;
85
86 while (!M.ExitRequest) {
87 // Assemble prompt
88 if (M.NumHVBoards == 0) snprintf(M.Prompt, sizeof(M.Prompt), "\rBias> ");
89 else {
90 if (M.FirstBoard == M.LastBoard) snprintf(M.Prompt, sizeof(M.Prompt), "\rBias|B%d> ",M.FirstBoard);
91 else snprintf(M.Prompt, sizeof(M.Prompt),"\rBias|B%d-%d> ",M.FirstBoard, M.LastBoard);
92 }
93
94 // Read Command
95 Command = readline(M.Prompt);
96 if (Command == NULL) continue;
97 if(strlen(Command)>0) add_history(Command);
98
99 // Process command (via DIM gives automatic thread serialisation)
100 DimClient::sendCommand("Bias/Command", Command);
101 free(Command);
102 }
103
104 // Wait for thread to quit
105 if (pthread_join(thread_HVMonitor, NULL) != 0) {
106 M.PrintMessage("pthread_join() failed in main()");
107 }
108}
109
110
111/********************************************************************\
112
113 Monitor HV board status
114
115\********************************************************************/
116
117void HVMonitor(ProcessIO *m) {
118
119 while (!m->ExitRequest) {
120 if (m->state == active) m->Monitor();
121 usleep((unsigned long)floor(1000000./(m->NumHVBoards*m->fStatusRefreshRate)));
122 }
123}
124
125
126/********************************************************************\
127
128 Signal handlers
129
130\********************************************************************/
131
132// Remove lock file before running default signal code
133void CrashHandler(int Signal) {
134
135 remove(LOCKFILE);
136 printf("Caught signal number %d. Removing lockfile and performing standard signal action. Good luck.\n",Signal);
137 signal(Signal, SIG_DFL);
138 raise(Signal);
139}
140
141// Dummy signal handler to return from blocking syscalls
142void DummyHandler(int Signal) {
143 return;
144}
145
146// This function will be implicitly called by exit()
147void ExitFunction() {
148
149 if (remove(LOCKFILE) == -1) {
150 printf("Could not remove lock file %s (%s)\n", LOCKFILE, strerror(errno));
151 }
152}
Note: See TracBrowser for help on using the repository browser.