From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- docs/doxygen/nel/service_8cpp-source.html | 1616 +++++++++++++++++++++++++++++ 1 file changed, 1616 insertions(+) create mode 100644 docs/doxygen/nel/service_8cpp-source.html (limited to 'docs/doxygen/nel/service_8cpp-source.html') diff --git a/docs/doxygen/nel/service_8cpp-source.html b/docs/doxygen/nel/service_8cpp-source.html new file mode 100644 index 00000000..f1ca647d --- /dev/null +++ b/docs/doxygen/nel/service_8cpp-source.html @@ -0,0 +1,1616 @@ + + + + nevrax.org : docs + + + + + + + + + + + + + + +
# Home   # nevrax.com   
+ + + + +
Nevrax
+ + + + + + + + + + +
+ + +
+ Nevrax.org
+ + + + + + + +
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
+
+ + +
+ + +
+Docs + +
+  + + + + + +
Documentation 
+ +
+Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  
+

service.cpp

Go to the documentation of this file.
00001 
+00009 /* Copyright, 2001 Nevrax Ltd.
+00010  *
+00011  * This file is part of NEVRAX NEL.
+00012  * NEVRAX NEL is free software; you can redistribute it and/or modify
+00013  * it under the terms of the GNU General Public License as published by
+00014  * the Free Software Foundation; either version 2, or (at your option)
+00015  * any later version.
+00016  *
+00017  * NEVRAX NEL is distributed in the hope that it will be useful, but
+00018  * WITHOUT ANY WARRANTY; without even the implied warranty of
+00019  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+00020  * General Public License for more details.
+00021  *
+00022  * You should have received a copy of the GNU General Public License
+00023  * along with NEVRAX NEL; see the file COPYING. If not, write to the
+00024  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+00025  * MA 02111-1307, USA.
+00026  */
+00027 
+00028 #include "stdnet.h"
+00029 
+00030 #ifdef NL_OS_WINDOWS
+00031 
+00032 //
+00033 // Includes
+00034 //
+00035 
+00036 // these defines is for IsDebuggerPresent(). it'll not compile on windows 95
+00037 // just comment this and the IsDebuggerPresent to compile on windows 95
+00038 #       define _WIN32_WINDOWS   0x0410
+00039 #       define WINVER                   0x0400
+00040 #       include <windows.h>
+00041 #       include <direct.h>
+00042 
+00043 #elif defined NL_OS_UNIX
+00044 
+00045 #       include <unistd.h>
+00046 
+00047 #endif
+00048 
+00049 #include <stdlib.h>
+00050 #include <signal.h>
+00051 
+00052 #include "nel/misc/config_file.h"
+00053 #include "nel/misc/displayer.h"
+00054 #include "nel/misc/mutex.h"
+00055 #include "nel/misc/window_displayer.h"
+00056 #include "nel/misc/gtk_displayer.h"
+00057 #include "nel/misc/win_displayer.h"
+00058 #include "nel/misc/path.h"
+00059 #include "nel/misc/hierarchical_timer.h"
+00060 #include "nel/misc/report.h"
+00061 
+00062 #include "nel/net/naming_client.h"
+00063 #include "nel/net/service.h"
+00064 #include "nel/net/unified_network.h"
+00065 #include "nel/net/net_manager.h"
+00066 #include "nel/net/net_displayer.h"
+00067 #include "nel/net/email.h"
+00068 #include "nel/net/varpath.h"
+00069 
+00070 #include "nel/misc/hierarchical_timer.h"
+00071 
+00072 
+00073 //
+00074 // Namespace
+00075 //
+00076 
+00077 using namespace std;
+00078 using namespace NLMISC;
+00079 
+00080 
+00081 namespace NLNET
+00082 {
+00083 
+00084 
+00085 //
+00086 // Constants
+00087 //
+00088 
+00089 static const sint Signal[] = {
+00090   SIGABRT, SIGFPE, SIGILL, SIGINT, SIGSEGV, SIGTERM
+00091 };
+00092 
+00093 static const char *SignalName[]=
+00094 {
+00095   "SIGABRT", "SIGFPE", "SIGILL", "SIGINT", "SIGSEGV", "SIGTERM"
+00096 };
+00097 
+00098 
+00099 //
+00100 // Variables
+00101 //
+00102 
+00103 
+00104 // class static member
+00105 IService        *IService::_Instance = NULL;
+00106 
+00107 static sint ExitSignalAsked = 0;
+00108 
+00109 // services stat
+00110 static sint32 NetSpeedLoop, UserSpeedLoop;
+00111 
+00112 // this is the thread that initialized the signal redirection
+00113 // we ll ignore other thread signals
+00114 static uint SignalisedThread;
+00115 
+00116 static CFileDisplayer fd;
+00117 static CNetDisplayer commandDisplayer(false);
+00118 static CLog commandLog;
+00119 
+00120 
+00121 //
+00122 // Callback managing
+00123 //
+00124 
+00125 void serviceGetView (uint32 rid, const string &rawvarpath, vector<string> &vara, vector<string> &vala)
+00126 {
+00127         string str;
+00128         CLog logDisplayVars;
+00129         CMemDisplayer mdDisplayVars;
+00130         logDisplayVars.addDisplayer (&mdDisplayVars);
+00131         
+00132         CVarPath varpath(rawvarpath);
+00133         
+00134         // add default row
+00135         vara.push_back ("service");
+00136 
+00137         vala.push_back (IService::getInstance ()->getServiceUnifiedName());
+00138         
+00139         for (uint j = 0; j < varpath.Destination.size (); j++)
+00140         {
+00141                 string cmd = varpath.Destination[j].first;
+00142 
+00143                 // replace = with space to execute the command
+00144                 uint pos = cmd.find("=");
+00145                 if (pos != string::npos)
+00146                         cmd[pos] = ' ';
+00147 
+00148                 mdDisplayVars.clear ();
+00149                 ICommand::execute(cmd, logDisplayVars, true);
+00150                 const std::deque<std::string>   &strs = mdDisplayVars.lockStrings();
+00151                 if (strs.size()>0)
+00152                 {
+00153                         string s_ = strs[0];
+00154                         
+00155                         uint32 pos = strs[0].find("=");
+00156                         if(pos != string::npos && pos + 2 < strs[0].size())
+00157                         {
+00158                                 uint32 pos2 = string::npos;
+00159                                 if(strs[0][strs[0].size()-1] == '\n')
+00160                                         pos2 = strs[0].size() - pos - 2 - 1;
+00161                                 
+00162                                 str = strs[0].substr (pos+2, pos2);
+00163                         }
+00164                         else
+00165                         {
+00166                                 str = "???";
+00167                         }
+00168                 }
+00169                 else
+00170                 {
+00171                         str = "???";
+00172                 }
+00173                 mdDisplayVars.unlockStrings();
+00174                 
+00175                 if (pos != string::npos)
+00176                         vara.push_back(cmd.substr(0, pos));
+00177                 else
+00178                         vara.push_back(cmd);
+00179 
+00180                 vala.push_back (str);
+00181                 nlinfo ("Add to result view '%s' = '%s'", varpath.Destination[j].first.c_str(), str.c_str());
+00182         }
+00183         
+00184 }
+00185 
+00186 void servcbGetView (CMessage &msgin, const std::string &serviceName, uint16 sid)
+00187 {
+00188         uint32 rid;
+00189         string rawvarpath;
+00190 
+00191         msgin.serial (rid);
+00192         msgin.serial (rawvarpath);
+00193 
+00194         vector<string> vara;
+00195         vector<string> vala;
+00196 
+00197         serviceGetView (rid, rawvarpath, vara, vala);
+00198 
+00199         CMessage msgout("VIEW");
+00200         msgout.serial(rid);
+00201         
+00202         msgout.serialCont (vara);
+00203         msgout.serialCont (vala);
+00204 
+00205         CUnifiedNetwork::getInstance ()->send (sid, msgout);
+00206         nlinfo ("Sent result view to service '%s-%hu'", serviceName.c_str(), sid);
+00207 }
+00208 
+00209 void AESConnection (const string &serviceName, uint16 sid, void *arg)
+00210 {
+00211         // established a connection to the AES, identify myself
+00212 
+00213         //
+00214         // Sends the identification message with the name of the service and all commands available on this service
+00215         //
+00216 
+00217         CMessage msgout ("SID");
+00218         uint32 pid = getpid ();
+00219         msgout.serial (IService::getInstance()->_AliasName, IService::getInstance()->_LongName, pid);
+00220         ICommand::serialCommands (msgout);
+00221         CUnifiedNetwork::getInstance()->send("AES", msgout);
+00222 
+00223         if (IService::getInstance()->_Initialized)
+00224         {
+00225                 CMessage msgout2 ("SR");
+00226                 CUnifiedNetwork::getInstance()->send("AES", msgout2);
+00227         }
+00228 
+00229         // add the displayer to the standard logger
+00230 //      TSockId                 hid;
+00231 //      CCallbackClient *client = dynamic_cast<CCallbackClient *>(CUnifiedNetwork::getInstance()->getNetBase("AES", hid));
+00232 //      commandDisplayer.setLogServer (client);
+00233 //      commandLog.addDisplayer (&commandDisplayer);
+00234 }
+00235 
+00236 
+00237 static void AESDisconnection (const std::string &serviceName, uint16 sid, void *arg)
+00238 {
+00239 //      commandLog.removeDisplayer (&commandDisplayer);
+00240 }
+00241 
+00242 
+00243 static void cbExecCommand (CMessage &msgin, const std::string &serviceName, uint16 sid)
+00244 {
+00245         nlwarning ("AES: Deprecated function call cbExecCommand");
+00246 
+00247 /*      string command;
+00248         msgin.serial (command);
+00249 
+00250         ICommand::execute (command, commandLog);
+00251 */}
+00252 
+00253 
+00254 static void cbStopService (CMessage &msgin, const std::string &serviceName, uint16 sid)
+00255 {
+00256         nlinfo ("Receive a stop from service %s-%d, need to quit", serviceName.c_str(), sid);
+00257         ExitSignalAsked = 0xFFFF;
+00258 }
+00259 
+00260 
+00261 
+00262 // layer 5
+00263 static TUnifiedCallbackItem AESCallbackArray[] =
+00264 {
+00265         { "STOPS", cbStopService },
+00266         { "EXEC_COMMAND", cbExecCommand },
+00267         { "GET_VIEW", servcbGetView },
+00268 };
+00269 
+00270 //
+00271 // Signals managing
+00272 //
+00273 
+00274 // This function is called when a signal comes
+00275 static void sigHandler(int Sig)
+00276 {
+00277         // redirect the signal for the next time
+00278         signal(Sig, sigHandler);
+00279 
+00280         // find the signal
+00281         for (int i = 0; i < (int)(sizeof(Signal)/sizeof(Signal[0])); i++)
+00282         {
+00283                 if (Sig == Signal[i])
+00284                 {
+00285                         if (getThreadId () != SignalisedThread)
+00286                         {
+00287                                 nldebug ("Not the main thread received the signal (%s, %d), ignore it", SignalName[i],Sig);
+00288                                 return;
+00289                         }
+00290                         else
+00291                         {
+00292                                 nlinfo ("Signal %s (%d) received", SignalName[i], Sig);
+00293                                 switch (Sig)
+00294                                 {
+00295                                 case SIGABRT :
+00296                                 case SIGILL  :
+00297                                 case SIGINT  :
+00298                                 case SIGSEGV :
+00299                                 case SIGTERM :
+00300                                 // you should not call a function and system function like printf in a SigHandle because
+00301                                 // signal-handler routines are usually called asynchronously when an interrupt occurs.
+00302                                 if (ExitSignalAsked == 0)
+00303                                 {
+00304                                         nlinfo ("Receive a signal that said that i must exit");
+00305                                         ExitSignalAsked = Sig;
+00306                                         return;
+00307                                 }
+00308                                 else
+00309                                 {
+00310                                         nlinfo ("Signal already received, launch the brutal exit");
+00311                                         exit (EXIT_FAILURE);
+00312                                 }
+00313                                 break;
+00314                                 }
+00315                         }
+00316                 }
+00317         }
+00318         nlinfo ("Unknown signal received (%d)", Sig);
+00319 }
+00320 
+00321 // Initialise the signal redirection
+00322 static void initSignal()
+00323 {
+00324         SignalisedThread = getThreadId ();
+00325 #ifdef NL_DEBUG
+00326         // in debug mode, we only trap the SIGINT signal
+00327         signal(Signal[3], sigHandler);
+00328         //nldebug("Signal : %s (%d) trapped", SignalName[3], Signal[3]);
+00329 #else
+00330         // in release, redirect all signals
+00331 /* don't redirect now because to hard to debug...
+00332         for (int i = 0; i < (int)(sizeof(Signal)/sizeof(Signal[0])); i++)
+00333         {
+00334                 signal(Signal[i], sigHandler);
+00335                 nldebug("Signal %s (%d) trapped", SignalName[i], Signal[i]);
+00336         }
+00337 */
+00338 #endif
+00339 }
+00340 
+00341 //
+00342 // Class implementation
+00343 //
+00344 
+00345 // Ctor
+00346 IService::IService() :
+00347         WindowDisplayer(NULL),
+00348         _Port(0),
+00349         _RecordingState(CCallbackNetBase::Off),
+00350         _UpdateTimeout(100),
+00351         _SId(0),
+00352         _Status(0),
+00353         _Initialized(false),
+00354         _ResetMeasures(false)
+00355 {
+00356         // Singleton
+00357         nlassert( _Instance == NULL );
+00358 
+00359         _Instance = this;
+00360 }
+00361 
+00362 
+00363 
+00364 bool IService::haveArg (char argName)
+00365 {
+00366         for (uint32 i = 0; i < _Args.size(); i++)
+00367         {
+00368                 if (_Args[i].size() >= 2 && _Args[i][0] == '-')
+00369                 {
+00370                         if (_Args[i][1] == argName)
+00371                         {
+00372                                 return true;
+00373                         }
+00374                 }
+00375         }
+00376         return false;
+00377 }
+00378 
+00379 string IService::getArg (char argName)
+00380 {
+00381         for (uint32 i = 0; i < _Args.size(); i++)
+00382         {
+00383                 if (_Args[i].size() >= 2 && _Args[i][0] == '-')
+00384                 {
+00385                         if (_Args[i][1] == argName)
+00386                         {
+00387                                 return _Args[i].substr(2);
+00388                         }
+00389                 }
+00390         }
+00391         throw Exception ("Parameter '-%c' is not found in command line", argName);
+00392 }
+00393 
+00394 
+00395 void IService::setArgs (const char *args)
+00396 {
+00397         _Args.push_back ("<ProgramName>");
+00398 
+00399         string sargs (args);
+00400         uint32 pos1 = 0, pos2 = 0;
+00401 
+00402         do
+00403         {
+00404                 pos1 = sargs.find_first_not_of (" ", pos2);
+00405                 if (pos1 == string::npos) break;
+00406                 pos2 = sargs.find_first_of (" ", pos1);
+00407                 _Args.push_back (sargs.substr (pos1, pos2-pos1));
+00408         }
+00409         while (pos2 != string::npos);
+00410 }
+00411 
+00412 void IService::setArgs (int argc, const char **argv)
+00413 {
+00414         for (sint i = 0; i < argc; i++)
+00415         {
+00416                 _Args.push_back (argv[i]);
+00417         }
+00418 }
+00419 
+00420 /*
+00421  * Returns a pointer to the CCallbackServer object
+00422  */
+00423 CCallbackServer *IService::getServer()
+00424 {
+00425         return NULL;
+00426 }
+00427 
+00428 
+00429 
+00430 void cbLogFilter (CConfigFile::CVar &var)
+00431 {
+00432         CLog *log = NULL;
+00433         if (var.Name == "NegFiltersDebug")
+00434         {
+00435                 log = DebugLog;
+00436                 nlinfo ("Updating negative filter on debug from config file");
+00437         }
+00438         else if (var.Name == "NegFiltersInfo")
+00439         {
+00440                 log = InfoLog;
+00441                 nlinfo ("Updating negative filter on info from config file");
+00442         }
+00443         else
+00444         {
+00445                 nlstop;
+00446         }
+00447 
+00448         // remove all old filter from configfile
+00449         CConfigFile::CVar &oldvar = IService::getInstance()->ConfigFile.getVar (var.Name);
+00450         for (sint j = 0; j < oldvar.size(); j++)
+00451         {
+00452                 log->removeFilter (oldvar.asString(j).c_str());
+00453         }
+00454 
+00455         // add all new filter from configfile
+00456         for (sint i = 0; i < var.size(); i++)
+00457         {
+00458                 log->addNegativeFilter (var.asString(i).c_str());
+00459         }
+00460 }
+00461 
+00462 
+00463 
+00464 
+00465 
+00466 
+00467 
+00468 
+00469 //
+00470 // The main function of the service
+00471 //
+00472 
+00473 sint IService::main (const char *serviceShortName, const char *serviceLongName, uint16 servicePort, const char *configDir, const char *logDir)
+00474 {
+00475         bool userInitCalled = false;
+00476         bool resyncEvenly = false;
+00477         CConfigFile::CVar *var = NULL;
+00478         
+00479         // a short name service can't be a number
+00480         nlassert (atoi(serviceShortName) == 0);
+00481 
+00482         try
+00483         {
+00484                 //
+00485                 // Init parameters
+00486                 //
+00487                 
+00488                 _ConfigDir = CPath::standardizePath(configDir);
+00489                 _LogDir = CPath::standardizePath(logDir);
+00490                 _ShortName = serviceShortName;
+00491                 _LongName = serviceLongName;
+00492 
+00493                 // Set the process name
+00494                 CLog::setProcessName (_ShortName);
+00495 
+00496                 setReportEmailFunction ((void*)sendEmail);
+00497                 setDefaultEmailParams ("gw.nevrax.com", "", "lecroart@nevrax.com");
+00498 
+00499                 // get the path where to run the service if any in the command line
+00500                 if (haveArg('A'))
+00501                 {
+00502                         _RunningPath = CPath::standardizePath(getArg('A'));
+00503 #ifdef NL_OS_WINDOWS
+00504                         _chdir (_RunningPath.c_str());
+00505 #else
+00506                         chdir (_RunningPath.c_str());
+00507 #endif
+00508                 }
+00509 
+00510                 //
+00511                 // Init debug/log stuffs (must be first things otherwise we can't log if errors)
+00512                 //
+00513 
+00514                 // get the log dir if any in the command line
+00515                 if (haveArg('L'))
+00516                         _LogDir = CPath::standardizePath(getArg('L'));
+00517 
+00518                 // get the config file dir if any in the command line
+00519                 if (haveArg('C'))
+00520                         _ConfigDir = CPath::standardizePath(getArg('C'));
+00521 
+00522                 createDebug (_LogDir.c_str(), false);
+00523 
+00524                 //DebugLog->addNegativeFilter ("NETL");
+00525 
+00526                 // we create the log with service name filename ("test_service.log" for example)
+00527                 fd.setParam (_LogDir + _LongName + ".log", false);
+00528 
+00529                 DebugLog->addDisplayer (&fd);
+00530                 InfoLog->addDisplayer (&fd);
+00531                 WarningLog->addDisplayer (&fd);
+00532                 AssertLog->addDisplayer (&fd);
+00533                 ErrorLog->addDisplayer (&fd);
+00534 
+00535 
+00536                 //
+00537                 // Init the hierarchical timer
+00538                 //
+00539 
+00540                 CHTimer::startBench(false, true);
+00541 
+00542 
+00543                 //
+00544                 // Load the config file
+00545                 //
+00546 
+00547                 ConfigFile.load (_ConfigDir + _LongName + ".cfg");
+00548 
+00549 
+00550                 //
+00551                 // Set the negatif filter from the config file
+00552                 //
+00553 
+00554                 if ((var = ConfigFile.getVarPtr ("NegFiltersDebug")) != NULL)
+00555                 {
+00556                         ConfigFile.setCallback ("NegFiltersDebug", cbLogFilter);
+00557                         for (sint i = 0; i < var->size(); i++)
+00558                         {
+00559                                 DebugLog->addNegativeFilter (var->asString(i).c_str());
+00560                         }
+00561                 }
+00562 
+00563                 if ((var = ConfigFile.getVarPtr ("NegFiltersInfo")) != NULL)
+00564                 {
+00565                         ConfigFile.setCallback ("NegFiltersInfo", cbLogFilter);
+00566                         for (sint i = 0; i < var->size(); i++)
+00567                         {
+00568                                 InfoLog->addNegativeFilter (var->asString(i).c_str());
+00569                         }
+00570                 }
+00571 
+00572 
+00573                 //
+00574                 // Create the window if neeeded
+00575                 //
+00576 
+00577                 if ((var = ConfigFile.getVarPtr ("WindowStyle")) != NULL)
+00578                 {
+00579                         string disp = var->asString ();
+00580 #ifdef NL_USE_GTK
+00581                         if (disp == "GTK")
+00582                         {
+00583                                 WindowDisplayer = new CGtkDisplayer ("DEFAULT_WD");
+00584                         }
+00585 #endif // NL_USE_GTK
+00586 
+00587 #ifdef NL_OS_WINDOWS
+00588                         if (disp == "WIN")
+00589                         {
+00590                                 WindowDisplayer = new CWinDisplayer ("DEFAULT_WD");
+00591                         }
+00592 #endif // NL_OS_WINDOWS
+00593 
+00594                         if (WindowDisplayer == NULL && disp != "NONE")
+00595                         {
+00596                                 nlwarning ("Unknown value for the WindowStyle (should be GTK, WIN or NONE), use no window displayer");
+00597                         }
+00598                 }
+00599 
+00600                 vector <pair<string,uint> > displayedVariables;
+00601                 //uint speedNetLabel, speedUsrLabel, rcvLabel, sndLabel, rcvQLabel, sndQLabel, scrollLabel;
+00602                 if (WindowDisplayer != NULL)
+00603                 {
+00604                         //
+00605                         // Init window param if necessary
+00606                         //
+00607 
+00608                         sint x=-1, y=-1, w=-1, h=-1, fs=10;
+00609                         bool iconified = false, ww = false;
+00610                         string fn;
+00611 
+00612                         if ((var = ConfigFile.getVarPtr("XWinParam")) != NULL) x = var->asInt();
+00613                         if ((var = ConfigFile.getVarPtr("YWinParam")) != NULL) y = var->asInt();
+00614                         if ((var = ConfigFile.getVarPtr("WWinParam")) != NULL) w = var->asInt();
+00615                         if ((var = ConfigFile.getVarPtr("HWinParam")) != NULL) h = var->asInt();
+00616                         if ((var = ConfigFile.getVarPtr("HWinParam")) != NULL) iconified = var->asInt() == 1;
+00617                         if ((var = ConfigFile.getVarPtr("FontSize")) != NULL) fs = var->asInt();
+00618                         if ((var = ConfigFile.getVarPtr("FontName")) != NULL) fn = var->asString();
+00619                         if ((var = ConfigFile.getVarPtr("WordWrap")) != NULL) ww = var->asInt() == 1;
+00620                         
+00621                         if (haveArg('I')) iconified = true;
+00622 
+00623                         WindowDisplayer->create (string("*INIT* ") + _ShortName + " " + _LongName, iconified, x, y, w, h, -1, fs, fn, ww);
+00624 
+00625                         DebugLog->addDisplayer (WindowDisplayer);
+00626                         InfoLog->addDisplayer (WindowDisplayer);
+00627                         WarningLog->addDisplayer (WindowDisplayer);
+00628                         ErrorLog->addDisplayer (WindowDisplayer);
+00629                         AssertLog->addDisplayer (WindowDisplayer);
+00630 
+00631                         // adding default displayed variables
+00632                         displayedVariables.push_back(make_pair(string("NetLop|NetSpeedLoop"), WindowDisplayer->createLabel ("NetLop")));
+00633                         displayedVariables.push_back(make_pair(string("UsrLop|UserSpeedLoop"), WindowDisplayer->createLabel ("UsrLop")));
+00634 //                      displayedVariables.push_back(make_pair(string("Rcv|ReceivedBytes"), WindowDisplayer->createLabel ("Rcv")));
+00635 //                      displayedVariables.push_back(make_pair(string("Snd|SentBytes"), WindowDisplayer->createLabel ("Snd")));
+00636 //                      displayedVariables.push_back(make_pair(string("RcvQ|ReceivedQueueSize"), WindowDisplayer->createLabel ("RcvQ")));
+00637 //                      displayedVariables.push_back(make_pair(string("SndQ|SentQueueSize"), WindowDisplayer->createLabel ("SndQ")));
+00638                         displayedVariables.push_back(make_pair(string("|Scroller"), WindowDisplayer->createLabel ("NeL Rulez")));
+00639                         
+00640                         CConfigFile::CVar *v = ConfigFile.getVarPtr("DisplayedVariables");
+00641                         if (v != NULL)
+00642                         {
+00643                                 for (sint i = 0; i < v->size(); i++)
+00644                                 {
+00645                                         displayedVariables.push_back(make_pair(v->asString(i), WindowDisplayer->createLabel (v->asString(i).c_str())));
+00646                                 }
+00647                         }
+00648                 }
+00649 
+00650                 nlinfo ("Starting Service '%s' using NeL ("__DATE__" "__TIME__")", _ShortName.c_str());
+00651 
+00652                 setStatus (EXIT_SUCCESS);
+00653 
+00654                 //
+00655                 // Redirect signal if needed (in release mode only)
+00656                 //
+00657 
+00658 #ifdef NL_OS_WINDOWS
+00659 #ifdef NL_RELEASE
+00660                 initSignal();
+00661 #else
+00662                 // don't install signal is the application is started in debug mode
+00663                 if (IsDebuggerPresent ())
+00664                 {
+00665                         //nlinfo("Running with the debugger, don't redirect signals");
+00666                         initSignal();
+00667                 }
+00668                 else
+00669                 {
+00670                         //nlinfo("Running without the debugger, redirect SIGINT signal");
+00671                         initSignal();
+00672                 }
+00673 #endif
+00674 #else // NL_OS_UNIX
+00675                 initSignal();
+00676 #endif
+00677 
+00678 
+00679                 //
+00680                 // Ignore SIGPIPE (broken pipe) on unix system
+00681                 //
+00682 
+00683 #ifdef NL_OS_UNIX
+00684                 // Ignore the SIGPIPE signal
+00685                 sigset_t SigList;
+00686                 bool IgnoredPipe = true;
+00687                 if (sigemptyset (&SigList) == -1)
+00688                 {
+00689                         perror("sigemptyset()");
+00690                         IgnoredPipe = false;
+00691                 }
+00692 
+00693                 if (sigaddset (&SigList, SIGPIPE) == -1)
+00694                 {
+00695                         perror("sigaddset()");
+00696                         IgnoredPipe = false;
+00697                 }
+00698 
+00699                 if (sigprocmask (SIG_BLOCK, &SigList, NULL) == -1)
+00700                 {
+00701                         perror("sigprocmask()");
+00702                         IgnoredPipe = false;
+00703                 }
+00704                 nldebug ("SIGPIPE %s", IgnoredPipe?"Ignored":"Not Ignored");
+00705 #endif // NL_OS_UNIX
+00706 
+00707 
+00708                 //
+00709                 // Initialize the network system
+00710                 //
+00711                 
+00712                 string localhost;
+00713                 try
+00714                 {
+00715                         // Initialize WSAStartup and network stuffs
+00716                         CSock::initNetwork();
+00717 
+00718                         // Get the localhost name
+00719                         localhost = CInetAddress::localHost().hostName();
+00720                 }
+00721                 catch (NLNET::ESocket &)
+00722                 {
+00723                         localhost = "<UnknownHost>";
+00724                 }
+00725 
+00726                 // Set the localhost name and service name to the logger
+00727                 CLog::setProcessName (localhost+"/"+_ShortName);
+00728 
+00729                 //
+00730                 // Initialize server parameters
+00731                 //
+00732 
+00733                 // Get the port from config file or in the macro (overload the port set by the user init())
+00734                 if ((var = ConfigFile.getVarPtr("Port")) != NULL)
+00735                 {
+00736                         // set the listen port with the value in the config file if any
+00737                         _Port = var->asInt();
+00738                 }
+00739                 else
+00740                 {
+00741                         // set the listen port with the value in the NLNET_SERVICE_MAIN macro
+00742                         _Port = servicePort;
+00743                 }
+00744 
+00745                 // set the listen port if there are a port arg in the command line
+00746                 if (haveArg('P'))
+00747                 {
+00748                         _Port = atoi(getArg('P').c_str());
+00749                 }
+00750 
+00751                 // set the aliasname if is present in the command line
+00752                 if (haveArg('N'))
+00753                 {
+00754                         _AliasName = getArg('N');
+00755                 }
+00756 
+00757                 // Load the recording state from the config file
+00758                 if ((var = ConfigFile.getVarPtr ("Rec")) != NULL)
+00759                 {
+00760                         string srecstate = var->asString();
+00761                         strupr( srecstate );
+00762                         if ( srecstate == "RECORD" )
+00763                         {
+00764                                 _RecordingState = CCallbackNetBase::Record;
+00765                                 nlinfo( "Service recording messages" );
+00766                         }
+00767                         else if ( srecstate == "REPLAY" )
+00768                         {
+00769                                 _RecordingState = CCallbackNetBase::Replay;
+00770                                 nlinfo( "Service replaying messages" );
+00771                         }
+00772                         else
+00773                         {
+00774                                 _RecordingState = CCallbackNetBase::Off;
+00775                         }
+00776                 }
+00777                 else
+00778                 {
+00779                         // Not found
+00780                         _RecordingState = CCallbackNetBase::Off;
+00781                 }
+00782 
+00783                 // Load the default stream format
+00784                 if ((var = ConfigFile.getVarPtr ("StringMsgFormat")) != NULL)
+00785                 {
+00786                         CMessage::setDefaultStringMode( var->asInt() == 1 );
+00787                 }
+00788                 else
+00789                 {
+00790                         // Not found => binary
+00791                         CMessage::setDefaultStringMode( false );
+00792                 }
+00793 
+00794 /*
+00795                 //
+00796                 // Layer4 Startup (Connect to the Naming Service (except for the NS itself and Login Service))
+00797                 //
+00798 
+00799                 if (IService::_ShortName != "NS" && IService::_ShortName != "LS" && IService::_ShortName != "AES" && IService::_ShortName != "AS")
+00800                 {
+00801                         bool ok = false;
+00802                         while (!ok)
+00803                         {
+00804                                 // read the naming service address from the config file
+00805                                 CInetAddress loc(ConfigFile.getVar("NSHost").asString(), ConfigFile.getVar("NSPort").asInt());
+00806                                 try
+00807                                 {
+00808                                         CNetManager::init( &loc, _RecordingState );
+00809                                         ok = true;
+00810                                 }
+00811                                 catch (ESocketConnectionFailed &)
+00812                                 {
+00813                                         nlwarning ("Could not connect to the Naming Service (%s). Retrying in a few seconds...", loc.asString().c_str());
+00814                                         nlSleep (5000);
+00815                                 }
+00816                         }
+00817                 }
+00818                 else
+00819                 {
+00820                         CNetManager::init( NULL, _RecordingState );
+00821                 }
+00822 */
+00823 
+00827 
+00828                 // get the sid
+00829                 if ((var = ConfigFile.getVarPtr ("SId")) != NULL)
+00830                 {
+00831                         sint32 sid = var->asInt();
+00832                         if (sid<=0 || sid>255)
+00833                         {
+00834                                 nlwarning("Bad SId value in the config file, %d is not in [0;255] range", sid);
+00835                                 _SId = 0;
+00836                         }
+00837                         else
+00838                         {
+00839                                 _SId = (uint8) sid;
+00840                         }
+00841                 }
+00842                 else
+00843                 {
+00844                         // ok, SId not found, use dynamic sid
+00845                         _SId = 0;
+00846                 }
+00847 
+00848 
+00849                 // look if we don't want to use NS
+00850                 if ((var = ConfigFile.getVarPtr ("DontUseNS")) != NULL)
+00851                 {
+00852                         // if we set the value in the config file, get it
+00853                         _DontUseNS = (var->asInt() == 1);
+00854                 }
+00855                 else
+00856                 {
+00857                         // if not, we use ns only if service is not ns, ls, aes, as
+00858                         _DontUseNS = false;
+00859                 }
+00860 
+00861                 //
+00862                 // Register all network associations (must be before the CUnifiedNetwork::getInstance()->init)
+00863                 //
+00864 
+00865                 if ((var = ConfigFile.getVarPtr ("Networks")) != NULL)
+00866                 {
+00867                         for (uint8 i = 0; i < var->size (); i++)
+00868                                 CUnifiedNetwork::getInstance()->addNetworkAssociation (var->asString(i), i);
+00869                 }
+00870 
+00871                 if ((var = ConfigFile.getVarPtr ("DefaultNetworks")) != NULL)
+00872                 {
+00873                         for (uint8 i = 0; i < var->size (); i++)
+00874                                 CUnifiedNetwork::getInstance()->addDefaultNetwork(var->asString(i));
+00875                 }
+00876 
+00877                 // normal setup for the common services
+00878                 if (!_DontUseNS)
+00879                 {
+00880                         bool ok = false;
+00881                         while (!ok)
+00882                         {
+00883                                 // read the naming service address from the config file
+00884                                 string LSAddr = ConfigFile.getVar ("NSHost").asString();
+00885                                 
+00886                                 // if there's no port to the NS, use the default one 50000
+00887                                 if (LSAddr.find(":") == string::npos)
+00888                                         LSAddr += ":50000";
+00889 
+00890                                 CInetAddress loc(LSAddr);
+00891                                 try
+00892                                 {
+00893                                         CUnifiedNetwork::getInstance()->init (&loc, _RecordingState, _ShortName, _Port, _SId);
+00894 
+00895                                         ok = true;
+00896                                 }
+00897                                 catch (ESocketConnectionFailed &)
+00898                                 {
+00899                                         nlwarning ("Could not connect to the Naming Service (%s). Retrying in a few seconds...", loc.asString().c_str());
+00900                                         nlSleep (5000);
+00901                                 }
+00902                         }
+00903                 }
+00904                 else
+00905                 {
+00906                         CUnifiedNetwork::getInstance()->init(NULL, _RecordingState, _ShortName, _Port, _SId);
+00907                 }
+00908 
+00909                 // At this point, the _SId must be ok if we use the naming service.
+00910                 // 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
+00911 
+00912                 if(!_DontUseNS)
+00913                 {
+00914                         nlassert (_SId != 0);
+00915                 }
+00916 
+00917                 //
+00918                 // Connect to the local AES and send identification
+00919                 //
+00920 
+00921                 // look if we don't want to use NS
+00922                 if ((var = ConfigFile.getVarPtr ("DontUseAES")) != NULL)
+00923                 {
+00924                         // if we set the value in the config file, get it
+00925                         _DontUseAES = var->asInt() == 1;
+00926                 }
+00927                 else
+00928                 {
+00929                         // if not, we use aes only if service is not aes or as
+00930                         _DontUseAES = false;
+00931                 }
+00932 
+00933                 if (!_DontUseAES)
+00934                 {
+00935                         CUnifiedNetwork::getInstance()->setServiceUpCallback ("AES", AESConnection, NULL);
+00936                         CUnifiedNetwork::getInstance()->setServiceDownCallback ("AES", AESDisconnection, NULL);
+00937                         CUnifiedNetwork::getInstance()->addCallbackArray (AESCallbackArray, sizeof(AESCallbackArray)/sizeof(AESCallbackArray[0]));
+00938                         CUnifiedNetwork::getInstance()->addService ("AES", CInetAddress("localhost:49997"));
+00939                 }
+00940 
+00941 
+00942                 //
+00943                 // Add callback array
+00944                 //
+00945 
+00946                 // add callback set in the NLNET_SERVICE_MAIN macro
+00947                 NLNET::CUnifiedNetwork::getInstance()->addCallbackArray(_CallbackArray, _CallbackArraySize);
+00948 
+00949                 //
+00950                 // Now we have the service id, we can set the entites id generator
+00951                 //
+00952 
+00953                 _NextEntityId.setServiceId(_SId);
+00954 
+00955                 // Set the localhost name and service name and the sid
+00956                 CLog::setProcessName (localhost+"/"+_ShortName+"-"+toString((uint16)_SId));
+00957 
+00958 
+00959                 //
+00960                 // Add default pathes
+00961                 //
+00962 
+00963                 if ((var = ConfigFile.getVarPtr ("Paths")) != NULL)
+00964                 {
+00965                         for (sint i = 0; i < var->size(); i++)
+00966                         {
+00967                                 CPath::addSearchPath (var->asString(i), true, false);
+00968                         }
+00969                 }
+00970 
+00971                 if ((var = ConfigFile.getVarPtr ("PathsNoRecurse")) != NULL)
+00972                 {
+00973                         for (sint i = 0; i < var->size(); i++)
+00974                         {
+00975                                 CPath::addSearchPath (var->asString(i), false, false);
+00976                         }
+00977                 }
+00978 
+00979 
+00980                 // if we can, try to setup where to write files
+00981                 if ((var = ConfigFile.getVarPtr ("WriteFilesDirectory")) != NULL)
+00982                 {
+00983                         WriteFilesDirectory = CPath::standardizePath(var->asString());
+00984                 }
+00985 
+00986 
+00987                 //
+00988                 // Call the user service init
+00989                 //
+00990 
+00991                 userInitCalled = true; // the bool must be put *before* the call to init()
+00992                 init ();
+00993 
+00994 
+00995                 //
+00996                 // Connects to the present services
+00997                 // WARNING: only after the user init() was called because the
+00998                 // addService may call up service callbacks.
+00999                 //
+01000 
+01001                 CUnifiedNetwork::getInstance()->connect();
+01002 
+01003 
+01004                 //
+01005                 // Say to the AES that the service is ready
+01006                 //
+01007 
+01008                 if (!_DontUseAES)
+01009                 {
+01010                         // send the ready message (service init finished)
+01011                         CMessage msgout ("SR");
+01012                         CUnifiedNetwork::getInstance()->send("AES", msgout);
+01013                 }
+01014 
+01015 
+01016                 _Initialized = true;
+01017 
+01018                 nlinfo ("Service initialised, executing StartCommands");
+01019 
+01020                 //
+01021                 // Call the user command from the config file if any
+01022                 //
+01023 
+01024                 if ((var = ConfigFile.getVarPtr ("StartCommands")) != NULL)
+01025                 {
+01026                         for (sint i = 0; i < var->size(); i++)
+01027                         {
+01028                                 ICommand::execute (var->asString(i), *InfoLog);
+01029                         }
+01030                 }
+01031 
+01032                 string str;
+01033                 CLog logDisplayVars;
+01034                 CMemDisplayer mdDisplayVars;
+01035                 logDisplayVars.addDisplayer (&mdDisplayVars);
+01036 
+01037                 nlinfo ("Service ready");
+01038 
+01039                 if (WindowDisplayer != NULL)
+01040                         WindowDisplayer->setTitleBar (_ShortName + " " + _LongName + " " + _Version);
+01041 
+01042                 //
+01043                 // Call the user service update each loop and check files and network activity
+01044                 //
+01045 
+01046                 do
+01047                 {
+01048                         //H_BEFORE(NLNETServiceLoop); // Not tick-wise
+01049                         // count the amount of time to manage internal system
+01050                         TTime bbefore = CTime::getLocalTime ();
+01051 
+01052                         // call the user update and exit if the user update asks it
+01053                         //H_BEFORE(NLNETServiceUpdate);
+01054                         if (!update ())
+01055                         {
+01056                                 //H_AFTER(NLNETServiceLoop); // Not tick-wise
+01057                                 //H_AFTER(NLNETServiceUpdate);
+01058                                 break;
+01059                         }
+01060                         //H_AFTER(NLNETServiceUpdate);
+01061                         
+01062                         // count the amount of time to manage internal system
+01063                         TTime before = CTime::getLocalTime ();
+01064 
+01065                         if (WindowDisplayer != NULL)
+01066                         {
+01067                                 // update the window displayer and quit if asked
+01068                                 if (!WindowDisplayer->update ())
+01069                                 {
+01070                                         nlinfo ("The window displayer was closed by user, need to quit");
+01071                                         ExitSignalAsked = 1;
+01072                                 }
+01073                         }
+01074 
+01075                         // stop the loop if the exit signal asked
+01076                         if (ExitSignalAsked > 0)
+01077                         {
+01078                                 //H_AFTER(NLNETServiceLoop) // Not tick-wise
+01079                                 break;
+01080                         }
+01081         
+01082                         CConfigFile::checkConfigFiles ();
+01083 
+01084                         CFile::checkFileChange();
+01085 
+01086                         //H_BEFORE(NLNETManageMessages); // Not tick-wise
+01087                         // get and manage layer 5 messages
+01088                         CUnifiedNetwork::getInstance()->update (_UpdateTimeout);
+01089                         //H_AFTER(NLNETManageMessages); // Not tick-wise
+01090                         
+01091                         // resync the clock every hours
+01092                         if (resyncEvenly)
+01093                         {
+01094                                 static TTime LastSyncTime = CTime::getLocalTime ();
+01095 
+01096                                 //---------------------------------------
+01097                                 // To simulate Ctrl-C in the debugger... Exit after 1 min !
+01098                                 /*if (CTime::getLocalTime () - LastSyncTime > 60 * 1000 )
+01099                                 {
+01100                                         ExitSignalAsked = 1;
+01101                                 }*/
+01102                                 //---------------------------------------
+01103 /*
+01104                                 if (CTime::getLocalTime () - LastSyncTime > 60*60*1000)
+01105                                 {
+01106                                         CUniTime::syncUniTimeFromService ( _RecordingState );
+01107                                         LastSyncTime = CTime::getLocalTime ();
+01108                                 }
+01109 */
+01110                         }
+01111 
+01112                         NetSpeedLoop = (sint32) (CTime::getLocalTime () - before);
+01113                         UserSpeedLoop = (sint32) (before - bbefore);
+01114 
+01115                         if (WindowDisplayer != NULL)
+01116                         {
+01117                                 uint64 rcv, snd, rcvq, sndq;
+01118                                 rcv = CUnifiedNetwork::getInstance()->getBytesReceived ();
+01119                                 snd = CUnifiedNetwork::getInstance()->getBytesSent ();
+01120                                 rcvq = CUnifiedNetwork::getInstance()->getReceiveQueueSize ();
+01121                                 sndq = CUnifiedNetwork::getInstance()->getSendQueueSize ();
+01122 
+01123                                 for (uint i = 0; i < displayedVariables.size(); i++)
+01124                                 {
+01125                                         // it s a separator, do nothing
+01126                                         if (displayedVariables[i].first.empty())
+01127                                                 continue;
+01128 
+01129                                         // it s a command, do nothing
+01130                                         if (displayedVariables[i].first[0] == '@')
+01131                                                 continue;
+01132 
+01133                                         string dispName = displayedVariables[i].first;
+01134                                         string varName = dispName;
+01135                                         uint32 pos = dispName.find("|");
+01136                                         if (pos != string::npos)
+01137                                         {
+01138                                                 varName = displayedVariables[i].first.substr(pos+1);
+01139                                                 dispName = displayedVariables[i].first.substr(0, pos);
+01140                                         }
+01141 
+01142                                         if (dispName.empty())
+01143                                                 str = "";
+01144                                         else
+01145                                                 str = dispName + ": ";
+01146                                         
+01147                                         mdDisplayVars.clear ();
+01148                                         ICommand::execute(varName, logDisplayVars, true);
+01149                                         const std::deque<std::string>   &strs = mdDisplayVars.lockStrings();
+01150                                         if (strs.size()>0)
+01151                                         {
+01152                                                 
+01153                                                 string s_ = strs[0];
+01154 
+01155                                                 uint32 pos = strs[0].find("=");
+01156                                                 if(pos != string::npos && pos + 2 < strs[0].size())
+01157                                                 {
+01158                                                         uint32 pos2 = string::npos;
+01159                                                         if(strs[0][strs[0].size()-1] == '\n')
+01160                                                                 pos2 = strs[0].size() - pos - 2 - 1;
+01161 
+01162                                                         str += strs[0].substr (pos+2, pos2);
+01163                                                 }
+01164                                                 else
+01165                                                 {
+01166                                                         str += "???";
+01167                                                 }
+01168                                         }
+01169                                         else
+01170                                         {
+01171                                                 str += "???";
+01172                                         }
+01173                                         mdDisplayVars.unlockStrings();
+01174                                         WindowDisplayer->setLabel (displayedVariables[i].second, str);
+01175                                 }
+01176 
+01177                         }
+01178 
+01179 //                      nldebug ("SYNC: updatetimeout must be %d and is %d, sleep the rest of the time", _UpdateTimeout, delta);
+01180                         //H_AFTER(NLNETServiceLoop); // Not tick-wise
+01181 
+01182                         // Resetting the hierarchical timer must be done outside the top-level timer
+01183                         if ( _ResetMeasures )
+01184                         {
+01185                                 CHTimer::clear();
+01186                                 _ResetMeasures = false;
+01187                         }
+01188                         //H_AFTER(NLNETServiceLoop);
+01189                 }
+01190                 while (true);
+01191         }
+01192 /*      catch (ETrapDebug &)
+01193         {
+01194                 // we have to do that if we want to trap unhandled exception with the report message box
+01195                 setStatus (EXIT_FAILURE);
+01196         }
+01197 */      catch (EFatalError &)
+01198         {
+01199                 // Somebody call nlerror, so we have to quit now, the message already display
+01200                 // so we don't have to to anything
+01201                 setStatus (EXIT_FAILURE);
+01202         }
+01203         catch ( uint ) // SEH exceptions
+01204         {
+01205                 ErrorLog->displayNL( "System exception" );
+01206         }
+01207 
+01208 #ifdef NL_RELEASE
+01209 /*      // in release mode, we catch everything to handle clean release.
+01210         catch (Exception &e)
+01211         {
+01212                 // Catch NeL exception to release the system cleanly
+01213                 setStatus (EXIT_FAILURE);
+01214                 nlinfo ("ERROR: NeL Exception: Error running the service \"%s\": %s", _ShortName.c_str(), e.what());
+01215         }
+01216         catch (...)
+01217         {
+01218                 // Catch anything we can to release the system cleanly
+01219                 setStatus (EXIT_FAILURE);
+01220                 nlinfo ("ERROR: Unknown external exception");
+01221         }
+01222 */
+01223 #endif
+01224 
+01225         try
+01226         {
+01227                 nlinfo ("Service starts releasing");
+01228 
+01229                 //
+01230                 // Call the user service release() if the init() was called
+01231                 //
+01232 
+01233                 if (userInitCalled)
+01234                         release ();
+01235 
+01236                 //
+01237                 // Delete all network connection (naming client also)
+01238                 //
+01239 
+01240                 CUnifiedNetwork::getInstance()->release ();
+01241 
+01242                 CSock::releaseNetwork ();
+01243 
+01244                 //
+01245                 // Remove the window displayer
+01246                 //
+01247 
+01248                 if (WindowDisplayer != NULL)
+01249                 {
+01250                         DebugLog->removeDisplayer (WindowDisplayer);
+01251                         InfoLog->removeDisplayer (WindowDisplayer);
+01252                         WarningLog->removeDisplayer (WindowDisplayer);
+01253                         ErrorLog->removeDisplayer (WindowDisplayer);
+01254                         AssertLog->removeDisplayer (WindowDisplayer);
+01255 
+01256                         delete WindowDisplayer;
+01257                         WindowDisplayer = NULL;
+01258                 }
+01259 
+01260                 nlinfo ("Service released succesfuly");
+01261         }
+01262 /*      catch (ETrapDebug &)
+01263         {
+01264                 // we have to do that if we want to trap unhandled exception with the report message box
+01265                 setStatus (EXIT_FAILURE);
+01266         }
+01267 */      catch (EFatalError &)
+01268         {
+01269                 // Somebody call nlerror, so we have to quit now, the message already display
+01270                 // so we don't have to to anything
+01271                 setStatus (EXIT_FAILURE);
+01272         }
+01273 
+01274 #ifdef NL_RELEASE
+01275 /*      // in release mode, we catch everything to handle clean release.
+01276         catch (Exception &e)
+01277         {
+01278                 setStatus (EXIT_FAILURE);
+01279                 nlinfo ("ERROR: NeL Exception: Error releasing the service \"%s\": %s", _ShortName.c_str(), e.what());
+01280         }
+01281         catch (...)
+01282         {
+01283                 // Catch anything we can to release the system cleanly
+01284                 setStatus (EXIT_FAILURE);
+01285                 nlinfo ("ERROR: Unknown external exception");
+01286         }
+01287 */
+01288 #endif
+01289 
+01290         CHTimer::endBench();
+01291         CHTimer::display();
+01292         CHTimer::displayByExecutionPath ();
+01293         CHTimer::displayHierarchical(InfoLog, true, 64);
+01294         CHTimer::displayHierarchicalByExecutionPathSorted (InfoLog, CHTimer::TotalTime, true, 64);
+01295 
+01296         nlinfo ("Service ends");
+01297 
+01298         return ExitSignalAsked?100+ExitSignalAsked:getStatus ();
+01299 }
+01300 
+01301 void IService::exit (sint code)
+01302 {
+01303         nlinfo ("somebody called IService::exit(), I have to quit");
+01304         ExitSignalAsked = code;
+01305 }
+01306 
+01307 /*
+01308  * Require to reset the hierarchical timer
+01309  */
+01310 void IService::requireResetMeasures()
+01311 {
+01312         _ResetMeasures = true;
+01313 }
+01314 
+01315 
+01316 std::string IService::getServiceUnifiedName () const
+01317 {
+01318         nlassert (!_ShortName.empty())
+01319                 string res;
+01320         if (!_AliasName.empty())
+01321         {
+01322                 res = _AliasName+"/";
+01323         }
+01324         res += _ShortName;
+01325         if (_SId != 0)
+01326         {
+01327                 res += "-";
+01328                 res += toString (_SId);
+01329         }
+01330         return res;
+01331 }
+01332 
+01333 
+01334 
+01335 //
+01336 // Commands and Variables for controling all services
+01337 //
+01338 
+01339 NLMISC_VARIABLE(sint32, NetSpeedLoop, "duration of the last network loop (in ms)");
+01340 NLMISC_VARIABLE(sint32, UserSpeedLoop, "duration of the last user loop (in ms)");
+01341 
+01342 NLMISC_DYNVARIABLE(uint64, ReceivedBytes, "total of bytes received by this service")
+01343 {
+01344         // we can only read the value
+01345         if (get)
+01346                 *pointer = CUnifiedNetwork::getInstance()->getBytesReceived ();
+01347 }
+01348 
+01349 NLMISC_DYNVARIABLE(uint64, SentBytes, "total of bytes sent by this service")
+01350 {
+01351         // we can only read the value
+01352         if (get)
+01353                 *pointer = CUnifiedNetwork::getInstance()->getBytesSent ();
+01354 }
+01355 
+01356 NLMISC_DYNVARIABLE(uint64, ReceivedQueueSize, "current size in bytes of the received queue size")
+01357 {
+01358         // we can only read the value
+01359         if (get)
+01360                 *pointer = CUnifiedNetwork::getInstance()->getReceiveQueueSize ();
+01361 }
+01362 
+01363 NLMISC_DYNVARIABLE(uint64, SentQueueSize, "current size in bytes of the sent queue size")
+01364 {
+01365         // we can only read the value
+01366         if (get)
+01367                 *pointer = CUnifiedNetwork::getInstance()->getSendQueueSize ();
+01368 }
+01369 
+01370 NLMISC_DYNVARIABLE(string, Scroller, "current size in bytes of the sent queue size")
+01371 {
+01372         if (get)
+01373         {
+01374                 // display the scroll text
+01375                 static string foo =     "Welcome to NeL Service! This scroll is used to see the update frequency of the main function and to see if the service is frozen or not. Have a nice day and hope you'll like NeL!!! "
+01376                                                         "Welcome to NeL Service! This scroll is used to see the update frequency of the main function and to see if the service is frozen or not. Have a nice day and hope you'll like NeL!!! ";
+01377                 static int pos = 0;
+01378                 *pointer = foo.substr ((pos++)%(foo.size()/2), 10);
+01379         }
+01380 }
+01381 
+01382 NLMISC_COMMAND (quit, "exit the service", "")
+01383 {
+01384         if(args.size() != 0) return false;
+01385 
+01386         nlinfo ("User ask me with a command to quit");
+01387         ExitSignalAsked = 0xFFFF;
+01388 
+01389         return true;
+01390 }
+01391 
+01392 NLMISC_COMMAND (brutalQuit, "exit the service brutally", "")
+01393 {
+01394         if(args.size() != 0) return false;
+01395 
+01396         ::exit (0xFFFFFFFF);
+01397 
+01398         return true;
+01399 }
+01400 
+01401 
+01402 #ifdef MUTEX_DEBUG
+01403 NLMISC_COMMAND (mutex, "display mutex values", "")
+01404 {
+01405         if(args.size() != 0) return false;
+01406 
+01407         map<CFairMutex*,TMutexLocks>    acquiretimes = getNewAcquireTimes();
+01408 
+01409         map<CFairMutex*,TMutexLocks>::iterator im;
+01410         for ( im=acquiretimes.begin(); im!=acquiretimes.end(); ++im )
+01411         {
+01412                 nlinfo( "%d %p %s: %.0f %.0f, called %u times th(%d, %d wait)%s", (*im).second.MutexNum, (*im).first, (*im).second.MutexName.c_str(),
+01413                         CTime::cpuCycleToSecond((*im).second.TimeToEnter)*1000.0, CTime::cpuCycleToSecond((*im).second.TimeInMutex)*1000.0,
+01414                         (*im).second.Nb, (*im).second.ThreadHavingTheMutex, (*im).second.WaitingMutex,
+01415                         (*im).second.Dead?" DEAD":"");
+01416         }
+01417 
+01418         return true;
+01419 }
+01420 #endif // MUTEX_DEBUG
+01421 
+01422 NLMISC_COMMAND (serviceInfo, "display information about this service", "")
+01423 {
+01424         if(args.size() != 0) return false;
+01425 
+01426         log.displayNL ("Service %s '%s' using NeL ("__DATE__" "__TIME__")", IService::getInstance()->getServiceLongName().c_str(), IService::getInstance()->getServiceUnifiedName().c_str());
+01427         log.displayNL ("Service listening port: %d", IService::getInstance()->_Port);
+01428         log.displayNL ("Service running directory: '%s'", IService::getInstance()->_RunningPath.c_str());
+01429         log.displayNL ("Service log directory: '%s'", IService::getInstance()->_LogDir.c_str());
+01430         log.displayNL ("Service config directory: '%s' config filename: '%s.cfg'", IService::getInstance()->_ConfigDir.c_str(), IService::getInstance()->_LongName.c_str());
+01431         log.displayNL ("Service id: %d", IService::getInstance()->_SId);
+01432         log.displayNL ("Service update timeout: %dms", IService::getInstance()->_UpdateTimeout);
+01433         log.displayNL ("Service %suse naming service", IService::getInstance()->_DontUseNS?"don't ":"");
+01434         log.displayNL ("Service %suse admin executor service", IService::getInstance()->_DontUseAES?"don't ":"");
+01435 #ifdef NL_RELEASE_DEBUG
+01436         string mode = "NL_RELEASE_DEBUG";
+01437 #elif defined(NL_DEBUG_FAST)
+01438         string mode = "NL_DEBUG_FAST";
+01439 #elif defined(NL_DEBUG)
+01440         string mode = "NL_DEBUG";
+01441 #elif defined(NL_RELEASE)
+01442         string mode = "NL_RELEASE";
+01443 #else
+01444         string mode = "???";
+01445 #endif
+01446         log.displayNL ("NeL is compiled in %s mode", mode.c_str());
+01447 
+01448         nlinfo ("Services arguments: %d args", IService::getInstance()->_Args.size ());
+01449         for (uint i = 0; i < IService::getInstance()->_Args.size (); i++)
+01450         {
+01451                 nlinfo ("  argv[%d] = '%s'", i, IService::getInstance()->_Args[i].c_str ());
+01452         }
+01453 
+01454         log.displayNL ("Naming service info: %s", CNamingClient::info().c_str());
+01455 
+01456         ICommand::execute ("services", log);
+01457 
+01458         return true;
+01459 }
+01460 
+01461 NLMISC_COMMAND(resetMeasures, "reset hierarchical timer", "")
+01462 {
+01463         IService::getInstance()->requireResetMeasures();
+01464         return true;
+01465 }
+01466 
+01467 NLMISC_COMMAND(displayMeasures, "display hierarchical timer", "")
+01468 {
+01469         CHTimer::display();
+01470         CHTimer::displayHierarchicalByExecutionPathSorted (InfoLog, CHTimer::TotalTime, true, 64);
+01471         return true;
+01472 }
+01473 
+01474 NLMISC_COMMAND(getWinDisplayerInfo, "display the info about the pos and size of the window displayer", "")
+01475 {
+01476         uint32 x,y,w,h;
+01477         IService::getInstance()->WindowDisplayer->getWindowPos (x,y,w,h);
+01478         log.displayNL ("Window Displayer : XWinParam = %d; YWinParam = %d; WWinParam = %d; HWinParam = %d;", x, y, w, h);
+01479         return true;
+01480 }
+01481 
+01482 NLMISC_COMMAND(printConfigFile, "display the variables of the default configfile", "")
+01483 {
+01484         IService::getInstance()->ConfigFile.print(&log);
+01485         return true;
+01486 }
+01487 
+01488 NLMISC_COMMAND(getUnknownConfigFileVariables, "display the variables from config file that are called but not present", "")
+01489 {
+01490         log.displayNL ("%d Variables not found in the configfile '%s'", IService::getInstance()->ConfigFile.UnknownVariables.size(), IService::getInstance()->ConfigFile.getFilename().c_str() );
+01491         for (uint i = 0; i < IService::getInstance()->ConfigFile.UnknownVariables.size(); i++)
+01492         {
+01493                 log.displayNL ("  %s", IService::getInstance()->ConfigFile.UnknownVariables[i].c_str());
+01494         }
+01495         return true;
+01496 }
+01497 
+01498 NLMISC_COMMAND (freeze, "Freeze the service for N seconds (for debug purpose)", "<N>")
+01499 {
+01500         if(args.size() != 1) return false;
+01501 
+01502         sint32 n = atoi (args[0].c_str());
+01503 
+01504         log.displayNL ("Freezing %d seconds", n);
+01505 
+01506         nlSleep(n * 1000);      
+01507         return true;
+01508 }
+01509 
+01510 uint32 foo = 7777, bar = 6666;
+01511 
+01512 NLMISC_VARIABLE(uint32, foo, "test the get view system");
+01513 NLMISC_VARIABLE(uint32, bar, "test the get view system");
+01514 
+01515 
+01516 // -1 = service is quitting
+01517 // 0 = service is not connected
+01518 // 1 = service is running
+01519 // 2 = service is launching
+01520 // 3 = service failed launching
+01521 
+01522 NLMISC_DYNVARIABLE(string, State, "Set this value to 0 to shutdown the service and 1 to start the service")
+01523 {
+01524         static string running = "Online";
+01525 
+01526         // read or write the variable
+01527         if (get)
+01528         {
+01529                 *pointer = running;
+01530         }
+01531         else
+01532         {
+01533                 if (IService::getInstance()->getServiceShortName() == "AES" || IService::getInstance()->getServiceShortName() == "AS")
+01534                 {
+01535                         nlinfo ("I can't set State=0 because I'm the admin and I should never quit");
+01536                 }
+01537                 else if (*pointer == "0")
+01538                 {
+01539                         // ok, we want to set the value to false, just quit
+01540                         nlinfo ("User ask me with a command to quit using the State variable");
+01541                         ExitSignalAsked = 0xFFFE;
+01542                         running = "Quitting";
+01543                 }
+01544                 else
+01545                 {
+01546                         nlwarning ("Unknown value for State '%s'", (*pointer).c_str());
+01547                 }
+01548         }
+01549 }
+01550 
+01551 
+01552 } //NLNET
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1