- Timestamp:
- 07/21/10 15:07:37 (14 years ago)
- Location:
- Evidence
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
Evidence/Alarm.cc
r253 r255 124 124 // Identify status service 125 125 for (int i=0; i<List.size(); i++) if (getInfo() == List[i].Subscription) { 126 // Update level: unavailable or current severity of status 126 // Update level: unavailable or current severity of status (safely extracted) 127 127 if (!ServiceOK(getInfo())) List[i].Level = 4; 128 else if (getInfo()->getInt() > List[i].Level) List[i].Level = getInfo()->getInt(); 128 else { 129 int Severity = atoi(ToString(getInfo()->getFormat(), getInfo()->getData(), getInfo()->getSize()).c_str()); 130 if (Severity > List[i].Level) List[i].Level = Severity; 131 } 129 132 } 130 133 … … 140 143 if (getCommand() != Command || Server.empty()) return; 141 144 142 // Reset alarm level and publish/log action145 // Reset alarm level, publish/log action and reset server message severity 143 146 for (int i=0; i<List.size(); i++) if (List[i].Server == Server) { 144 147 Message(INFO, "Alarm level of server %s reset by %s (ID %d)", Server.c_str(), getClientName(), getClientId()); 145 148 List[i].Level = 0; 146 149 List[i].WarnedLevel = 0; 150 if (Server != "DIS_DNS") sendCommandNB((Server+"/EXIT").c_str(), (int) 0); 147 151 } 148 152 … … 155 159 156 160 ostringstream Buf; 157 int Alarm , Ret;161 int Alarm = 0, Ret; 158 162 159 163 Lock(); … … 223 227 } 224 228 if (!Exist) Alarm.List[i].Level = 4; 225 else if (Alarm.List[i].Level = -1) Alarm.List[i].Level = 0;229 else if (Alarm.List[i].Level == -1) Alarm.List[i].Level = 0; 226 230 } 227 231 -
Evidence/Doc/Evidence.tex
-
Property svn:keywords
set to
Rev
r253 r255 39 39 \maketitle 40 40 41 This report describes the design and basic functionality of the \E control system. This essentially is a C++ class and a set of programs running on Linux for controlling small scale experiments. It is based on CERN's DIM library for interprocess communication over TCP/IP connections. 41 This report describes the design and basic functionality of the \E control system. This essentially is a C++ class and a set of programs running on Linux for controlling small scale experiments. It is based on CERN's DIM library for interprocess communication over TCP/IP connections. \lstinline{$Rev$} 42 42 43 43 \tableofcontents … … 130 130 \item Provides a method for configuration requests. If the configuration data is not available, the application terminates with a message of FATAL severity unless default data is given. 131 131 \item Provides a method for safely translating DIM service data into text. 132 \item Implements the virtual DIM methods \lstinline{exitHandler()} and \lstinline{errorHandler()}. The exit handler can be called through a standard DIM command and will, upon first invocation, just set the flag \lstinline{ExitRequest} which then should be handled by the application. Upon second invocation, it will call \lstinline{exit()}. The error handler will issue a message with ERROR severity.The user application can override these handlers. 132 \item Implements the virtual DIM methods \lstinline{exitHandler()}. It can be called through a standard DIM command \lstinline{SvrName/EXIT}, taking a single integer as argument. Upon first invocation, the handler just sets the flag \lstinline{ExitRequest} which should be handled by the application. Upon second invocation, it will call \lstinline{exit()}. A special functionality is given to the argument value 0: it instructs the server to reset its message severity to INFO, without exiting. This is used by the \lstinline{Alarm} server if it receives a command to reset an alarm level, but is also available to the user. The user application can override this handler. 133 \item Implements the virtual DIM methods \lstinline{errorHandler()}. The error handler will issue a message with ERROR severity that contains the DIM error code. The user application can override this handler. 133 134 \item Installs signal handler for SIGQUIT (ctrl-backspace), SIGTERM, SIGINT (ctrl-c), and SIGHUP (terminal closed). The signal handler sets first \lstinline{ExitRequest}, and on second invocation calls \lstinline{exit()}. After instantiating the class, the programmer may override the handlers. 134 135 \item Catches un-handled C++ exceptions and extracts as much information from the exception as possible.\footnote{This termination handler is taken directly from the code of the \lstinline{g++} compiler and is thus compiler specific.} That information is also published as a message. … … 140 141 \label{EvidenceServer-Methods} 141 142 142 The \lstinline{public} part of the header file \lstinline{Evidence.h} is as follows. The namespace designation \lstinline{std} has been left out for clarity in this listing. 143 The \lstinline{public} part of the header file \lstinline{Evidence.h} is as follows. The namespace designation \lstinline{std} has been left out for clarity in this listing. 143 144 144 145 \begin{lstlisting}[numbers=left,numberstyle=\tiny,stepnumber=2,numbersep=5pt] … … 180 181 \underline{\lstinline{ActivateSignal()}} is used to define a signal that should be emitted to the main thread in case the configuration file changes. See Sect.\,\ref{ConfigHandling} for details. No signal will be emitted if not set by this routine. 181 182 182 The methods \underline{\lstinline{Lock()}} and \underline{\lstinline{Unlock()}} work on an internal mutex.\footnote{Its type is \lstinline{PTHREAD_MUTEX_ERRORCHECK}. In case an already locked mutex is re-locked, the corresponding system call will therefore return a error and thus avoid dead-locking. } They are used by \lstinline{GetConfig()} but are also available for the user application to serialize access from multiple threads. If a signal is set by \lstinline{ActivateSignal()}, it is masked before locking and unmasked after unlocking.183 The methods \underline{\lstinline{Lock()}} and \underline{\lstinline{Unlock()}} work on an internal mutex.\footnote{Its type is \lstinline{PTHREAD_MUTEX_ERRORCHECK}. In case an already locked mutex is re-locked, the corresponding system call will therefore return a error and thus avoid dead-locking. Error messages from \lstinline{Lock()} and \lstinline{Unlock()} are written to the console and to the log file. They are not published using \lstinline{Message()} since this method itself uses locking and calling it would result in an infinite recursion.} They are used by \lstinline{GetConfig()} but are also available for the user application to serialize access from multiple threads. If a signal is set by \lstinline{ActivateSignal()}, it is masked before locking and unmasked after unlocking. Calling functions in the locked state should be avoided as it might result in re-locking. 183 184 184 185 The static method \underline{\lstinline{ToString()}} translates the contents of a DIM service safely into a string that is returned. As no consistency between a service format and the contained data is guaranteed by DIM, precautions are necessary to avoid buffer overruns. The method currently handles the standardized message format \lstinline{"I:1;C"}, arrays of numbers and strings. All other formats are translated into a hex representation. The arguments are the DIM service format, a pointer to the service data and the data size in bytes. It is thread safe as it uses only the arguments and dynamically allocated storage. -
Property svn:keywords
set to
-
Evidence/Evidence.cc
r253 r255 122 122 // Return current value 123 123 Result = List[Item].Value; 124 This->Unlock();125 124 } 125 This->Unlock(); 126 126 } 127 127 … … 200 200 void EvidenceServer::exitHandler(int Code) { 201 201 202 Message(INFO, "Exit handler called (DIM exit code %d)", Code); 203 exit(EXIT_SUCCESS); 202 if (Code == 0) Message(INFO, "Message cleared by %s (ID %d)", getClientName(), getClientId()); 203 else { 204 Message(INFO, "Exit handler called (DIM exit code %d)", Code); 205 exit(EXIT_SUCCESS); 206 } 204 207 } 205 208 … … 241 244 } 242 245 243 // Terminate if severity if FATAL244 if (Severity == FATAL) exit(EXIT_FAILURE);245 246 246 // Delete old message 247 // Note that Lock()/Unlock() might fail with a FATAL message. To avoid an infinite loop,248 // check for FATAL severity is done before here.249 247 Lock(); 250 248 delete[] MessageData; 251 249 MessageData = NewMsg; 252 250 Unlock(); 253 } 254 255 256 // Set to central logging server with non-blocking command (may be used in DIM handler) 251 252 // Terminate if severity if FATAL 253 if (Severity == FATAL) exit(EXIT_FAILURE); 254 } 255 256 257 // Send to central logging server with non-blocking command 257 258 void EvidenceServer::SendToLog(const char *Format, ...) { 258 259 260 static char ErrorString[] = "vasprintf() failed in SendToLog()"; 259 261 char *Buffer; 260 262 int Ret; … … 271 273 free (Buffer); 272 274 } 273 else Message(ERROR, "Could not create logging text in SendToLog(), vasprintf() failed");275 else DimClient::sendCommandNB("DColl/Log", ErrorString); 274 276 } 275 277 … … 300 302 301 303 302 // Locking and unlocking for list access 303 // Signal blocked before locking to avoid dead-lock by calling GetConfig() from ConfigChanged(). 304 // Locking and unlocking functions. 305 // Signal blocked before locking (pthread_mutex_lock() not asynch-signal safe). 306 // Message() is not used to avoid infinite recursion 304 307 void EvidenceServer::Lock() { 305 308 … … 312 315 Ret += abs(pthread_sigmask(SIG_BLOCK, &Set, NULL)); 313 316 314 if (Ret != 0) Message(FATAL, "Signal masking failed in Lock()"); 317 if (Ret != 0) { 318 printf("Signal masking failed in Lock()"); 319 SendToLog("Signal masking failed in Lock()"); 320 exit(EXIT_FAILURE); 321 } 315 322 } 316 323 317 324 if ((Ret = pthread_mutex_lock(&Mutex)) != 0) { 318 Message(FATAL, "pthread_mutex_lock() failed in Lock() (%s)", strerror(Ret)); 325 printf("pthread_mutex_lock() failed in Lock() (%s)", strerror(Ret)); 326 SendToLog("pthread_mutex_lock() failed in Lock() (%s)", strerror(Ret)); 327 exit(EXIT_FAILURE); 319 328 } 320 329 } … … 326 335 327 336 if ((Ret = pthread_mutex_unlock(&Mutex)) != 0) { 328 Message(FATAL, "pthread_mutex_unlock() failed in Unlock() (%s)", strerror(Ret)); 337 printf("pthread_mutex_unlock() failed in Unlock() (%s)", strerror(Ret)); 338 SendToLog("pthread_mutex_unlock() failed in Unlock() (%s)", strerror(Ret)); 339 exit(EXIT_FAILURE); 329 340 } 330 341 … … 334 345 Ret += abs(pthread_sigmask(SIG_UNBLOCK, &Set, NULL)); 335 346 336 if (Ret != 0) Message(FATAL, "Signal unmasking failed in Unlock()"); 347 if (Ret != 0) { 348 printf("Signal unmasking failed in Unlock()"); 349 SendToLog("Signal unmasking failed in Unlock()"); 350 exit(EXIT_FAILURE); 351 } 337 352 } 338 353 } -
Evidence/readme.txt
r253 r255 1 Short description of Evidence control system2 1 3 2 This directory contains the backbone of the control system. See directory Doc for documentation. … … 44 43 second-last message will not be freed correctly if severity is FATAL). Added 45 44 History server configuration parameters to adjust buffer size. 46 45 20/7/2010 SendToLog() does not call Message() in case of error, but writes error message to log. 46 21/7/2010 Lock()/Unlock() do not report errors via Message(), but print to console and use 47 SendToLog(). That avoids a recursion problem since Message() also uses locking. 48 The general exitHandler() will react in a special way to code 0: it will reset 49 the message severity. This feature is used by Alarm if it receives a command to 50 reset an alarm level.
Note:
See TracChangeset
for help on using the changeset viewer.