#include <iostream>
#include <stdlib.h>
#include <unistd.h>
#include "OnlineUtil/msgLogLib/msgLog.h"
#include "OnlineUtil/minosDaq.h"
#include <signal.h>
#include <string>
#include <map>
#include "TROOT.h"
#include "TRint.h"
#include "TVirtualX.h"
#include "TGuiFactory.h"
#include "TServerSocket.h"
#include "TSocket.h"
#include "TMessage.h"
#include "Rotorooter/RotoServer.h"
#include "Rotorooter/RotoObjectifier.h"
#include "Rotorooter/MsgLogTErrorHandler.h"
#include "RawData/RawBlockId.h"
#include "RawData/RawBlockRegistry.h"
#include "RawData/RawBlockProxy.h"
#include "RawData/RawDataBlock.h"
#include "RawData/RawRecord.h"
Go to the source code of this file.
Functions | |
static void | roto_sighandler (int dummy) |
int | config_autosave (const char *config) |
int | config_compress (const char *config) |
int | config_basketsize (const char *config) |
int | parse_port (const char *opt, string &inputFileName) |
int | main (int argc, char **argv) |
Variables | |
RotoServer * | server = 0 |
int config_autosave | ( | const char * | config | ) |
Definition at line 319 of file rotorooter.cc.
References len, logNotice(), and RotoServer::SetAutoSaveConfig().
Referenced by main().
00320 { 00321 int nerr = 0; 00322 int len = strlen(config); 00323 char *wcopy = (char*)malloc(len+1); /* a writable copy of config string */ 00324 char stream[1024]; 00325 const char *p1; 00326 char *p2; 00327 char achar; 00328 int nrec,nsec, nitems; 00329 00330 /* make a copy, replacing all the commas with blanks*/ 00331 p1 = config; p2 = wcopy; 00332 while (p2 < wcopy+len) { 00333 achar = *p1; 00334 if (achar != ',') *p2 = achar; 00335 else *p2 = ' '; 00336 p1++; p2++; 00337 } 00338 00339 p2 = wcopy; 00340 while (p2 < wcopy+len) { 00341 nitems = sscanf(p2,"%s %d %d",stream,&nrec,&nsec); 00342 if (nitems != 3) { 00343 logNotice("config_autosave: only %d items from \"%s\"\n",nitems,p2); 00344 nerr += 1; 00345 } 00346 else 00347 nerr += server->SetAutoSaveConfig(stream,nrec,nsec); 00348 00349 p2 = strchr(p2,';'); /* move to the semicolon */ 00350 if (!p2) break; /* in case of no final semicolon */ 00351 p2++; /* start just beyond semicolon */ 00352 } 00353 00354 00355 free(wcopy); /* return the allocated space */ 00356 wcopy = 0; 00357 00358 return nerr; 00359 }
int config_basketsize | ( | const char * | config | ) |
Definition at line 435 of file rotorooter.cc.
References len, logNotice(), and RotoServer::SetBasketSizeConfig().
Referenced by main().
00436 { 00437 int nerr = 0; 00438 int len = strlen(config); 00439 char *wcopy = (char*)malloc(len+1); /* a writable copy of config string */ 00440 char stream[1024]; 00441 const char *p1; 00442 char *p2; 00443 char achar; 00444 int basketsize, nitems; 00445 00446 /* make a copy, replacing all the commas with blanks*/ 00447 p1 = config; p2 = wcopy; 00448 while (p2 < wcopy+len) { 00449 achar = *p1; 00450 if (achar != ',') *p2 = achar; 00451 else *p2 = ' '; 00452 p1++; p2++; 00453 } 00454 00455 p2 = wcopy; 00456 while (p2 < wcopy+len) { 00457 nitems = sscanf(p2,"%s %d",stream,&basketsize); 00458 if (nitems != 2) { 00459 logNotice("config_basketsize: only %d items from \"%s\"\n",nitems,p2); 00460 nerr += 1; 00461 } 00462 else 00463 nerr += server->SetBasketSizeConfig(stream,basketsize); 00464 00465 p2 = strchr(p2,';'); /* move to the semicolon */ 00466 if (!p2) break; /* in case of no final semicolon */ 00467 p2++; /* start just beyond semicolon */ 00468 } 00469 00470 00471 free(wcopy); /* return the allocated space */ 00472 wcopy = 0; 00473 00474 return nerr; 00475 }
int config_compress | ( | const char * | config | ) |
Definition at line 377 of file rotorooter.cc.
References len, logNotice(), and RotoServer::SetCompressConfig().
Referenced by main().
00378 { 00379 int nerr = 0; 00380 int len = strlen(config); 00381 char *wcopy = (char*)malloc(len+1); /* a writable copy of config string */ 00382 char stream[1024]; 00383 const char *p1; 00384 char *p2; 00385 char achar; 00386 int level, nitems; 00387 00388 /* make a copy, replacing all the commas with blanks*/ 00389 p1 = config; p2 = wcopy; 00390 while (p2 < wcopy+len) { 00391 achar = *p1; 00392 if (achar != ',') *p2 = achar; 00393 else *p2 = ' '; 00394 p1++; p2++; 00395 } 00396 00397 p2 = wcopy; 00398 while (p2 < wcopy+len) { 00399 nitems = sscanf(p2,"%s %d",stream,&level); 00400 if (nitems != 2) { 00401 logNotice("config_compress: only %d items from \"%s\"\n",nitems,p2); 00402 nerr += 1; 00403 } 00404 else 00405 nerr += server->SetCompressConfig(stream,level); 00406 00407 p2 = strchr(p2,';'); /* move to the semicolon */ 00408 if (!p2) break; /* in case of no final semicolon */ 00409 p2++; /* start just beyond semicolon */ 00410 } 00411 00412 00413 free(wcopy); /* return the allocated space */ 00414 wcopy = 0; 00415 00416 return nerr; 00417 }
int main | ( | int | argc, | |
char ** | argv | |||
) |
Definition at line 69 of file rotorooter.cc.
References SimFlag::AsString(), Detector::AsString(), config_autosave(), config_basketsize(), config_compress(), exit(), Detector::kCalDet, SimFlag::kDaqFakeData, SimFlag::kData, Detector::kFar, SimFlag::kMC, Detector::kNear, SimFlag::kReroot, SimFlag::kUnknown, Detector::kUnknown, logDebugLevelSet(), logInfo(), logNotice(), MINOS_ROOTER, msgLogCleanup(), msgLogInit(), msgLogLocalEchoSet(), msgLogNodeIdSet(), MsgLogTErrorHandler(), n, parse_port(), port, ROOTER_PORT_DAQ, roto_sighandler(), RotoServer::Run(), RotoServer::SetFlatBinaryOutputFile(), RotoObjectifier::SetForceDetector(), RotoObjectifier::SetForceSimFlag(), and RotoServer::SetSymlink().
00070 { 00071 int copt; 00072 00073 Bool_t allow_overwrite = kFALSE; 00074 string inputFileName; 00075 Int_t port = ROOTER_PORT_DAQ; 00076 Int_t nwords = 2*1024*1024; 00077 Int_t tcp_nodelay_flag = 1; /* on by default */ 00078 const Char_t* autosave_config = 0; 00079 const Char_t* compress_config = 0; 00080 const Char_t* basketsize_config = 0; 00081 const Char_t* bin_output_file = 0; 00082 const Char_t* symlink_config = 0; 00083 00084 // install error handler for Info(),Warning(),Error(),SysError() 00085 // that redirects messages to msgLog 00086 //ErrorHandlerFunc_t old_errhndlr = 00087 SetErrorHandler(MsgLogTErrorHandler); 00088 00089 #ifdef ALLOW_FORCE 00090 Detector::Detector_t forceDetector = Detector::kUnknown; 00091 SimFlag::SimFlag_t forceSimFlag = SimFlag::kUnknown; 00092 const char* optlist = "aep:b:c:C:B:D:v:z:hd:sl:"; 00093 #else 00094 const char* optlist = "aep:b:c:C:B:D:v:z:hl:"; 00095 #endif 00096 00097 /* 00098 * parse the options and filenames 00099 * -a: allow overwrite 00100 * -p: port # (or "dcp"/"daq", "dcs", "beammon") 00101 * -b: initial buffer size 00102 * -c: autosave config "streamName,nrec,nsec[;streamName,nrec,nsec]" 00103 * -C: compression config "streamName,level[;streamName,level]" 00104 * -B: basketsize config "streamName,size[;streamName,size]" 00105 * both -c,-C,-B use "*" as streamName to set all legal streams 00106 * -D: tcp_nodelay flag 00107 * -e: msgLog local echo 00108 * -v: verbosity level 00109 * -d: force detector 00110 * -s: force simflag 00111 * -l: Make symlink to current file 00112 * -z: write a binary copy of received data to this file 00113 * -h: help 00114 */ 00115 00116 msgLogInit(argv[0]); 00117 msgLogNodeIdSet(MINOS_ROOTER); 00118 logInfo("rotorooter command line configuration\n"); 00119 00120 while ((copt = getopt(argc, argv, optlist)) != EOF) { 00121 switch (copt) { 00122 case 'a': 00123 allow_overwrite = kTRUE; 00124 break; 00125 case 'e': 00126 msgLogLocalEchoSet(1); 00127 break; 00128 case 'p': 00129 // Handle port number or file name 00130 port = parse_port(optarg, inputFileName); 00131 break; 00132 case 'b': 00133 nwords = atoi(optarg); 00134 break; 00135 case 'c': /* autosave config string */ 00136 autosave_config = optarg; 00137 break; 00138 case 'C': /* compression config string */ 00139 compress_config = optarg; 00140 break; 00141 case 'B': /* basketsize config string */ 00142 basketsize_config = optarg; 00143 break; 00144 case 'D': 00145 tcp_nodelay_flag = atoi(optarg); 00146 break; 00147 case 'v': 00148 logDebugLevelSet(atoi(optarg)); 00149 break; 00150 case 'z': 00151 bin_output_file = optarg; 00152 break; 00153 case 'h': 00154 printf(" usage: %s -a -p<port#> -b<buffersize> -e\n", argv[0]); 00155 printf(" -a: allow file overwriting\n"); 00156 printf(" -p: port number rotorooter is listening on\n"); 00157 printf(" or file name or \"dcs\"/\"daq\", \"dcs\", \"beammon\"\n"); 00158 printf(" -b: initial buffer size in long words\n"); 00159 printf(" -e: direct msgLog errors to stdout as well\n"); 00160 printf(" -v: msgLog debug level\n"); 00161 printf(" -c: autosave config \"streamName,nrec,nsec[;streamName,nrec,nsec]\"\n"); 00162 printf(" -C: compression config \"streamName,level[;streamName,level]\"\n"); 00163 printf(" -B: basketsize config \"streamName,size[;streamName,size]\"\n"); 00164 printf(" -D: TCP_NODELAY flag\n"); 00165 printf(" -z: make copy of flat data to binary file\n"); 00166 #ifdef ALLOW_FORCE 00167 printf(" -d: detector override\n"); 00168 printf(" -s: simflag override\n"); 00169 #endif 00170 printf(" -l: symlink to this file on each successful open\n"); 00171 printf(" -h: print this message\n"); 00172 exit(1); 00173 break; 00174 default: 00175 printf(" unrecognized option '%c'\n",(char)optopt); 00176 exit(1); 00177 break; 00178 #ifdef ALLOW_FORCE 00179 case 'd': 00180 { 00181 // be very strict! 00182 Detector::Detector_t dlist[] = { Detector::kNear, 00183 Detector::kFar, 00184 Detector::kCalDet }; 00185 int n = sizeof(dlist)/sizeof(forceDetector); 00186 string user = optarg; 00187 // look for a match 00188 for (int i = 0; i < n; i++) { 00189 if ( Detector::AsString(dlist[i]) == user) 00190 forceDetector = dlist[i]; 00191 } 00192 // complain if value didn't match 00193 if (Detector::kUnknown == forceDetector) { 00194 printf(" -d flag (force detector type) unknown value: %s\n", 00195 user.c_str()); 00196 printf(" must be followed by exactly one of: %s", 00197 Detector::AsString(dlist[0])); 00198 for (int i = 1; i < n; i++ ) printf(", %s", 00199 Detector::AsString(dlist[i])); 00200 printf("\n"); 00201 forceDetector = Detector::kUnknown; 00202 exit(1); 00203 } 00204 } 00205 break; 00206 case 's': 00207 { 00208 // be very strict! 00209 SimFlag::SimFlag_t slist[] = { SimFlag::kData, 00210 SimFlag::kDaqFakeData, 00211 SimFlag::kMC, 00212 SimFlag::kReroot }; 00213 int n = sizeof(slist)/sizeof(forceSimFlag); 00214 string user = optarg; 00215 // look for a match 00216 for (int i = 0; i < n; i++) { 00217 if ( SimFlag::AsString(slist[i]) == user) 00218 forceSimFlag = slist[i]; 00219 } 00220 // complain if value didn't match 00221 if (SimFlag::kUnknown == forceSimFlag) { 00222 printf(" -s flag (force simflag) unknown value: %s\n", 00223 user.c_str()); 00224 printf(" must be followed by exactly one of: %s", 00225 SimFlag::AsString(slist[0])); 00226 for (int i = 1; i < n; i++ ) printf(", %s", 00227 SimFlag::AsString(slist[i])); 00228 printf("\n"); 00229 forceSimFlag = SimFlag::kUnknown; 00230 exit(1); 00231 } 00232 } 00233 break; 00234 #endif 00235 case 'l': 00236 symlink_config = optarg; 00237 break; 00238 } 00239 } 00240 00241 logNotice("starting %s port %d, inputFileName '%s'", 00242 argv[0],port,inputFileName.c_str()); 00243 00244 // use global so handler can do a clean shutdown 00245 if ( port ) 00246 server = new RotoServer(port,nwords,allow_overwrite,tcp_nodelay_flag); 00247 else 00248 server = new RotoServer(inputFileName.c_str(),nwords,allow_overwrite); 00249 00250 /* Trap HUP, INT and TERM signals so that we close down gracefully */ 00251 struct sigaction termAction ; 00252 termAction.sa_handler = roto_sighandler ; 00253 sigemptyset (&termAction.sa_mask) ; 00254 termAction.sa_flags = 0 ; 00255 sigaction (SIGHUP, &termAction, NULL) ; 00256 sigaction (SIGINT, &termAction, NULL) ; 00257 sigaction (SIGTERM, &termAction, NULL) ; 00258 00259 #ifdef ALLOW_FORCE 00260 if (Detector::kUnknown != forceDetector) { 00261 // DANGER! DANGER! DANGER! 00262 logNotice("DANGER! overriding detector in all block IDs: %s", 00263 Detector::AsString(forceDetector)); 00264 RotoObjectifier::SetForceDetector(forceDetector); 00265 } 00266 if (SimFlag::kUnknown != forceSimFlag) { 00267 // DANGER! DANGER! DANGER! 00268 logNotice("DANGER! overriding simflag in all block IDs: %s", 00269 SimFlag::AsString(forceSimFlag)); 00270 RotoObjectifier::SetForceSimFlag(forceSimFlag); 00271 } 00272 #endif 00273 00274 // run ROOT in batch mode (ie. no X11) 00275 // based on what root does when passed -b flag 00276 gROOT->SetBatch(); 00277 if (gGuiFactory != gBatchGuiFactory) delete gGuiFactory; 00278 gGuiFactory = gBatchGuiFactory; 00279 #ifndef WIN32 00280 if (gVirtualX != gGXBatch) delete gVirtualX; 00281 #endif 00282 gVirtualX = gGXBatch; 00283 00284 // configure initial autosave and compression values 00285 Int_t nerr = 0; 00286 if (autosave_config) nerr += config_autosave(autosave_config); 00287 if (compress_config) nerr += config_compress(compress_config); 00288 if (basketsize_config) nerr += config_basketsize(basketsize_config); 00289 00290 if (bin_output_file) nerr += server->SetFlatBinaryOutputFile(bin_output_file); 00291 00292 if (symlink_config) server->SetSymlink(symlink_config); 00293 00294 server->Run(); 00295 delete server; 00296 00297 logNotice("stopping %s",argv[0]); 00298 msgLogCleanup(); 00299 00300 return 0; 00301 }
int parse_port | ( | const char * | opt, | |
string & | inputFileName | |||
) |
Definition at line 495 of file rotorooter.cc.
References port, ROOTER_PORT_BEAMMON, ROOTER_PORT_DAQ, and ROOTER_PORT_DCS.
Referenced by main().
00496 { 00497 int port = ROOTER_PORT_DAQ; 00498 00499 enum ptype { kNumeric, kSpecial, kIsFile }; 00500 ptype pType = kNumeric; // start by assuming numeric value 00501 // bool input_from_file = kFALSE; 00502 00503 // look for non-digit characters 00504 const char* c = optarg; 00505 while ( *c != '\0' ) { 00506 if ( ! isdigit(*c) ) { 00507 //input_from_file = kTRUE; 00508 pType = kIsFile; 00509 inputFileName = optarg; 00510 break; 00511 } 00512 c++; 00513 } 00514 00515 // if (provisionally) from a file (ie. not all digits) 00516 // look for special cases 00517 //if ( input_from_file ) { 00518 if ( pType != kNumeric ) { 00519 00520 std::map<string,int> specialNames; 00521 specialNames["dcp"] = ROOTER_PORT_DAQ; 00522 specialNames["DCP"] = ROOTER_PORT_DAQ; 00523 specialNames["daq"] = ROOTER_PORT_DAQ; 00524 specialNames["DAQ"] = ROOTER_PORT_DAQ; 00525 specialNames["dcs"] = ROOTER_PORT_DCS; 00526 specialNames["DCS"] = ROOTER_PORT_DCS; 00527 specialNames["beammon"] = ROOTER_PORT_BEAMMON; 00528 specialNames["BEAMMON"] = ROOTER_PORT_BEAMMON; 00529 specialNames["BeamMon"] = ROOTER_PORT_BEAMMON; 00530 00531 int specialPort = specialNames[inputFileName]; 00532 if (specialPort) { 00533 port = specialPort; 00534 //input_from_file = kFALSE; 00535 pType = kSpecial; 00536 } 00537 } 00538 00539 if ( pType == kNumeric) port = atoi(optarg); 00540 else if ( pType == kIsFile ) port = 0; 00541 00542 return port; 00543 }
static void roto_sighandler | ( | int | dummy | ) | [static] |
Definition at line 42 of file rotorooter.cc.
References exit(), logNotice(), and msgLogCleanup().
Referenced by main().
00043 { 00044 if (server) { 00045 logNotice("roto_sighandler signal %d; attempt shutdown",dummy); 00046 00047 // make sure the clean up code is called 00048 delete server; 00049 logNotice("roto_sighandler exit"); 00050 00051 } else { 00052 logNotice("roto_sighandler signal %d, but no server",dummy); 00053 00054 } 00055 00056 msgLogCleanup(); 00057 00058 exit(1); 00059 }
RotoServer* server = 0 |
Definition at line 39 of file rotorooter.cc.