Add infos into target window
[ryzomcore.git] / ryzom / server / src / frontend_service / module_manager.h
blob60d7db8511b13bd4e40a0231e5661163e393544c
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #ifndef NL_MODULE_MANAGER_H
20 #define NL_MODULE_MANAGER_H
22 #include <vector>
23 #include <string>
25 #include "nel/misc/types_nl.h"
26 #include "nel/misc/time_nl.h"
27 #include "nel/misc/mutex.h"
28 #include "nel/misc/thread.h"
29 #include "nel/misc/debug.h"
32 typedef void (*TModuleExecCallback)();
34 /**
35 * A simple function call stacker
36 * \warning When there are several module, the Windows Task Manager shows the service taking
37 * 100% of CPU but it remains nice to other programs. See waitAllReady() for more information.
38 * \author Benjamin Legros
39 * \author Nevrax France
40 * \date 2001
42 class CModuleManager : public NLMISC::IRunnable
44 private:
45 /// The maximum number of modules
46 static uint _MaxModules;
48 /// The mutexes associated to each module
49 static NLMISC::CMutex *_ModMutexes;
51 /// The managers currently used
52 static std::vector<CModuleManager*> _RegisteredManagers;
55 /// The name (for display) of this manager
56 std::string _StackName;
58 /// The Id of the manager
59 uint _Id;
61 /// Run on an independent thread
62 bool _Independent;
64 /// The current cycle (same for all managers, used for synchro.)
65 volatile uint64 _Cycle;
67 /// Complete coutner (used for synchro, as cycle restart.)
68 volatile uint64 _CompleteCycle;
70 /// The type of an item (module or wait)
71 enum TExecutionType
73 Module = 0,
74 Wait
77 /// An execution item
78 struct CExecutionItem
80 TExecutionType Type;
81 uint Id;
82 TModuleExecCallback Cb;
85 /// The stack of execution items
86 std::vector<CExecutionItem> _ExecutionStack;
88 /// The list of modules per manager
89 std::vector<uint> _ExecutedModules;
92 /// The thread associated to this manager
93 NLMISC::IThread *_Thread;
95 /// @name The stop flags
96 //@{
97 volatile bool _StopThread;
98 volatile bool _ThreadStopped;
99 //@}
101 private:
102 /// Constructor. WARNING, never create module manager from another manager !!
103 CModuleManager(const CModuleManager &mod) { nlerror("FEMMAN: forbidden constructor used!"); }
105 /// WARNING, never initialize module manager from another manager !!
106 CModuleManager & operator = (const CModuleManager &mod) { nlerror("FEMMAN: forbidden operator = used!");}
108 public:
110 /// Inits the whole manager structure, and setup the maximum number of usable modules
111 static void init(uint maxModules);
113 /// Releases the whole manager structure.
114 static void release();
119 /// Starts all managers at the same time
120 static void startAll();
122 /// Stop all managers before timeout (if can't, the threads are hard terminated.)
123 static void stopAll(NLMISC::TTime timeout = 2000);
125 /// Resets the whole managers list
126 static void resetManagers();
131 /// Constructor
132 CModuleManager(const char *name = NULL, bool independent = false);
134 /// Destructor
135 ~CModuleManager();
138 /// Adds a new module to this manager (id must be unique.)
139 void addModule(uint id, TModuleExecCallback cb);
141 /// Adds a wait for a module (id doesn't have to be unique.)
142 void addWait(uint id);
145 /// Starts the manager loop, independantly from the other managers
146 void start();
148 /// Run the execution stack only once
149 void runOnce();
151 /** Stops the manager loop
152 * \param blockingMode if set, the stop will wait for timeout before terminating the thread.
154 void stop(bool blockingMode=true, NLMISC::TTime timeout = 2000);
158 /// The run() method from the runnable interface. Not to be called it.
159 virtual void run();
161 private:
164 static void resetCycle();
167 static bool allReady();
170 static bool allComplete();
173 static bool allStopped();
178 void executeStack();
181 void enterMutexes();
185 void stepCycle()
187 ++_Cycle;
192 void waitAllReady()
194 //nldebug("FEMMAN: [%s] waiting for all modules to increase cycle", _StackName.c_str());
195 while (!allReady())
196 NLMISC::nlSleep(0);
198 /* Warning (Windows platform): this sleep(0) will make the service show 100% of CPU in the
199 * Windows task manager. In fact, if there is idle time, the sleep(0) makes the system give
200 * the CPU back to the same service. This service is still nice to other programs.
201 * See also waitAllComplete().
206 void completeCycle()
208 ++_CompleteCycle;
212 void waitAllComplete()
214 //nldebug("FEMMAN: [%s] waiting for all modules to restart cycle", _StackName.c_str());
215 while (!allComplete())
216 NLMISC::nlSleep(0);
218 /* Warning (Windows platform) about sleep(0): see waitAllReady().
224 #endif // NL_MODULE_MANAGER_H
226 /* End of module_manager.h */