1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
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.
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
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
)();
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
42 class CModuleManager
: public NLMISC::IRunnable
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
61 /// Run on an independent thread
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)
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
97 volatile bool _StopThread
;
98 volatile bool _ThreadStopped
;
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!");}
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();
132 CModuleManager(const char *name
= NULL
, bool independent
= false);
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
148 /// Run the execution stack only once
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.
164 static void resetCycle();
167 static bool allReady();
170 static bool allComplete();
173 static bool allStopped();
194 //nldebug("FEMMAN: [%s] waiting for all modules to increase cycle", _StackName.c_str());
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().
212 void waitAllComplete()
214 //nldebug("FEMMAN: [%s] waiting for all modules to restart cycle", _StackName.c_str());
215 while (!allComplete())
218 /* Warning (Windows platform) about sleep(0): see waitAllReady().
224 #endif // NL_MODULE_MANAGER_H
226 /* End of module_manager.h */