#include <service.h>
service_howto
Temporary command line arguments :
Olivier Cado
Nevrax France
Definition at line 177 of file service.h.
get methods. These methods provide a way to read internal service variables. | |
std::string | getArg (char argName) |
const std::vector< std::string > & | getArgs () const |
Returns arguments of the program pass from the user to the program using parameters (ie: "myprog param1 param2"). | |
CCallbackNetBase::TRecordingState | getRecordingState () const |
Returns the recording state (don't needed if you use layer5). | |
const std::string & | getServiceAliasName () const |
Returns the current service alias name setted by AES. | |
TServiceId | getServiceId () const |
Returns the service identifier. | |
const std::string & | getServiceLongName () const |
Returns the current service long name (ie: test_serivce). | |
const std::string & | getServiceShortName () const |
Returns the current service short name (ie: TS). | |
std::string | getServiceUnifiedName () const |
Returns the current service unified name that is alias/short-id or short-id if alias is empty. | |
sint | getStatus () const |
Returns the status. | |
bool | haveArg (char argName) |
Returns true if the argument if present in the command line (ie: haveArg('p') will return true if -p is in the command line). | |
IService * | getInstance () |
Returns the instance of the service to access to methods/variables class. | |
variables. These variables are used by the internal system. | |
std::string | _AliasName |
std::vector< std::string > | _Args |
Array of arguments pass from the command line. | |
TUnifiedCallbackItem * | _CallbackArray |
uint | _CallbackArraySize |
bool | _DontUseAES |
true if the service don't use the admin executor service | |
bool | _DontUseNS |
true if the service don't use the naming service | |
bool | _Initialized |
true if the service initialisation is passed | |
std::string | _LongName |
CCallbackNetBase::TRecordingState | _RecordingState |
Recording state. | |
bool | _ResetMeasures |
Require to reset the hierarchical timer. | |
uint32 | _ShardId |
Shard Id. | |
std::string | _ShortName |
Current service name sets by the actual service when declaring NLNET_SERVICE_MAIN. | |
TServiceId | _SId |
the service id of this sevice | |
sint | _Status |
the status of this service (the status is give to the at the release time) | |
NLMISC::TTime | _UpdateTimeout |
Select timeout value in milliseconds between to call of user update(). | |
NLMISC::CVariable< std::string > | ConfigDirectory |
The directory where the configfile is. | |
NLMISC::CVariable< uint16 > | ListeningPort |
Listening port of this service. | |
NLMISC::CVariable< std::string > | LogDirectory |
The directory where the logfiles are. | |
NLMISC::CVariable< std::string > | RunningDirectory |
The directory where the service is running. | |
NLMISC::CVariable< std::string > | Version |
IService * | _Instance = NULL |
Instance of this service (singleton). | |
Public Member Functions | |
uint16 | getPort () |
uint32 | getShardId () const |
void | setVersion (const std::string &version) |
set methods. These methods provide a way to modify internal service variables. | |
void | exit (sint code=0x10) |
void | setStatus (sint status) |
void | setUpdateTimeout (NLMISC::TTime timeout) |
User overload methods. These methods can be overload by the user do handle init, update and release operation. | |
virtual void | init () |
Initializes the service (must be called before the first call to update()). | |
virtual void | release () |
Finalization. Release the service. For example, this founction free all allocation made in the init() function. | |
virtual bool | update () |
This function is called every "frame" (you must call init() before). It returns false if the service is stopped. | |
private methods. These methods are used by internal system but can't be put in private, don't use them. | |
IService () | |
Ctor. You must not inherit ctor but overload init() function. | |
sint | main (const char *serviceShortName, const char *serviceLongName, uint16 servicePort, const char *configDir, const char *logDir, const char *compilationDate) |
This main is called by the macro (service5 says if we have to use layer5 or not). | |
void | requireResetMeasures () |
Require to reset the hierarchical timer. | |
void | setArgs (const char *args) |
Sets the command line and init _Args variable. You must call this before calling main(). | |
void | setArgs (int argc, const char **argv) |
Sets the command line and init _Args variable. You must call this before calling main(). | |
void | setCallbackArray (TUnifiedCallbackItem *array, uint nbelem) |
Sets the default callback array given from the macro. | |
virtual | ~IService () |
Dtor. You must not inherit dtor but overload release() function. | |
Data Fields | |
NLMISC::CVariable< std::string > | SaveFilesDirectory |
NLMISC::CWindowDisplayer * | WindowDisplayer |
The window displayer instance. | |
NLMISC::CVariable< std::string > | WriteFilesDirectory |
variables. These variables can be read/modified by the user. | |
NLMISC::CLog | CommandLog |
NLMISC::CConfigFile | ConfigFile |
Private Member Functions | |
methods. These methods are used by internal system. | |
void | setRecordingState (CCallbackNetBase::TRecordingState rec) |
Changes the recording state (use if you know what you are doing). | |
Friends | |
void | cbAESConnection (const std::string &serviceName, uint16 sid, void *arg) |
void | cbDirectoryChanged (const NLMISC::IVariable &var) |
void | cbReceiveShardId (NLNET::CMessage &msgin, const std::string &serviceName, uint16 serviceId) |
struct | getWinDisplayerInfoClass |
void | serviceGetView (uint32 rid, const std::string &rawvarpath, std::vector< std::string > &vara, std::vector< std::string > &vala) |
struct | serviceInfoClass |
|
Ctor. You must not inherit ctor but overload init() function.
Definition at line 278 of file service.cpp. References NLNET::cbDirectoryChanged().
00278 : 00279 WindowDisplayer(0), 00280 WriteFilesDirectory("WriteFilesDirectory", "directory where to save generic shard information (packed_sheets for example)", ".", 0, true, cbDirectoryChanged), 00281 SaveFilesDirectory("SaveFilesDirectory", "directory where to save specific shard information (shard time for example)", ".", 0, true, cbDirectoryChanged), 00282 ListeningPort("ListeningPort", "listening port for this service", 0, 0, true), 00283 _RecordingState(CCallbackNetBase::Off), 00284 _UpdateTimeout(100), 00285 _SId(0), 00286 _Status(0), 00287 _Initialized(false), 00288 ConfigDirectory("ConfigDirectory", "directory where config files are", ".", 0, true, cbDirectoryChanged), 00289 LogDirectory("LogDirectory", "directory where the service is logging", ".", 0, true, cbDirectoryChanged), 00290 RunningDirectory("RunningDirectory", "directory where the service is running on", ".", 0, true, cbDirectoryChanged), 00291 Version("Version", "Version of the shard", ""), 00292 _CallbackArray (0), 00293 _CallbackArraySize (0), 00294 _DontUseNS(false), 00295 _DontUseAES(false), 00296 _ResetMeasures(false) 00297 { 00298 // Singleton 00299 _Instance = this; 00300 } |
|
Dtor. You must not inherit dtor but overload release() function.
Definition at line 300 of file service.h.
00300 {} |
|
Call this function if you want the service quits next loop. The code will be returned outside of the application.
Definition at line 1333 of file service.cpp. References NLNET::ExitSignalAsked, nlinfo, and sint.
01334 { 01335 nlinfo ("SERVICE: Somebody called IService::exit(), I have to quit"); 01336 ExitSignalAsked = code; 01337 } |
|
Returns the parameter linked to an option (ie: getArg('p') will return "toto" if -ptoto is in the command line) It'll thrown an Exception if the argName is not found Definition at line 319 of file service.cpp. References uint32. Referenced by main().
00320 { 00321 for (uint32 i = 0; i < _Args.size(); i++) 00322 { 00323 if (_Args[i].size() >= 2 && _Args[i][0] == '-') 00324 { 00325 if (_Args[i][1] == argName) 00326 { 00327 return _Args[i].substr(2); 00328 } 00329 } 00330 } 00331 throw Exception ("Parameter '-%c' is not found in command line", argName); 00332 } |
|
Returns arguments of the program pass from the user to the program using parameters (ie: "myprog param1 param2").
Definition at line 221 of file service.h.
00221 { return _Args; } |
|
Returns the instance of the service to access to methods/variables class.
Definition at line 200 of file service.h. References nlassert. Referenced by NLAILINK::getLocalServerID().
|
|
Definition at line 317 of file service.h. References ListeningPort, and uint16.
00317 { return ListeningPort; } |
|
Returns the recording state (don't needed if you use layer5).
Definition at line 238 of file service.h.
00238 { return _RecordingState; } |
|
Returns the current service alias name setted by AES.
Definition at line 209 of file service.h. References _AliasName.
00209 { return _AliasName; }; |
|
Returns the service identifier.
Definition at line 215 of file service.h. References _SId, and NLNET::TServiceId.
00215 { return _SId; } |
|
Returns the current service long name (ie: test_serivce).
Definition at line 206 of file service.h. References _LongName. Referenced by main().
00206 { return _LongName; }; |
|
Returns the current service short name (ie: TS).
Definition at line 203 of file service.h. References _ShortName.
00203 { return _ShortName; }; |
|
Returns the current service unified name that is alias/short-id or short-id if alias is empty.
Definition at line 1348 of file service.cpp. References _AliasName, _ShortName, _SId, nlassert, res, and NLMISC::toString().
01349 { 01350 nlassert (!_ShortName.empty()); 01351 string res; 01352 if (!_AliasName.empty()) 01353 { 01354 res = _AliasName+"/"; 01355 } 01356 res += _ShortName; 01357 if (_SId != 0) 01358 { 01359 res += "-"; 01360 res += toString (_SId); 01361 } 01362 return res; 01363 } |
|
Definition at line 319 of file service.h. References _ShardId, and uint32.
00319 { return _ShardId; } |
|
Returns the status.
Definition at line 218 of file service.h. Referenced by main().
00218 { return _Status; } |
|
Returns true if the argument if present in the command line (ie: haveArg('p') will return true if -p is in the command line).
Definition at line 304 of file service.cpp. References uint32. Referenced by main().
|
|
Initializes the service (must be called before the first call to update()).
Definition at line 185 of file service.h. Referenced by main().
00185 {} |
|
This main is called by the macro (service5 says if we have to use layer5 or not).
Layer5 Startup Definition at line 419 of file service.cpp. References _AliasName, _CallbackArraySize, _DontUseAES, _DontUseNS, _LongName, _ResetMeasures, _ShardId, _ShortName, _SId, _UpdateTimeout, CTimeoutAssertionThread::activate(), NLNET::CUnifiedNetwork::addCallbackArray(), NLMISC::CLog::addDisplayer(), NLMISC::CConfigFile::CVar::asInt(), NLMISC::AssertLog, NLNET::CInetAddress::asString(), NLMISC::CConfigFile::CVar::asString(), NLMISC::beep(), NLNET::Bench(), NLNET::builtinServiceCallbacks, NLNET::cbExecuteCommands(), NLNET::cbLogFilter(), NLMISC::changeLogDirectory(), NLMISC::CMemDisplayer::clear(), CommandLog, NLNET::CompilationDate, ConfigDirectory, ConfigFile, NLMISC::CWindowDisplayer::create(), NLMISC::CWindowDisplayer::createLabel(), NLMISC::DebugLog, CTimeoutAssertionThread::desactivate(), NLMISC::CLog::displayNL(), NLMISC::ErrorLog, NLMISC::CConfigFile::exists(), NLNET::ExitSignalAsked, getArg(), NLNET::CUnifiedNetwork::getInstance(), getServiceLongName(), getStatus(), NLMISC::CConfigFile::getVar(), NLMISC::CConfigFile::getVarPtr(), H_AUTO, haveArg(), NLMISC::InfoLog, init(), NLMISC::IVariable::init(), NLNET::initAdmin(), NLNET::initSignal(), IsDebuggerPresent, NLNET::LaunchingDate, ListeningPort, NLMISC::CConfigFile::load(), NLMISC::CMemDisplayer::lockStrings(), LogDirectory, NLNET::MyTAT, NLNET::NbUserUpdate, NLNET::NegFiltersNames, NLNET::NetSpeedLoop(), nlassert, nldebug, nlerror, nlinfo, NLMISC::nlSleep(), nlwarning, release(), NLMISC::CLog::removeDisplayer(), RunningDirectory, SaveFilesDirectory, NLNET::sendEmail(), NLMISC::setAssert(), NLMISC::CConfigFile::setCallback(), NLNET::setDefaultEmailParams(), NLMISC::CWindowDisplayer::setLabel(), NLMISC::CLog::setProcessName(), NLMISC::setReportEmailFunction(), NLMISC::CEntityId::setServiceId(), setStatus(), NLMISC::CWindowDisplayer::setTitleBar(), sint, sint32, size, NLMISC::CConfigFile::CVar::size(), NLMISC::strupr(), NLMISC::toString(), NLMISC::TTime, uint, uint16, uint32, uint64, uint8, NLMISC::CMemDisplayer::unlockStrings(), NLMISC::CWindowDisplayer::update(), update(), NLNET::updateAdmin(), NLNET::UserSpeedLoop(), v, w, NLMISC::WarningLog, WindowDisplayer, x, and y.
00420 { 00421 bool userInitCalled = false; 00422 // bool resyncEvenly = false; 00423 CConfigFile::CVar *var = NULL; 00424 00425 // a short name service can't be a number 00426 nlassert (atoi(serviceShortName) == 0); 00427 00428 try 00429 { 00430 // 00431 // Init parameters 00432 // 00433 00434 _ShortName = serviceShortName; 00435 CLog::setProcessName (_ShortName); 00436 00437 // get the path where to run the service if any in the command line 00438 if (haveArg('A')) 00439 RunningDirectory = CPath::standardizePath(getArg('A')); 00440 00441 ConfigDirectory = CPath::standardizePath(configDir); 00442 LogDirectory = CPath::standardizePath(logDir); 00443 _LongName = serviceLongName; 00444 00445 CompilationDate = compilationDate; 00446 00447 LaunchingDate = CTime::getSecondsSince1970(); 00448 00449 ListeningPort = servicePort; 00450 00451 setReportEmailFunction ((void*)sendEmail); 00452 setDefaultEmailParams ("gw.nevrax.com", "", "lecroart@nevrax.com"); 00453 00454 00455 // 00456 // Load the config file 00457 // 00458 00459 // get the config file dir if any in the command line 00460 if (haveArg('C')) 00461 ConfigDirectory = CPath::standardizePath(getArg('C')); 00462 00463 string cfn = ConfigDirectory.c_str() + _LongName + ".cfg"; 00464 if (!CFile::fileExists(ConfigDirectory.c_str() + _LongName + ".cfg")) 00465 { 00466 // check if the default exists 00467 if (!CFile::fileExists(ConfigDirectory.c_str() + _LongName + "_default.cfg")) 00468 { 00469 nlerror ("SERVICE: The config file '%s' is not found, neither the default one, can't launch the service", cfn.c_str()); 00470 } 00471 else 00472 { 00473 // create the basic .cfg that link the default one 00474 FILE *fp = fopen (cfn.c_str(), "w"); 00475 if (fp == NULL) 00476 { 00477 nlerror ("SERVICE: Can't create config file '%s'", cfn.c_str()); 00478 } 00479 fprintf(fp, "// link the default config file for %s\n", _LongName.c_str()); 00480 fprintf(fp, "RootConfigFilename = \"%s_default.cfg\";\n", _LongName.c_str()); 00481 fclose (fp); 00482 } 00483 } 00484 00485 ConfigFile.load (cfn); 00486 00487 // setup variable with config file variable 00488 IVariable::init (ConfigFile); 00489 00490 // we have to call this again because the config file can changed this variable but the cmd line is more prioritary 00491 if (haveArg('A')) 00492 RunningDirectory = CPath::standardizePath(getArg('A')); 00493 00494 00495 // 00496 // Init debug/log stuffs (must be first things otherwise we can't log if errors) 00497 // 00498 00499 // get the log dir if any in the command line 00500 if (haveArg('L')) 00501 LogDirectory = CPath::standardizePath(getArg('L')); 00502 00503 changeLogDirectory (LogDirectory); 00504 00505 // we create the log with service name filename ("test_service.log" for example) 00506 fd.setParam (LogDirectory.c_str() + _LongName + ".log", false); 00507 00508 DebugLog->addDisplayer (&fd); 00509 InfoLog->addDisplayer (&fd); 00510 WarningLog->addDisplayer (&fd); 00511 AssertLog->addDisplayer (&fd); 00512 ErrorLog->addDisplayer (&fd); 00513 CommandLog.addDisplayer (&fd, true); 00514 00515 // 00516 // Init the hierarchical timer 00517 // 00518 00519 CHTimer::startBench(false, true); 00520 CHTimer::endBench(); 00521 00522 00523 // 00524 // Set the assert mode 00525 // 00526 00527 if (ConfigFile.exists ("Assert")) 00528 setAssert (ConfigFile.getVar("Assert").asInt() == 1); 00529 00530 // 00531 // Set the shard Id 00532 // 00533 00534 if ((var = ConfigFile.getVarPtr("NoWSShardId")) != NULL) 00535 { 00536 _ShardId = var->asInt(); 00537 } 00538 else 00539 { 00540 // something high enough as default 00541 _ShardId = 666; 00542 } 00543 00544 // 00545 // Set the negative filter from the config file 00546 // 00547 00548 for(const char **name = NegFiltersNames; *name; name++) 00549 { 00550 if ((var = ConfigFile.getVarPtr (*name)) != NULL) 00551 { 00552 ConfigFile.setCallback (*name, cbLogFilter); 00553 cbLogFilter(*var); 00554 } 00555 } 00556 00557 ConfigFile.setCallback ("Commands", cbExecuteCommands); 00558 if ((var = ConfigFile.getVarPtr ("Commands")) != NULL) 00559 { 00560 cbExecuteCommands(*var); 00561 } 00562 00563 00564 // 00565 // Create the window if needed 00566 // 00567 00568 if ((var = ConfigFile.getVarPtr ("WindowStyle")) != NULL) 00569 { 00570 string disp = var->asString (); 00571 #ifdef NL_USE_GTK 00572 if (disp == "GTK") 00573 { 00574 WindowDisplayer = new CGtkDisplayer ("DEFAULT_WD"); 00575 } 00576 #endif // NL_USE_GTK 00577 00578 #ifdef NL_OS_WINDOWS 00579 if (disp == "WIN") 00580 { 00581 WindowDisplayer = new CWinDisplayer ("DEFAULT_WD"); 00582 } 00583 #endif // NL_OS_WINDOWS 00584 00585 if (WindowDisplayer == NULL && disp != "NONE") 00586 { 00587 nlwarning ("SERVICE: Unknown value for the WindowStyle (should be GTK, WIN or NONE), use no window displayer"); 00588 } 00589 } 00590 00591 vector <pair<string,uint> > displayedVariables; 00592 //uint speedNetLabel, speedUsrLabel, rcvLabel, sndLabel, rcvQLabel, sndQLabel, scrollLabel; 00593 if (WindowDisplayer != NULL) 00594 { 00595 // 00596 // Init window param if necessary 00597 // 00598 00599 sint x=-1, y=-1, w=-1, h=-1, fs=10, history=-1; 00600 bool iconified = false, ww = false; 00601 string fn; 00602 00603 if ((var = ConfigFile.getVarPtr("XWinParam")) != NULL) x = var->asInt(); 00604 if ((var = ConfigFile.getVarPtr("YWinParam")) != NULL) y = var->asInt(); 00605 if ((var = ConfigFile.getVarPtr("WWinParam")) != NULL) w = var->asInt(); 00606 if ((var = ConfigFile.getVarPtr("HWinParam")) != NULL) h = var->asInt(); 00607 if ((var = ConfigFile.getVarPtr("HistoryWinParam")) != NULL) history = var->asInt(); 00608 if ((var = ConfigFile.getVarPtr("IWinParam")) != NULL) iconified = var->asInt() == 1; 00609 if ((var = ConfigFile.getVarPtr("FontSize")) != NULL) fs = var->asInt(); 00610 if ((var = ConfigFile.getVarPtr("FontName")) != NULL) fn = var->asString(); 00611 if ((var = ConfigFile.getVarPtr("WordWrap")) != NULL) ww = var->asInt() == 1; 00612 00613 if (haveArg('I')) iconified = true; 00614 00615 WindowDisplayer->create (string("*INIT* ") + _ShortName + " " + _LongName, iconified, x, y, w, h, history, fs, fn, ww, &CommandLog); 00616 00617 DebugLog->addDisplayer (WindowDisplayer); 00618 InfoLog->addDisplayer (WindowDisplayer); 00619 WarningLog->addDisplayer (WindowDisplayer); 00620 ErrorLog->addDisplayer (WindowDisplayer); 00621 AssertLog->addDisplayer (WindowDisplayer); 00622 CommandLog.addDisplayer(WindowDisplayer, true); 00623 00624 // adding default displayed variables 00625 displayedVariables.push_back(make_pair(string("NetLop|NetSpeedLoop"), WindowDisplayer->createLabel ("NetLop"))); 00626 displayedVariables.push_back(make_pair(string("UsrLop|UserSpeedLoop"), WindowDisplayer->createLabel ("UsrLop"))); 00627 // displayedVariables.push_back(make_pair(string("Rcv|ReceivedBytes"), WindowDisplayer->createLabel ("Rcv"))); 00628 // displayedVariables.push_back(make_pair(string("Snd|SentBytes"), WindowDisplayer->createLabel ("Snd"))); 00629 // displayedVariables.push_back(make_pair(string("RcvQ|ReceivedQueueSize"), WindowDisplayer->createLabel ("RcvQ"))); 00630 // displayedVariables.push_back(make_pair(string("SndQ|SentQueueSize"), WindowDisplayer->createLabel ("SndQ"))); 00631 displayedVariables.push_back(make_pair(string("|Scroller"), WindowDisplayer->createLabel ("NeL Rulez"))); 00632 00633 CConfigFile::CVar *v = ConfigFile.getVarPtr("DisplayedVariables"); 00634 if (v != NULL) 00635 { 00636 for (sint i = 0; i < v->size(); i++) 00637 { 00638 displayedVariables.push_back(make_pair(v->asString(i), WindowDisplayer->createLabel (v->asString(i).c_str()))); 00639 } 00640 } 00641 } 00642 00643 nlinfo ("SERVICE: Starting Service '%s' using NeL ("__DATE__" "__TIME__") compiled %s", _ShortName.c_str(), CompilationDate.c_str()); 00644 nlinfo ("SERVICE: On OS: %s", CSystemInfo::getOS().c_str()); 00645 00646 setStatus (EXIT_SUCCESS); 00647 00648 // 00649 // Redirect signal if needed (in release mode only) 00650 // 00651 00652 #ifdef NL_OS_WINDOWS 00653 #ifdef NL_RELEASE 00654 initSignal(); 00655 #else 00656 // don't install signal is the application is started in debug mode 00657 if (IsDebuggerPresent ()) 00658 { 00659 //nlinfo("Running with the debugger, don't redirect signals"); 00660 initSignal(); 00661 } 00662 else 00663 { 00664 //nlinfo("Running without the debugger, redirect SIGINT signal"); 00665 initSignal(); 00666 } 00667 #endif 00668 #else // NL_OS_UNIX 00669 initSignal(); 00670 #endif 00671 00672 00673 // 00674 // Ignore SIGPIPE (broken pipe) on unix system 00675 // 00676 00677 #ifdef NL_OS_UNIX 00678 // Ignore the SIGPIPE signal 00679 sigset_t SigList; 00680 bool IgnoredPipe = true; 00681 if (sigemptyset (&SigList) == -1) 00682 { 00683 perror("sigemptyset()"); 00684 IgnoredPipe = false; 00685 } 00686 00687 if (sigaddset (&SigList, SIGPIPE) == -1) 00688 { 00689 perror("sigaddset()"); 00690 IgnoredPipe = false; 00691 } 00692 00693 if (sigprocmask (SIG_BLOCK, &SigList, NULL) == -1) 00694 { 00695 perror("sigprocmask()"); 00696 IgnoredPipe = false; 00697 } 00698 nldebug ("SERVICE: SIGPIPE %s", IgnoredPipe?"Ignored":"Not Ignored"); 00699 #endif // NL_OS_UNIX 00700 00701 00702 // 00703 // Initialize the network system 00704 // 00705 00706 string localhost; 00707 try 00708 { 00709 // Initialize WSAStartup and network stuffs 00710 CSock::initNetwork(); 00711 00712 // Get the localhost name 00713 localhost = CInetAddress::localHost().hostName(); 00714 } 00715 catch (NLNET::ESocket &) 00716 { 00717 localhost = "<UnknownHost>"; 00718 } 00719 00720 // Set the localhost name and service name to the logger 00721 CLog::setProcessName (localhost+"/"+_ShortName); 00722 nlinfo ("SERVICE: Host: %s", localhost.c_str()); 00723 00724 // 00725 // Initialize server parameters 00726 // 00727 00728 // set the listen port if there are a port arg in the command line 00729 if (haveArg('P')) 00730 { 00731 ListeningPort = atoi(getArg('P').c_str()); 00732 } 00733 00734 // set the aliasname if is present in the command line 00735 if (haveArg('N')) 00736 { 00737 _AliasName = getArg('N'); 00738 } 00739 00740 // Load the recording state from the config file 00741 if ((var = ConfigFile.getVarPtr ("Rec")) != NULL) 00742 { 00743 string srecstate = var->asString(); 00744 strupr( srecstate ); 00745 if ( srecstate == "RECORD" ) 00746 { 00747 _RecordingState = CCallbackNetBase::Record; 00748 nlinfo( "SERVICE: Service recording messages" ); 00749 } 00750 else if ( srecstate == "REPLAY" ) 00751 { 00752 _RecordingState = CCallbackNetBase::Replay; 00753 nlinfo( "SERVICE: Service replaying messages" ); 00754 } 00755 else 00756 { 00757 _RecordingState = CCallbackNetBase::Off; 00758 } 00759 } 00760 else 00761 { 00762 // Not found 00763 _RecordingState = CCallbackNetBase::Off; 00764 } 00765 00766 // Load the default stream format 00767 if ((var = ConfigFile.getVarPtr ("StringMsgFormat")) != NULL) 00768 { 00769 CMessage::setDefaultStringMode( var->asInt() == 1 ); 00770 } 00771 else 00772 { 00773 // Not found => binary 00774 CMessage::setDefaultStringMode( false ); 00775 } 00776 00777 /* 00778 // 00779 // Layer4 Startup (Connect to the Naming Service (except for the NS itself and Login Service)) 00780 // 00781 00782 if (IService::_ShortName != "NS" && IService::_ShortName != "LS" && IService::_ShortName != "AES" && IService::_ShortName != "AS") 00783 { 00784 bool ok = false; 00785 while (!ok) 00786 { 00787 // read the naming service address from the config file 00788 CInetAddress loc(ConfigFile.getVar("NSHost").asString(), ConfigFile.getVar("NSPort").asInt()); 00789 try 00790 { 00791 CNetManager::init( &loc, _RecordingState ); 00792 ok = true; 00793 } 00794 catch (ESocketConnectionFailed &) 00795 { 00796 nlwarning ("Could not connect to the Naming Service (%s). Retrying in a few seconds...", loc.asString().c_str()); 00797 nlSleep (5000); 00798 } 00799 } 00800 } 00801 else 00802 { 00803 CNetManager::init( NULL, _RecordingState ); 00804 } 00805 */ 00806 00810 00811 // get the sid 00812 if ((var = ConfigFile.getVarPtr ("SId")) != NULL) 00813 { 00814 sint32 sid = var->asInt(); 00815 if (sid<=0 || sid>255) 00816 { 00817 nlwarning("SERVICE: Bad SId value in the config file, %d is not in [0;255] range", sid); 00818 _SId = 0; 00819 } 00820 else 00821 { 00822 _SId = (uint8) sid; 00823 } 00824 } 00825 else 00826 { 00827 // ok, SId not found, use dynamic sid 00828 _SId = 0; 00829 } 00830 00831 00832 // look if we don't want to use NS 00833 if ((var = ConfigFile.getVarPtr ("DontUseNS")) != NULL) 00834 { 00835 // if we set the value in the config file, get it 00836 _DontUseNS = (var->asInt() == 1); 00837 } 00838 else 00839 { 00840 // if not, we use ns only if service is not ns, ls, aes, as 00841 _DontUseNS = false; 00842 } 00843 00844 // 00845 // Register all network associations (must be before the CUnifiedNetwork::getInstance()->init) 00846 // 00847 00848 if ((var = ConfigFile.getVarPtr ("Networks")) != NULL) 00849 { 00850 for (uint8 i = 0; i < var->size (); i++) 00851 CUnifiedNetwork::getInstance()->addNetworkAssociation (var->asString(i), i); 00852 } 00853 00854 if ((var = ConfigFile.getVarPtr ("DefaultNetworks")) != NULL) 00855 { 00856 for (uint8 i = 0; i < var->size (); i++) 00857 CUnifiedNetwork::getInstance()->addDefaultNetwork(var->asString(i)); 00858 } 00859 00860 // normal setup for the common services 00861 if (!_DontUseNS) 00862 { 00863 bool ok = false; 00864 while (!ok) 00865 { 00866 string LSAddr; 00867 00868 if (haveArg('B')) 00869 { 00870 // if the naming service address is set on the command line, get it (overwrite the cfg) 00871 LSAddr = getArg('B'); 00872 } 00873 else 00874 { 00875 // else read the naming service address from the config file 00876 LSAddr = ConfigFile.getVar ("NSHost").asString(); 00877 } 00878 00879 // if there's no port to the NS, use the default one 50000 00880 if (LSAddr.find(":") == string::npos) 00881 LSAddr += ":50000"; 00882 00883 CInetAddress loc(LSAddr); 00884 try 00885 { 00886 if ( CUnifiedNetwork::getInstance()->init (&loc, _RecordingState, _ShortName, ListeningPort, _SId) ) 00887 { 00888 ok = true; 00889 } 00890 else 00891 { 00892 nlinfo( "SERVICE: Exiting..." ); 00893 beep( 880, 400 ); 00894 beep( 440, 400 ); 00895 beep( 220, 400 ); 00896 return 10; 00897 } 00898 } 00899 catch (ESocketConnectionFailed &) 00900 { 00901 nlwarning ("SERVICE: Could not connect to the Naming Service (%s). Retrying in a few seconds...", loc.asString().c_str()); 00902 nlSleep (5000); 00903 } 00904 } 00905 } 00906 else 00907 { 00908 CUnifiedNetwork::getInstance()->init(NULL, _RecordingState, _ShortName, ListeningPort, _SId); 00909 } 00910 00911 // At this point, the _SId must be ok if we use the naming service. 00912 // If it's 0, it means that we don't use NS and we left the other side server to find a sid for your connection 00913 00914 if(!_DontUseNS) 00915 { 00916 nlassert (_SId != 0); 00917 } 00918 00919 // 00920 // Connect to the local AES and send identification 00921 // 00922 00923 // look if we don't want to use NS 00924 if ((var = ConfigFile.getVarPtr ("DontUseAES")) != NULL) 00925 { 00926 // if we set the value in the config file, get it 00927 _DontUseAES = var->asInt() == 1; 00928 } 00929 else 00930 { 00931 // if not, we use aes only if service is not aes or as 00932 _DontUseAES = false; 00933 } 00934 00935 initAdmin (_DontUseAES); 00936 00937 00938 // 00939 // Add callback array 00940 // 00941 00942 // add inner service callback array 00943 NLNET::CUnifiedNetwork::getInstance()->addCallbackArray(builtinServiceCallbacks, sizeof(builtinServiceCallbacks)/sizeof(builtinServiceCallbacks[0])); 00944 00945 // add callback set in the NLNET_SERVICE_MAIN macro 00946 NLNET::CUnifiedNetwork::getInstance()->addCallbackArray(_CallbackArray, _CallbackArraySize); 00947 00948 // 00949 // Now we have the service id, we can set the entites id generator 00950 // 00951 00952 NLMISC::CEntityId::setServiceId(_SId); 00953 00954 // Set the localhost name and service name and the sid 00955 CLog::setProcessName (localhost+"/"+_ShortName+"-"+toString((uint16)_SId)); 00956 00957 00958 // 00959 // Add default pathes 00960 // 00961 00962 if ((var = ConfigFile.getVarPtr ("IgnoredFiles")) != NULL) 00963 { 00964 for (sint i = 0; i < var->size(); i++) 00965 { 00966 CPath::addIgnoredDoubleFile (var->asString(i)); 00967 } 00968 } 00969 00970 if ((var = ConfigFile.getVarPtr ("Paths")) != NULL) 00971 { 00972 for (sint i = 0; i < var->size(); i++) 00973 { 00974 CPath::addSearchPath (var->asString(i), true, false); 00975 } 00976 } 00977 00978 if ((var = ConfigFile.getVarPtr ("PathsNoRecurse")) != NULL) 00979 { 00980 for (sint i = 0; i < var->size(); i++) 00981 { 00982 CPath::addSearchPath (var->asString(i), false, false); 00983 } 00984 } 00985 00986 // if we can, try to setup where to save files 00987 if (IService::getInstance()->haveArg('W')) 00988 { 00989 // use the command line param if set 00990 SaveFilesDirectory = IService::getInstance()->getArg('W'); 00991 } 00992 00993 00994 // 00995 // Call the user service init 00996 // 00997 00998 userInitCalled = true; // the bool must be put *before* the call to init() 00999 init (); 01000 01001 01002 // 01003 // Connects to the present services 01004 // WARNING: only after the user init() was called because the 01005 // addService may call up service callbacks. 01006 // 01007 01008 CUnifiedNetwork::getInstance()->connect(); 01009 01010 // 01011 // Say to the AES that the service is ready 01012 // 01013 01014 if (!_DontUseAES) 01015 { 01016 // send the ready message (service init finished) 01017 CMessage msgout ("SR"); 01018 CUnifiedNetwork::getInstance()->send("AES", msgout); 01019 } 01020 01021 01022 _Initialized = true; 01023 01024 nlinfo ("SERVICE: Service initialised, executing StartCommands"); 01025 01026 // 01027 // Call the user command from the config file if any 01028 // 01029 01030 if ((var = ConfigFile.getVarPtr ("StartCommands")) != NULL) 01031 { 01032 for (sint i = 0; i < var->size(); i++) 01033 { 01034 ICommand::execute (var->asString(i), CommandLog); 01035 } 01036 } 01037 01038 string str; 01039 CLog logDisplayVars; 01040 CLightMemDisplayer mdDisplayVars; 01041 logDisplayVars.addDisplayer (&mdDisplayVars); 01042 01043 // 01044 // Activate the timeout assertion thread 01045 // 01046 01047 IThread::create(&MyTAT)->start(); 01048 01049 // 01050 // Set service ready 01051 // 01052 01053 nlinfo ("SERVICE: Service ready"); 01054 01055 if (WindowDisplayer != NULL) 01056 WindowDisplayer->setTitleBar (_ShortName + " " + _LongName + " " + Version.c_str()); 01057 01058 // 01059 // Call the user service update each loop and check files and network activity 01060 // 01061 01062 do 01063 { 01064 MyTAT.activate(); 01065 01066 if(Bench) CHTimer::startBench(false, true, false); 01067 01068 // count the amount of time to manage internal system 01069 TTime bbefore = CTime::getLocalTime (); 01070 01071 // call the user update and exit if the user update asks it 01072 { 01073 H_AUTO(NLNETServiceUpdate); 01074 if (!update ()) 01075 { 01076 CHTimer::endBench(); 01077 break; 01078 } 01079 } 01080 01081 // if the launching mode is 'quit after the first update' we set the exit signal 01082 if (haveArg('Q')) 01083 { 01084 ExitSignalAsked = 1; 01085 } 01086 NbUserUpdate++; 01087 01088 // count the amount of time to manage internal system 01089 TTime before = CTime::getLocalTime (); 01090 01091 if (WindowDisplayer != NULL) 01092 { 01093 // update the window displayer and quit if asked 01094 if (!WindowDisplayer->update ()) 01095 { 01096 nlinfo ("SERVICE: The window displayer was closed by user, need to quit"); 01097 ExitSignalAsked = 1; 01098 } 01099 } 01100 01101 // stop the loop if the exit signal asked 01102 if (ExitSignalAsked > 0) 01103 { 01104 CHTimer::endBench(); 01105 break; 01106 } 01107 01108 CConfigFile::checkConfigFiles (); 01109 01110 updateAdmin (); 01111 01112 CFile::checkFileChange(); 01113 01114 // get and manage layer 5 messages 01115 CUnifiedNetwork::getInstance()->update (_UpdateTimeout); 01116 01117 // resync the clock every hours 01118 // if (resyncEvenly) 01119 // { 01120 // static TTime LastSyncTime = CTime::getLocalTime (); 01121 01122 //--------------------------------------- 01123 // To simulate Ctrl-C in the debugger... Exit after 1 min ! 01124 /*if (CTime::getLocalTime () - LastSyncTime > 60 * 1000 ) 01125 { 01126 ExitSignalAsked = 1; 01127 }*/ 01128 //--------------------------------------- 01129 /* 01130 if (CTime::getLocalTime () - LastSyncTime > 60*60*1000) 01131 { 01132 CUniTime::syncUniTimeFromService ( _RecordingState ); 01133 LastSyncTime = CTime::getLocalTime (); 01134 } 01135 */ 01136 // } 01137 01138 NetSpeedLoop = (sint32) (CTime::getLocalTime () - before); 01139 UserSpeedLoop = (sint32) (before - bbefore); 01140 01141 if (WindowDisplayer != NULL) 01142 { 01143 uint64 rcv, snd, rcvq, sndq; 01144 rcv = CUnifiedNetwork::getInstance()->getBytesReceived (); 01145 snd = CUnifiedNetwork::getInstance()->getBytesSent (); 01146 rcvq = CUnifiedNetwork::getInstance()->getReceiveQueueSize (); 01147 sndq = CUnifiedNetwork::getInstance()->getSendQueueSize (); 01148 01149 for (uint i = 0; i < displayedVariables.size(); i++) 01150 { 01151 // it s a separator, do nothing 01152 if (displayedVariables[i].first.empty()) 01153 continue; 01154 01155 // it s a command, do nothing 01156 if (displayedVariables[i].first[0] == '@') 01157 continue; 01158 01159 string dispName = displayedVariables[i].first; 01160 string varName = dispName; 01161 uint32 pos = dispName.find("|"); 01162 if (pos != string::npos) 01163 { 01164 varName = displayedVariables[i].first.substr(pos+1); 01165 dispName = displayedVariables[i].first.substr(0, pos); 01166 } 01167 01168 if (dispName.empty()) 01169 str = ""; 01170 else 01171 str = dispName + ": "; 01172 01173 mdDisplayVars.clear (); 01174 ICommand::execute(varName, logDisplayVars, true); 01175 const std::deque<std::string> &strs = mdDisplayVars.lockStrings(); 01176 if (strs.size()>0) 01177 { 01178 str += strs[0].substr(0,strs[0].size()-1); 01179 /* 01180 string s_ = strs[0]; 01181 01182 uint32 pos = strs[0].find("="); 01183 if(pos != string::npos && pos + 2 < strs[0].size()) 01184 { 01185 uint32 pos2 = string::npos; 01186 if(strs[0][strs[0].size()-1] == '\n') 01187 pos2 = strs[0].size() - pos - 2 - 1; 01188 01189 str += strs[0].substr (pos+2, pos2); 01190 } 01191 else 01192 { 01193 str += "???"; 01194 }*/ 01195 } 01196 else 01197 { 01198 str += "???"; 01199 } 01200 mdDisplayVars.unlockStrings(); 01201 WindowDisplayer->setLabel (displayedVariables[i].second, str); 01202 } 01203 01204 } 01205 01206 // nldebug ("SYNC: updatetimeout must be %d and is %d, sleep the rest of the time", _UpdateTimeout, delta); 01207 01208 CHTimer::endBench(); 01209 01210 // Resetting the hierarchical timer must be done outside the top-level timer 01211 if ( _ResetMeasures ) 01212 { 01213 CHTimer::clear(); 01214 _ResetMeasures = false; 01215 } 01216 01217 MyTAT.desactivate(); 01218 } 01219 while (true); 01220 } 01221 /* catch (ETrapDebug &) 01222 { 01223 // we have to do that if we want to trap unhandled exception with the report message box 01224 setStatus (EXIT_FAILURE); 01225 } 01226 */ catch (EFatalError &) 01227 { 01228 // Somebody call nlerror, so we have to quit now, the message already display 01229 // so we don't have to to anything 01230 setStatus (EXIT_FAILURE); 01231 } 01232 catch ( uint ) // SEH exceptions 01233 { 01234 ErrorLog->displayNL( "SERVICE: System exception" ); 01235 } 01236 01237 #ifdef NL_RELEASE 01238 /* // in release mode, we catch everything to handle clean release. 01239 catch (Exception &e) 01240 { 01241 // Catch NeL exception to release the system cleanly 01242 setStatus (EXIT_FAILURE); 01243 nlinfo ("ERROR: NeL Exception: Error running the service \"%s\": %s", _ShortName.c_str(), e.what()); 01244 } 01245 catch (...) 01246 { 01247 // Catch anything we can to release the system cleanly 01248 setStatus (EXIT_FAILURE); 01249 nlinfo ("ERROR: Unknown external exception"); 01250 } 01251 */ 01252 #endif 01253 01254 try 01255 { 01256 nlinfo ("SERVICE: Service starts releasing"); 01257 01258 // 01259 // Call the user service release() if the init() was called 01260 // 01261 01262 if (userInitCalled) 01263 release (); 01264 01265 // 01266 // Delete all network connection (naming client also) 01267 // 01268 01269 CUnifiedNetwork::getInstance()->release (); 01270 01271 CSock::releaseNetwork (); 01272 01273 // 01274 // Remove the window displayer 01275 // 01276 01277 if (WindowDisplayer != NULL) 01278 { 01279 DebugLog->removeDisplayer (WindowDisplayer); 01280 InfoLog->removeDisplayer (WindowDisplayer); 01281 WarningLog->removeDisplayer (WindowDisplayer); 01282 ErrorLog->removeDisplayer (WindowDisplayer); 01283 AssertLog->removeDisplayer (WindowDisplayer); 01284 CommandLog.removeDisplayer (WindowDisplayer); 01285 01286 delete WindowDisplayer; 01287 WindowDisplayer = NULL; 01288 } 01289 01290 nlinfo ("SERVICE: Service released succesfuly"); 01291 } 01292 /* catch (ETrapDebug &) 01293 { 01294 // we have to do that if we want to trap unhandled exception with the report message box 01295 setStatus (EXIT_FAILURE); 01296 } 01297 */ catch (EFatalError &) 01298 { 01299 // Somebody call nlerror, so we have to quit now, the message already display 01300 // so we don't have to to anything 01301 setStatus (EXIT_FAILURE); 01302 } 01303 01304 #ifdef NL_RELEASE 01305 /* // in release mode, we catch everything to handle clean release. 01306 catch (Exception &e) 01307 { 01308 setStatus (EXIT_FAILURE); 01309 nlinfo ("ERROR: NeL Exception: Error releasing the service \"%s\": %s", _ShortName.c_str(), e.what()); 01310 } 01311 catch (...) 01312 { 01313 // Catch anything we can to release the system cleanly 01314 setStatus (EXIT_FAILURE); 01315 nlinfo ("ERROR: Unknown external exception"); 01316 } 01317 */ 01318 #endif 01319 01320 CHTimer::display(); 01321 CHTimer::displayByExecutionPath (); 01322 CHTimer::displayHierarchical(&CommandLog, true, 64); 01323 CHTimer::displayHierarchicalByExecutionPathSorted (&CommandLog, CHTimer::TotalTime, true, 64); 01324 01325 nlinfo ("SERVICE: Service ends"); 01326 01327 string name = getServiceLongName () + ".memory_report"; 01328 NLMEMORY::StatisticsReport (name.c_str(), false); 01329 01330 return ExitSignalAsked?100+ExitSignalAsked:getStatus (); 01331 } |
|
Finalization. Release the service. For example, this founction free all allocation made in the init() function.
Definition at line 191 of file service.h. Referenced by main().
00191 {} |
|
Require to reset the hierarchical timer.
Definition at line 1342 of file service.cpp. References _ResetMeasures.
01343 { 01344 _ResetMeasures = true; 01345 } |
|
Sets the command line and init _Args variable. You must call this before calling main().
Definition at line 335 of file service.cpp. References uint32.
00336 { 00337 _Args.push_back ("<ProgramName>"); 00338 00339 string sargs (args); 00340 uint32 pos1 = 0, pos2 = 0; 00341 00342 do 00343 { 00344 pos1 = sargs.find_first_not_of (" ", pos2); 00345 if (pos1 == string::npos) break; 00346 pos2 = sargs.find_first_of (" ", pos1); 00347 _Args.push_back (sargs.substr (pos1, pos2-pos1)); 00348 } 00349 while (pos2 != string::npos); 00350 } |
|
Sets the command line and init _Args variable. You must call this before calling main().
Definition at line 352 of file service.cpp. References sint.
|
|
Sets the default callback array given from the macro.
Definition at line 291 of file service.h. References _CallbackArraySize, and uint.
00291 { _CallbackArray = array; _CallbackArraySize = nbelem; } |
|
Changes the recording state (use if you know what you are doing).
Definition at line 327 of file service.h.
00327 { _RecordingState = rec; } |
|
Sets the status of the service, this status is return to the application. EXIT_SUCCESS is the default status You can set it to EXIT_FAILURE or any value you want. It's useful when you use the service in a script and you want to know the return value of the application to do the appropriate things. Definition at line 251 of file service.h. Referenced by main().
00251 { _Status = status; } |
|
Selects timeout value in seconds for each update. You are absolutely certain that your update() function will not be called before this amount of time you set. If you set the update timeout value higher than 0, all messages in queues will be process until the time greater than the timeout user update(). If you set the update timeout value to 0, all messages in queues will be process one time before calling the user update(). The default value is 100 (100ms) Definition at line 264 of file service.h. References _UpdateTimeout, and NLMISC::TTime.
00264 { /*if (timeout>1.0) nlerror ("IServer::setUpdateTimeout is now a double in SECOND and not ms");*/ _UpdateTimeout = timeout; } |
|
Definition at line 315 of file service.h.
00315 { Version = version; } |
|
This function is called every "frame" (you must call init() before). It returns false if the service is stopped.
Definition at line 188 of file service.h. Referenced by main().
00188 { return true; } |
|
|
|
|
|
|
|
|
|
|
|
|
|
Definition at line 347 of file service.h. Referenced by getServiceAliasName(), getServiceUnifiedName(), and main(). |
|
Array of arguments pass from the command line.
|
|
|
|
Definition at line 376 of file service.h. Referenced by main(), and setCallbackArray(). |
|
true if the service don't use the admin executor service
Definition at line 381 of file service.h. Referenced by main(). |
|
true if the service don't use the naming service
Definition at line 379 of file service.h. Referenced by main(). |
|
true if the service initialisation is passed
|
|
Instance of this service (singleton).
Definition at line 115 of file service.cpp. |
|
Definition at line 346 of file service.h. Referenced by getServiceLongName(), and main(). |
|
Recording state.
|
|
Require to reset the hierarchical timer.
Definition at line 384 of file service.h. Referenced by main(), and requireResetMeasures(). |
|
Shard Id.
Definition at line 387 of file service.h. Referenced by getShardId(), and main(). |
|
Current service name sets by the actual service when declaring NLNET_SERVICE_MAIN.
Definition at line 345 of file service.h. Referenced by getServiceShortName(), getServiceUnifiedName(), and main(). |
|
the service id of this sevice
Definition at line 356 of file service.h. Referenced by getServiceId(), getServiceUnifiedName(), and main(). |
|
the status of this service (the status is give to the at the release time)
Definition at line 359 of file service.h. Referenced by getStatus(), and setStatus(). |
|
Select timeout value in milliseconds between to call of user update().
Definition at line 353 of file service.h. Referenced by main(), and setUpdateTimeout(). |
|
Definition at line 273 of file service.h. Referenced by main(). |
|
The directory where the configfile is.
Definition at line 365 of file service.h. Referenced by main(). |
|
Definition at line 270 of file service.h. Referenced by main(). |
|
Listening port of this service.
|
|
The directory where the logfiles are.
Definition at line 368 of file service.h. Referenced by main(). |
|
The directory where the service is running.
Definition at line 371 of file service.h. Referenced by main(). |
|
Directory where to store files that the services will write during the exploitation of the game (for example: player backup, string cache) Use .toString() to access to the value Definition at line 313 of file service.h. Referenced by main(). |
|
|
|
The window displayer instance.
Definition at line 305 of file service.h. Referenced by main(). |
|
Directory where to store files that the services will write but are the same for all shard instance (for example: packet_sheets) Use .toString() to access to the value |