From b74c3cc9fa8af3dfec6d733a50679b444625279b Mon Sep 17 00:00:00 2001 From: kaetemi Date: Tue, 10 Jun 2014 20:19:29 +0200 Subject: [PATCH] SDL2: Replace thread implementation --HG-- branch : sdl2 --- .../include/nel/misc/inter_window_msg_queue.h | 2 +- code/nel/include/nel/misc/p_thread.h | 97 --- code/nel/include/nel/misc/system_info.h | 4 + code/nel/include/nel/misc/task_manager.h | 2 +- code/nel/include/nel/misc/thread.h | 118 +--- code/nel/include/nel/misc/time_nl.h | 2 - .../nel/misc/timeout_assertion_thread.h | 2 +- code/nel/include/nel/misc/win_thread.h | 145 ----- code/nel/include/nel/misc/window_displayer.h | 2 +- code/nel/include/nel/net/buf_client.h | 2 +- code/nel/include/nel/net/buf_server.h | 6 +- .../include/nel/sound/stream_file_source.h | 2 +- code/nel/src/3d/zone_lighter.cpp | 68 +- code/nel/src/georges/header.cpp | 2 +- code/nel/src/misc/co_task.cpp | 4 +- code/nel/src/misc/inter_window_msg_queue.cpp | 2 +- code/nel/src/misc/p_thread.cpp | 387 ----------- code/nel/src/misc/system_info.cpp | 5 + code/nel/src/misc/task_manager.cpp | 2 +- code/nel/src/misc/thread.cpp | 105 +++ code/nel/src/misc/time_nl.cpp | 129 ---- code/nel/src/misc/win_thread.cpp | 609 ------------------ code/nel/src/misc/window_displayer.cpp | 2 +- code/nel/src/net/buf_client.cpp | 2 +- code/nel/src/net/buf_server.cpp | 4 +- code/nel/src/net/service.cpp | 4 +- code/nel/src/net/stdin_monitor_thread.cpp | 6 +- code/nel/src/net/unified_network.cpp | 4 +- code/nel/src/sound/stream_file_source.cpp | 6 +- .../admin_executor_service/log_report.cpp | 2 +- .../nelns/admin_executor_service/log_report.h | 2 +- .../ryzom/client/src/bg_downloader_access.cpp | 5 +- code/ryzom/client/src/init.cpp | 34 +- code/ryzom/client/src/init_main_loop.cpp | 2 +- .../src/interface_v3/group_html_webig.cpp | 2 +- code/ryzom/client/src/login.cpp | 2 +- code/ryzom/client/src/login_patch.cpp | 10 +- code/ryzom/client/src/login_patch.h | 4 +- .../client/src/login_progress_post_thread.cpp | 2 +- .../client/src/login_progress_post_thread.h | 2 +- code/ryzom/client/src/session_browser.cpp | 2 +- code/ryzom/client/src/session_browser.h | 2 +- .../src/entities_game_service/admin.cpp | 2 +- .../phrase_manager/fg_prospection_phrase.cpp | 4 +- .../src/frontend_service/fe_receive_sub.cpp | 2 +- .../src/frontend_service/fe_receive_sub.h | 2 +- .../src/frontend_service/frontend_service.cpp | 4 +- .../src/frontend_service/module_manager.cpp | 6 +- .../src/frontend_service/module_manager.h | 2 +- .../stdin_monitor_thread.cpp | 6 +- .../log_analyser_service.cpp | 2 +- .../log_analyser_service.h | 2 +- .../src/logger_service/logger_service.cpp | 4 +- .../reference_builder_service.cpp | 2 +- .../reference_builder_service.h | 2 +- 55 files changed, 222 insertions(+), 1614 deletions(-) delete mode 100644 code/nel/include/nel/misc/p_thread.h delete mode 100644 code/nel/include/nel/misc/win_thread.h delete mode 100644 code/nel/src/misc/p_thread.cpp create mode 100644 code/nel/src/misc/thread.cpp delete mode 100644 code/nel/src/misc/win_thread.cpp diff --git a/code/nel/include/nel/misc/inter_window_msg_queue.h b/code/nel/include/nel/misc/inter_window_msg_queue.h index f65767bce..97b96d3c5 100644 --- a/code/nel/include/nel/misc/inter_window_msg_queue.h +++ b/code/nel/include/nel/misc/inter_window_msg_queue.h @@ -177,7 +177,7 @@ private: CProtagonist _LocalWindow; CProtagonist _ForeignWindow; CSendTask *_SendTask; - IThread *_SendThread; + CThread *_SendThread; static const uint _CurrentVersion; // for messages serialisation diff --git a/code/nel/include/nel/misc/p_thread.h b/code/nel/include/nel/misc/p_thread.h deleted file mode 100644 index 4f0a9aa63..000000000 --- a/code/nel/include/nel/misc/p_thread.h +++ /dev/null @@ -1,97 +0,0 @@ -// NeL - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#ifndef NL_P_THREAD_H -#define NL_P_THREAD_H - -#include "types_nl.h" - -#ifdef NL_OS_UNIX - -#include "thread.h" -#include - - -namespace NLMISC { - - -/** - * Posix Thread - * \author Olivier Cado - * \author Nevrax France - * \date 2001 - */ -class CPThread : public IThread -{ -public: - enum TThreadState - { - ThreadStateNone, - ThreadStateRunning, - ThreadStateFinished, - }; - - /// Constructor - CPThread( IRunnable *runnable, uint32 stackSize); - - virtual ~CPThread(); - - virtual void start(); - virtual bool isRunning(); - virtual void terminate(); - virtual void wait(); - virtual bool setCPUMask(uint64 cpuMask); - virtual uint64 getCPUMask(); - virtual void setPriority(TThreadPriority priority); - virtual std::string getUserName(); - - virtual IRunnable *getRunnable() - { - return Runnable; - } - - /// Internal use - IRunnable *Runnable; - - TThreadState _State; - pthread_t _ThreadHandle; - -private: - uint32 _StackSize; -}; - -/** - * Posix Process - * \author Cyril 'Hulud' Corvazier - * \author Nevrax France - * \date 2001 - */ -class CPProcess : public IProcess -{ -public: - virtual ~CPProcess() {} - virtual uint64 getCPUMask(); - virtual bool setCPUMask(uint64 mask); -}; - -} // NLMISC - - -#endif // NL_OS_UNIX - -#endif // NL_P_THREAD_H - -/* End of p_thread.h */ diff --git a/code/nel/include/nel/misc/system_info.h b/code/nel/include/nel/misc/system_info.h index 264b02ddf..ef4a32a09 100644 --- a/code/nel/include/nel/misc/system_info.h +++ b/code/nel/include/nel/misc/system_info.h @@ -65,6 +65,10 @@ public: */ static bool isNT(); + /** Return number of CPU cores + */ + static uint getCPUCount(); + /** Returns the space left on the hard drive that contains the filename */ static std::string availableHDSpace (const std::string &filename); diff --git a/code/nel/include/nel/misc/task_manager.h b/code/nel/include/nel/misc/task_manager.h index 15b3eef0b..e826dfa01 100644 --- a/code/nel/include/nel/misc/task_manager.h +++ b/code/nel/include/nel/misc/task_manager.h @@ -144,7 +144,7 @@ protected: CSynchronized > _DoneTaskQueue; /// thread pointer - IThread *_Thread; + CThread *_Thread; /// flag indicate thread loop, if false cause thread exit volatile bool _ThreadRunning; diff --git a/code/nel/include/nel/misc/thread.h b/code/nel/include/nel/misc/thread.h index e2dfcc3c7..aa87565ed 100644 --- a/code/nel/include/nel/misc/thread.h +++ b/code/nel/include/nel/misc/thread.h @@ -19,11 +19,12 @@ #include "types_nl.h" #include "common.h" +#include "mutex.h" +struct SDL_Thread; namespace NLMISC { - /** * Thread callback interface. * When a thread is created, it will call run() in its attached IRunnable interface. @@ -41,7 +42,7 @@ namespace NLMISC { }; - IThread *thread = IThread::create (new HelloLoopThread); + CThread *thread = new CThread (new HelloLoopThread); thread->start (); *\endcode @@ -62,7 +63,7 @@ public: { } // Return the runnable name - virtual void getName (std::string &result) const + virtual void getName(std::string &result) const { result = "NoName"; } @@ -71,74 +72,48 @@ public: /// Thread priorities, numbering follows Win32 for now enum TThreadPriority { - ThreadPriorityLowest = -2, - ThreadPriorityLow = -1, - ThreadPriorityNormal = 0, - ThreadPriorityHigh = 1, - ThreadPriorityHighest = 2, + ThreadPriorityLow, + ThreadPriorityNormal, + ThreadPriorityHigh }; /** - * Thread base interface, must be implemented for all OS - * \author Vianney Lecroart - * \author Nevrax France - * \date 2000 + * Interface to SDL2 threads + * \date 2014 */ -class IThread +class CThread { public: + CThread(IRunnable *runnable); - /** - * Create a new thread. - * Implemented in the derived class. - */ - static IThread *create(IRunnable *runnable, uint32 stackSize = 0); - - /** - * Return a pointer on the current thread. - * Implemented in the derived class. - */ - static IThread *getCurrentThread (); - - virtual ~IThread () { } + // Thread will be detached immediately and remain running. + ~CThread(); // Starts the thread. - virtual void start()=0; + void start(); // Check if the thread is still running - virtual bool isRunning() =0; + bool isRunning(); - // Terminate the thread (risky method, use only in extreme cases) - virtual void terminate()=0; - - // In the calling program, wait until the specified thread has exited. After wait() has returned, you can delete the thread object. - virtual void wait()=0; + /// In the calling program, wait until the specified thread has exited. + int wait(); /// Return a pointer to the runnable object - virtual IRunnable *getRunnable()=0; - - /** - * Set the CPU mask of this thread. Thread must have been started before. - * The mask must be a subset of the CPU mask returned by IProcess::getCPUMask() thread process. - */ - virtual bool setCPUMask(uint64 cpuMask)=0; - - /** - * Get the CPU mask of this thread. Thread must have been started before. - * The mask should be a subset of the CPU mask returned by IProcess::getCPUMask() thread process. - */ - virtual uint64 getCPUMask()=0; - - /// Set the thread priority. Thread must have been started before. - virtual void setPriority(TThreadPriority priority) = 0; - - /** - * Get the thread user name. - * Under Linux return thread owner, under windows return the name of the logon user. - */ - virtual std::string getUserName()=0; -}; + IRunnable *getRunnable(); + + /// Set the priority for the current thread. + static void setPriority(TThreadPriority priority); +private: + static int run(void *ptr); + + volatile bool m_IsRunning; + SDL_Thread *m_SDLThread; + IRunnable *m_Runnable; + CMutex m_WaitMutex; // Mutex to allow multiple threads to wait for one thread + int m_ThreadResult; // Result from last thread run + +}; /* * Thread exception @@ -148,39 +123,8 @@ struct EThread : public Exception EThread (const char* message) : Exception (message) {} }; - -/** - * Process base interface, must be implemented for all OS - * \author Cyril 'Hulud' Corvazier - * \author Nevrax France - * \date 2000 - */ -class IProcess -{ -public: - virtual ~IProcess() {} - - /** - * Return a pointer on the current process. - * Implemented in the derived class. - */ - static IProcess *getCurrentProcess (); - - /** - * Return process CPU mask. Each bit stand for a CPU usable by the process threads. - */ - virtual uint64 getCPUMask()=0; - - /** - * Set the process CPU mask. Each bit stand for a CPU usable by the process threads. - */ - virtual bool setCPUMask(uint64 mask)=0; -}; - - } // NLMISC - #endif // NL_THREAD_H /* End of thread.h */ diff --git a/code/nel/include/nel/misc/time_nl.h b/code/nel/include/nel/misc/time_nl.h index e7deaae24..9b82bdaac 100644 --- a/code/nel/include/nel/misc/time_nl.h +++ b/code/nel/include/nel/misc/time_nl.h @@ -52,8 +52,6 @@ public: { /// Returns if there is a high precision timer that can be used. bool IsHighPrecisionAvailable; - /// If a CPU specific timer is used and the values are not consistent accross threads. - bool RequiresSingleCore; /// The resolution of the high resolution timer. TTicks HighPrecisionResolution; }; diff --git a/code/nel/include/nel/misc/timeout_assertion_thread.h b/code/nel/include/nel/misc/timeout_assertion_thread.h index 1d329ed2b..f445bd6ab 100644 --- a/code/nel/include/nel/misc/timeout_assertion_thread.h +++ b/code/nel/include/nel/misc/timeout_assertion_thread.h @@ -28,7 +28,7 @@ // in init CTimeoutAssertionThread *myTAT = new CTimeoutAssertionThread(1000); - IThread::create(myTAT)->start(); + new CThread(myTAT)->start(); ... diff --git a/code/nel/include/nel/misc/win_thread.h b/code/nel/include/nel/misc/win_thread.h deleted file mode 100644 index 1ba122126..000000000 --- a/code/nel/include/nel/misc/win_thread.h +++ /dev/null @@ -1,145 +0,0 @@ -// NeL - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#ifndef NL_WIN_THREAD_H -#define NL_WIN_THREAD_H - -#include "types_nl.h" -#include "thread.h" - -#ifdef NL_OS_WINDOWS - -namespace NLMISC { - - -/** - * Windows implementation of CThread class (look thread.h) - * \author Vianney Lecroart - * \author Nevrax France - * \date 2000 - */ -class CWinThread : public IThread -{ -public: - - /// Constructor - CWinThread(IRunnable *runnable, uint32 stackSize); - - /// Don't use this constructor, only used to initialise the main thread class - CWinThread (void* threadHandle, uint32 threadId); - - virtual ~CWinThread(); - - virtual void start(); - virtual bool isRunning(); - virtual void terminate(); - virtual void wait(); - virtual bool setCPUMask(uint64 cpuMask); - virtual uint64 getCPUMask(); - virtual void setPriority(TThreadPriority priority); - virtual std::string getUserName(); - - virtual IRunnable *getRunnable() - { - return Runnable; - } - - // Win32 specific - // Get the suspend count. Will be -1 is the thread hasn't been started yet - int getSuspendCount() const { return _SuspendCount; } - // Increment the suspend count, a suspend count >= 1 means the thread is suspended - void incSuspendCount(); - /** Descrement the suspend count. Reaching 0 will resume the thread - * An assertion is raised is the suspend count is already 0 - */ - void decSuspendCount(); - // Suspend the thread. No-op if already suspended - void suspend(); - // Resume the thread. No-op if already resumed - void resume(); - // Priority boost - void enablePriorityBoost(bool enabled); - - /// private use - IRunnable *Runnable; - -private: - int _SuspendCount; - uint32 _StackSize; - void *ThreadHandle; // HANDLE don't put it to avoid including windows.h - uint32 ThreadId; // DWORD don't put it to avoid including windows.h - bool _MainThread; // true if ths thread is the main thread, else false -}; - -/** - * Windows Process - * \author Cyril 'Hulud' Corvazier - * \author Nicolas Vizerie - * \author Nevrax France - * \date 2001, 2007 - */ -class CWinProcess : public IProcess -{ -public: - - CWinProcess (void *handle); - virtual ~CWinProcess() {} // TODO do something with _ProcessHandle? - - virtual uint64 getCPUMask(); - virtual bool setCPUMask(uint64 mask); - - // processes helpers - static bool enumProcessesId(std::vector &processesId); - // get fully qualified path for all modules used by a given process - static bool enumProcessModules(uint32 processId, std::vector &moduleNames); - static uint32 getProcessIdFromModuleFilename(const std::string &moduleFileName); - static bool terminateProcess(uint32 processId, uint exitCode = 0); - static bool terminateProcessFromModuleName(const std::string &moduleName, uint exitCode = 0); - -private: - void *_ProcessHandle; -}; - - - -/* -// I didn't use and test that code, enventually, but maybe useful in the future -// -// Utility class to launch a process and check if it is still running. -// Implemented under windows only for now -// -class CProcessWatch -{ -public: - CProcessWatch(); - ~CProcessWatch(); - // launch a process with the given name and arguments, return true on success - bool launch(const std::string &programName, const std::string &arguments); - // return true if the process is still runing - bool isRunning() const; -private: - class CProcessWatchImpl *_PImpl; -}; - -*/ - -} // NLMISC - -#endif // NL_OS_WINDOWS - -#endif // NL_WIN_THREAD_H - -/* End of win_thread.h */ diff --git a/code/nel/include/nel/misc/window_displayer.h b/code/nel/include/nel/misc/window_displayer.h index de05b25d5..21e2af413 100644 --- a/code/nel/include/nel/misc/window_displayer.h +++ b/code/nel/include/nel/misc/window_displayer.h @@ -103,7 +103,7 @@ protected: sint _InputEditHeight; // the thread used to update the display - NLMISC::IThread *_Thread; + NLMISC::CThread *_Thread; CLog *Log; diff --git a/code/nel/include/nel/net/buf_client.h b/code/nel/include/nel/net/buf_client.h index a540f78d9..44fbff564 100644 --- a/code/nel/include/nel/net/buf_client.h +++ b/code/nel/include/nel/net/buf_client.h @@ -235,7 +235,7 @@ private: CClientReceiveTask *_RecvTask; /// Receive thread - NLMISC::IThread *_RecvThread; + NLMISC::CThread *_RecvThread; }; diff --git a/code/nel/include/nel/net/buf_server.h b/code/nel/include/nel/net/buf_server.h index 70c56d2c8..cd710d902 100644 --- a/code/nel/include/nel/net/buf_server.h +++ b/code/nel/include/nel/net/buf_server.h @@ -105,7 +105,7 @@ private: }; -typedef std::vector CThreadPool; +typedef std::vector CThreadPool; // Mode: Small server @@ -290,7 +290,7 @@ protected: void dispatchNewSocket( CServerBufSock *bufsock ); /// Returns the receive task corresponding to a particular thread - CServerReceiveTask *receiveTask( std::vector::iterator ipt ) + CServerReceiveTask *receiveTask( std::vector::iterator ipt ) { return ((CServerReceiveTask*)((*ipt)->getRunnable())); } @@ -346,7 +346,7 @@ private: CListenTask *_ListenTask; /// Listen thread - NLMISC::IThread *_ListenThread; + NLMISC::CThread *_ListenThread; /* Vector of receiving threads. * Thread: thread control diff --git a/code/nel/include/nel/sound/stream_file_source.h b/code/nel/include/nel/sound/stream_file_source.h index 79151f171..3c54f6f5e 100644 --- a/code/nel/include/nel/sound/stream_file_source.h +++ b/code/nel/include/nel/sound/stream_file_source.h @@ -95,7 +95,7 @@ private: private: inline CStreamFileSound *getStreamFileSound() { return static_cast(m_StreamSound); } - NLMISC::IThread *m_Thread; + NLMISC::CThread *m_Thread; IAudioDecoder *m_AudioDecoder; diff --git a/code/nel/src/3d/zone_lighter.cpp b/code/nel/src/3d/zone_lighter.cpp index 1d7ec5a66..a2b8d170f 100644 --- a/code/nel/src/3d/zone_lighter.cpp +++ b/code/nel/src/3d/zone_lighter.cpp @@ -33,6 +33,7 @@ #include "nel/misc/file.h" #include "nel/misc/aabbox.h" #include "nel/misc/algo.h" +#include "nel/misc/system_info.h" #ifdef NL_OS_WINDOWS @@ -315,38 +316,6 @@ void NEL3DCalcBase (CVector &direction, CMatrix& matrix) // *************************************************************************** -void setCPUMask (IThread *thread, uint process) -{ - // Set the processor mask - uint64 mask = IProcess::getCurrentProcess()->getCPUMask (); - - // Mask must not be NULL - nlassert (mask != 0); - - if (mask != 0) - { - uint i=0; - uint count = 0; - for(;;) - { - if (mask & (UINT64_CONSTANT(1)<setCPUMask (1<processCalc (_Process, *_Description); _ZoneLighter->_ProcessExitedMutex.enter(); _ZoneLighter->_ProcessExited++; @@ -397,7 +363,7 @@ class NL3D::CRenderZBuffer : public IRunnable const vector *_Triangles; public: - IThread *Thread; + CThread *Thread; public: // Ctor @@ -614,9 +580,6 @@ void RenderTriangle (const CZoneLighter::CTriangle &triangle, const CZoneLighter void NL3D::CRenderZBuffer::run() { - // Set the CPU mask - setCPUMask (Thread, _Process); - // Span array CPolygon2D::TRasterVect borders; @@ -915,11 +878,6 @@ void CZoneLighter::light (CLandscape &landscape, CZone& output, uint zoneToLight * - */ - // Backup thread mask - IThread *currentThread = IThread::getCurrentThread (); - uint64 threadMask = currentThread->getCPUMask(); - currentThread->setCPUMask (1); - // Calc the ray basis _SunDirection=description.SunDirection; NEL3DCalcBase (_SunDirection, _RayBasis); @@ -934,16 +892,7 @@ void CZoneLighter::light (CLandscape &landscape, CZone& output, uint zoneToLight _ProcessCount=description.NumCPU; if (_ProcessCount==0) { - // Create a doomy thread - IProcess *pProcess=IProcess::getCurrentProcess (); - _CPUMask = pProcess->getCPUMask(); - _ProcessCount = 0; - uint64 i; - for (i=0; i<64; i++) - { - if (_CPUMask&((uint64)1<MAX_CPU_PROCESS) _ProcessCount=MAX_CPU_PROCESS; @@ -1027,7 +976,7 @@ void CZoneLighter::light (CLandscape &landscape, CZone& output, uint zoneToLight // Create a thread CRenderZBuffer *runnable = new CRenderZBuffer (process, this, &description, firstTriangle, lastTriangle - firstTriangle, &obstacles); - IThread *pThread=IThread::create (runnable); + CThread *pThread=new CThread (runnable); runnable->Thread = pThread; // New first patch @@ -1183,7 +1132,7 @@ void CZoneLighter::light (CLandscape &landscape, CZone& output, uint zoneToLight // Create a thread CLightRunnable *runnable = new CLightRunnable (process, this, &description); - IThread *pThread=IThread::create (runnable); + CThread *pThread=new CThread (runnable); runnable->Thread = pThread; // New first patch @@ -1202,9 +1151,6 @@ void CZoneLighter::light (CLandscape &landscape, CZone& output, uint zoneToLight progress ("Lighting patches", (float)_NumberOfPatchComputed/(float)_PatchInfo.size()); } - // Reset old thread mask - currentThread->setCPUMask (threadMask); - // overflow ? if (_ZBufferOverflow) nlwarning ("Error : zbuffer overflow"); @@ -2861,7 +2807,7 @@ void CZoneLighter::lightShapes(uint zoneID, const CLightDesc& description) { uint lastShapeIndex = currShapeIndex + numShapePerThread; lastShapeIndex = std::min((uint)_LightableShapes.size(), lastShapeIndex); - IThread *pThread = IThread::create (new CCalcLightableShapeRunnable(process, this, &description, &_LightableShapes, currShapeIndex, lastShapeIndex)); + CThread *pThread = new CThread (new CCalcLightableShapeRunnable(process, this, &description, &_LightableShapes, currShapeIndex, lastShapeIndex)); pThread->start(); currShapeIndex = lastShapeIndex; } diff --git a/code/nel/src/georges/header.cpp b/code/nel/src/georges/header.cpp index ff92d60ea..c6a6026ee 100644 --- a/code/nel/src/georges/header.cpp +++ b/code/nel/src/georges/header.cpp @@ -85,7 +85,7 @@ void CFileHeader::addLog (const char *log) Log += ctime(&t); Log.resize (Log.size()-1); Log += " ("; - Log += IThread::getCurrentThread ()->getUserName (); + // Log += CThread::getCurrentThread ()->getUserName (); // FIXME: USERNAME Log += ") "; Log += log; } diff --git a/code/nel/src/misc/co_task.cpp b/code/nel/src/misc/co_task.cpp index 91b0132a9..44c3a490d 100644 --- a/code/nel/src/misc/co_task.cpp +++ b/code/nel/src/misc/co_task.cpp @@ -84,7 +84,7 @@ namespace NLMISC // TThreadId *_ParentThreadId; // the thread of the task - IThread *_TaskThread; + CThread *_TaskThread; /// The mutex of the task task CFastMutex _TaskMutex; @@ -300,7 +300,7 @@ namespace NLMISC #if defined(NL_USE_THREAD_COTASK) // create the thread - _PImpl->_TaskThread = IThread::create(_PImpl); + _PImpl->_TaskThread = new CThread(_PImpl); NL_CT_DEBUG("CoTask : start() task %p entering mutex", this); // get the mutex diff --git a/code/nel/src/misc/inter_window_msg_queue.cpp b/code/nel/src/misc/inter_window_msg_queue.cpp index 77e72e654..698f88ea4 100644 --- a/code/nel/src/misc/inter_window_msg_queue.cpp +++ b/code/nel/src/misc/inter_window_msg_queue.cpp @@ -296,7 +296,7 @@ namespace NLMISC // messageQueueMap->value()[msgQueueIdent] = this; _SendTask = new CSendTask(this); - _SendThread = IThread::create(_SendTask); + _SendThread = new CThread(_SendTask); _SendThread->start(); // init the window handle in shared memory last, // this way we are sure that the new win proc has been installed, and can start received messages diff --git a/code/nel/src/misc/p_thread.cpp b/code/nel/src/misc/p_thread.cpp deleted file mode 100644 index a24029b3c..000000000 --- a/code/nel/src/misc/p_thread.cpp +++ /dev/null @@ -1,387 +0,0 @@ -// NeL - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - - -#include "stdmisc.h" - -#include -#include - -#ifdef NL_OS_UNIX - -#include "nel/misc/p_thread.h" - -#include -#include - -#ifdef DEBUG_NEW - #define new DEBUG_NEW -#endif - -namespace NLMISC { - -/* Key for thread specific storage holding IThread pointer. */ -static pthread_key_t threadSpecificKey; - -/* Special thread type representing the main thread. */ -struct CPMainThread : public CPThread -{ - CPMainThread() : CPThread(NULL, 0) - { - if(pthread_key_create(&threadSpecificKey, NULL) != 0) - throw EThread("cannot create thread specific storage key."); - - if(pthread_setspecific(threadSpecificKey, this) != 0) - throw EThread("cannot set main thread ptr in thread specific storage."); - } - - ~CPMainThread() - { - if(pthread_key_delete(threadSpecificKey) != 0) - throw EThread("cannot delete thread specific storage key."); - } -}; - -/* Holds the thread instance representing the main thread. */ -static CPMainThread mainThread = CPMainThread(); - -/* - * The IThread static creator - */ -IThread *IThread::create( IRunnable *runnable, uint32 stackSize) -{ - return new CPThread( runnable, stackSize ); -} - -/* - * Get the current thread - */ -IThread *IThread::getCurrentThread () -{ - return (IThread *)pthread_getspecific(threadSpecificKey); -} - -/* - * Thread beginning - */ -static void *ProxyFunc( void *arg ) -{ - CPThread *parent = (CPThread*)arg; - - // Set this thread's thread specific storage to IThread instance pointer - if(pthread_setspecific(threadSpecificKey, parent) != 0) - throw EThread("cannot set thread ptr in thread specific storage."); - - // Allow to terminate the thread without cancellation point - pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0); - - // Run the code of the thread - parent->Runnable->run(); - - { - pthread_t thread_self = pthread_self(); - // Make sure the parent still cares - // If this thread was replaced with a new thread (which should not happen), - // and the IThread object has been deleted, this will likely crash. - if (parent->_ThreadHandle == thread_self) - parent->_State = CPThread::ThreadStateFinished; - else - throw EThread("Thread ended after being detached, this should not happen"); - } - - // Allow some clean -// pthread_exit(0); - return NULL; -} - - - -/* - * Constructor - */ -CPThread::CPThread(IRunnable *runnable, uint32 stackSize) - : Runnable(runnable), - _State(ThreadStateNone), - _StackSize(stackSize) -{} - - -/* - * Destructor - */ -CPThread::~CPThread() -{ - terminate(); // force the end of the thread if not already ended - - if (_State != ThreadStateNone) - pthread_detach(_ThreadHandle); // free allocated resources only if it was created -} - -/* - * start - */ -void CPThread::start() -{ - pthread_attr_t tattr; - int ret; - - if (_StackSize != 0) - { - /* initialized with default attributes */ - ret = pthread_attr_init(&tattr); - - /* setting the size of the stack also */ - ret = pthread_attr_setstacksize(&tattr, _StackSize); - } - - bool detach_old_thread = false; - pthread_t old_thread_handle; - if (_State != ThreadStateNone) - { - if (_State == ThreadStateRunning) - { - // I don't know if this behaviour is allowed, but neither thread implementations - // check the start function, and both simply let the existing running thread for what it is... - // From now on, this is not allowed. - throw EThread("Starting a thread that is already started, existing thread will continue running, this should not happen"); - } - detach_old_thread = true; - old_thread_handle = _ThreadHandle; - } - - if (pthread_create(&_ThreadHandle, _StackSize != 0 ? &tattr : NULL, ProxyFunc, this) != 0) - { - throw EThread("Cannot start new thread"); - } - _State = ThreadStateRunning; - - if (detach_old_thread) - { - // Docs don't say anything about what happens when pthread_create is called with existing handle referenced. - if (old_thread_handle == _ThreadHandle) - throw EThread("Thread handle did not change, this should not happen"); - // Don't care about old thread, free resources when it terminates. - pthread_detach(old_thread_handle); - } -} - -bool CPThread::isRunning() -{ - return _State == ThreadStateRunning; -} - -/* - * terminate - */ -void CPThread::terminate() -{ - if (_State == ThreadStateRunning) - { - // cancel only if started - pthread_cancel(_ThreadHandle); - _State = ThreadStateFinished; // set to finished - } -} - -/* - * wait - */ -void CPThread::wait () -{ - if (_State == ThreadStateRunning) - { - int error = pthread_join(_ThreadHandle, 0); - switch (error) - { - case 0: - break; - case EINVAL: - throw EThread("Thread is not joinable"); - case ESRCH: - throw EThread("No thread found with this id"); - case EDEADLK: - throw EThread("Deadlock detected or calling thread waits for itself"); - default: - throw EThread("Unknown thread join error"); - } - if(_State != ThreadStateFinished) - throw EThread("Thread did not finish, this should not happen"); - } -} - -/* - * setCPUMask - */ -bool CPThread::setCPUMask(uint64 cpuMask) -{ -#ifdef __USE_GNU - - nlwarning("This code does not work. May cause a segmentation fault..."); - - sint res = pthread_setaffinity_np(_ThreadHandle, sizeof(uint64), (const cpu_set_t*)&cpuMask); - - if (res) - { - nlwarning("pthread_setaffinity_np() returned %d", res); - return false; - } - - return true; - -#else // __USE_GNU - - return false; - -#endif // __USE_GNU -} - -/* - * getCPUMask - */ -uint64 CPThread::getCPUMask() -{ -#ifdef __USE_GNU - - nlwarning("This code does not work. May cause a segmentation fault..."); - - uint64 cpuMask = 0; - - sint res = pthread_getaffinity_np(_ThreadHandle, sizeof(uint64), (cpu_set_t*)&cpuMask); - - if (res) - { - nlwarning("pthread_getaffinity_np() returned %d", res); - return 0; - } - - return cpuMask; - -#else // __USE_GNU - - return 0; - -#endif // __USE_GNU -} - -void CPThread::setPriority(TThreadPriority priority) -{ - // TODO: Test this - sched_param sp; - switch (priority) - { - case ThreadPriorityHigh: - { - int minPrio = sched_get_priority_min(SCHED_FIFO); - int maxPrio = sched_get_priority_max(SCHED_FIFO); - sp.sched_priority = ((maxPrio - minPrio) / 4) + minPrio; - pthread_setschedparam(_ThreadHandle, SCHED_FIFO, &sp); - break; - } - case ThreadPriorityHighest: - { - int minPrio = sched_get_priority_min(SCHED_FIFO); - int maxPrio = sched_get_priority_max(SCHED_FIFO); - sp.sched_priority = ((maxPrio - minPrio) / 2) + minPrio; - pthread_setschedparam(_ThreadHandle, SCHED_FIFO, &sp); - break; - } - default: - sp.sched_priority = 0; - pthread_setschedparam(_ThreadHandle, SCHED_OTHER, &sp); - } -} - -/* - * getUserName - */ -std::string CPThread::getUserName() -{ - struct passwd *pw = getpwuid(getuid()); - - if (!pw) - return ""; - - return pw->pw_name; -} - - -// **** Process - -// The current process -CPProcess CurrentProcess; - -// Get the current process -IProcess *IProcess::getCurrentProcess () -{ - return &CurrentProcess; -} - -/* - * getCPUMask - */ -uint64 CPProcess::getCPUMask() -{ -#ifdef __USE_GNU - - uint64 cpuMask = 0; - sint res = sched_getaffinity(getpid(), sizeof(uint64), (cpu_set_t*)&cpuMask); - - if (res) - { - nlwarning("sched_getaffinity() returned %d, errno = %d: %s", res, errno, strerror(errno)); - return 0; - } - - return cpuMask; - -#else // __USE_GNU - - return 0; - -#endif // __USE_GNU -} - -/// set the CPU mask -bool CPProcess::setCPUMask(uint64 cpuMask) -{ -#ifdef __USE_GNU - - sint res = sched_setaffinity(getpid(), sizeof(uint64), (const cpu_set_t*)&cpuMask); - - if (res) - { - nlwarning("sched_setaffinity() returned %d, errno = %d: %s", res, errno, strerror(errno)); - return false; - } - - return true; - -#else // __USE_GNU - - return false; - -#endif // __USE_GNU -} - - -} // NLMISC - -#else // NL_OS_UNIX - -// remove stupid VC6 warnings -void foo_p_thread_cpp() {} - -#endif // NL_OS_UNIX diff --git a/code/nel/src/misc/system_info.cpp b/code/nel/src/misc/system_info.cpp index aa7127693..042726d80 100644 --- a/code/nel/src/misc/system_info.cpp +++ b/code/nel/src/misc/system_info.cpp @@ -918,6 +918,11 @@ bool CSystemInfo::hasSSE2() return SDL_HasSSE2(); } +uint CSystemInfo::getCPUCount() +{ + return SDL_GetCPUCount(); +} + bool CSystemInfo::isNT() { #ifdef NL_OS_WINDOWS diff --git a/code/nel/src/misc/task_manager.cpp b/code/nel/src/misc/task_manager.cpp index 4cdb16bd0..9dbdcd16a 100644 --- a/code/nel/src/misc/task_manager.cpp +++ b/code/nel/src/misc/task_manager.cpp @@ -38,7 +38,7 @@ CTaskManager::CTaskManager() : _RunningTask (""), _TaskQueue (""), _DoneTaskQueu _ThreadRunning = true; CSynchronized::CAccessor currentTask(&_RunningTask); currentTask.value () = ""; - _Thread = IThread::create(this); + _Thread = new CThread(this); _Thread->start(); _ChangePriorityCallback = NULL; } diff --git a/code/nel/src/misc/thread.cpp b/code/nel/src/misc/thread.cpp new file mode 100644 index 000000000..794f7c916 --- /dev/null +++ b/code/nel/src/misc/thread.cpp @@ -0,0 +1,105 @@ +// NeL - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#include "stdmisc.h" +#include "nel/misc/thread.h" +#include "nel/misc/debug.h" + +#include + +namespace NLMISC { + +CThread::CThread(IRunnable *runnable) : m_IsRunning(false), m_SDLThread(NULL), m_Runnable(runnable) +{ + +} + +CThread::~CThread () +{ + /* + NOTE: Detach not supported, due to m_IsRunning which is referenced by the running thread + FIX: Use a thread-safe reference counted object for the m_IsRunning flag + if (m_SDLThread) + { + SDL_DetachThread(m_SDLThread); + } + NOTE: Currently use wait, which is much saner behaviour. + */ + + wait(); +} + +void CThread::start() +{ + nlassert(!m_SDLThread); + nlassert(!m_IsRunning); + std::string name; + m_Runnable->getName(name); + m_IsRunning = true; + m_SDLThread = SDL_CreateThread(run, name.c_str(), (void *)this); +} + +int CThread::run(void *ptr) +{ + NLMISC::CThread *thread = static_cast(ptr); + thread->m_Runnable->run(); + thread->m_IsRunning = false; + return 0; +} + +void CThread::setPriority(TThreadPriority priority) +{ + switch (priority) + { + case ThreadPriorityLow: + SDL_SetThreadPriority(SDL_THREAD_PRIORITY_LOW); + break; + case ThreadPriorityNormal: + SDL_SetThreadPriority(SDL_THREAD_PRIORITY_NORMAL); + break; + case ThreadPriorityHigh: + SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH); + break; + default: + nlerror("Invalid thread priority"); + break; + } +} + +bool CThread::isRunning() +{ + return m_IsRunning; +} + +int CThread::wait() +{ + m_WaitMutex.enter(); + if (m_SDLThread) + { + SDL_WaitThread(m_SDLThread, &m_ThreadResult); + m_SDLThread = NULL; + nlassert(!m_IsRunning); + } + m_WaitMutex.leave(); + return m_ThreadResult; +} + +IRunnable *CThread::getRunnable() +{ + return m_Runnable; +} + +} // NLMISC diff --git a/code/nel/src/misc/time_nl.cpp b/code/nel/src/misc/time_nl.cpp index 0ba60c8e2..412c66214 100644 --- a/code/nel/src/misc/time_nl.cpp +++ b/code/nel/src/misc/time_nl.cpp @@ -153,135 +153,6 @@ void CTime::probeTimerInfo(CTime::CTimerInfo &result) #endif - uint64 cpuMask = IProcess::getCurrentProcess()->getCPUMask(); -#ifdef NL_OS_WINDOWS - uint64 threadMask = IThread::getCurrentThread()->getCPUMask(); // broken on linux, don't expect it to work anywhere -#else - uint64 threadMask = cpuMask; -#endif - - uint identical = 0; // Identical stamps may indicate the os handling backwards glitches. - uint backwards = 0; // Happens when the timers are not always in sync and the implementation is faulty. - uint regular = 0; // How many times the number advanced normally. - uint skipping = 0; // Does not really mean anything necessarily. - uint frequencybug = 0; // Should never happen. - // uint badcore = 0; // Affinity does not work. - - // Cycle 32 times trough all cores, and verify if the timing remains consistent. - for (uint i = 32; i; --i) - { - uint64 currentBit = 1; - for (uint j = 64; j; --j) - { - if (cpuMask & currentBit) - { -#ifdef NL_OS_WINDOWS - if (!IThread::getCurrentThread()->setCPUMask(currentBit)) -#else - if (!IProcess::getCurrentProcess()->setCPUMask(currentBit)) -#endif - break; // Thread was set to last cpu. -#ifdef NL_OS_WINDOWS - // Make sure the thread is rescheduled. - SwitchToThread(); - Sleep(0); - // Verify the core - /* Can only verify on 2003, Vista and higher. - if (1 << GetCurrentProcessorNumber() != currentBit) - ++badcore; - */ - // Check if the timer is still sane. - if (result.IsHighPrecisionAvailable) - { - LARGE_INTEGER winPerfFreqN; - LARGE_INTEGER winPerfCountN; - QueryPerformanceFrequency(&winPerfFreqN); - if (winPerfFreqN.QuadPart != winPerfFreq.QuadPart) - ++frequencybug; - QueryPerformanceCounter(&winPerfCountN); - if (winPerfCountN.QuadPart == winPerfCount.QuadPart) - ++identical; - if (winPerfCountN.QuadPart < winPerfCount.QuadPart || winPerfCountN.QuadPart - winPerfCount.QuadPart < 0) - ++backwards; - if (winPerfCountN.QuadPart - winPerfCount.QuadPart > winPerfFreq.QuadPart / 20) // 50ms skipping check - ++skipping; - else if (winPerfCountN.QuadPart > winPerfCount.QuadPart) - ++regular; - winPerfCount.QuadPart = winPerfCountN.QuadPart; - } - else - { - DWORD lowResTimeN; - lowResTimeN = timeGetTime(); - if (lowResTimeN == lowResTime) - ++identical; - if (lowResTimeN < lowResTime || lowResTimeN - lowResTime < 0) - ++backwards; - if (lowResTimeN - lowResTime > 50) - ++skipping; - else if (lowResTimeN > lowResTime) - ++regular; - lowResTime = lowResTimeN; - } -#else -#ifdef NL_OS_UNIX - sched_yield(); -#else - nlSleep(0); -#endif -# ifdef NL_MONOTONIC_CLOCK - if (hasMonotonicClock()) - { - timespec monoClockN; - clock_gettime(CLOCK_MONOTONIC, &monoClockN); - if (monoClock.tv_sec == monoClockN.tv_sec && monoClock.tv_nsec == monoClockN.tv_nsec) - ++identical; - if (monoClockN.tv_sec < monoClock.tv_sec || (monoClock.tv_sec == monoClockN.tv_sec && monoClockN.tv_nsec < monoClock.tv_nsec)) - ++backwards; - if (monoClock.tv_sec == monoClockN.tv_sec && (monoClockN.tv_nsec - monoClock.tv_nsec > 50000000L)) - ++skipping; - else if ((monoClock.tv_sec == monoClockN.tv_sec && monoClock.tv_nsec < monoClockN.tv_nsec) || monoClock.tv_sec < monoClockN.tv_sec) - ++regular; - monoClock.tv_sec = monoClockN.tv_sec; - monoClock.tv_nsec = monoClockN.tv_nsec; - } - else -# endif - { - TTime localTimeN = getLocalTime(); - if (localTimeN == localTime) - ++identical; - if (localTimeN < localTime || localTimeN - localTime < 0) - ++backwards; - if (localTimeN - localTime > 50) - ++skipping; - else if (localTimeN > localTime) - ++regular; - localTime = localTimeN; - } -#endif - } - currentBit <<= 1; - } - } - -#ifdef NL_OS_WINDOWS - IThread::getCurrentThread()->setCPUMask(threadMask); -#else - IProcess::getCurrentProcess()->setCPUMask(threadMask); -#endif - - nldebug("Timer resolution: %i Hz", (int)(result.HighPrecisionResolution)); - nldebug("Time identical: %i, backwards: %i, regular: %i, skipping: %i, frequency bug: %i", identical, backwards, regular, skipping, frequencybug); - if (identical > regular) - nlwarning("The system timer is of relatively low resolution, you may experience issues"); - if (backwards > 0 || frequencybug > 0) - { - nlwarning("The current system timer is not reliable across multiple cpu cores"); - result.RequiresSingleCore = true; - } - else result.RequiresSingleCore = false; - if (result.HighPrecisionResolution == 14318180) { nldebug("Detected known HPET era timer frequency"); diff --git a/code/nel/src/misc/win_thread.cpp b/code/nel/src/misc/win_thread.cpp deleted file mode 100644 index d90d081ff..000000000 --- a/code/nel/src/misc/win_thread.cpp +++ /dev/null @@ -1,609 +0,0 @@ -// NeL - MMORPG Framework -// Copyright (C) 2010 Winch Gate Property Limited -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as -// published by the Free Software Foundation, either version 3 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#include "stdmisc.h" -#include "nel/misc/win_thread.h" - -#ifdef NL_OS_WINDOWS - -#include "nel/misc/path.h" -#define NOMINMAX -#include - -#include - -#ifdef DEBUG_NEW - #define new DEBUG_NEW -#endif - -namespace NLMISC { - -CWinThread MainThread ((void*)GetCurrentThread (), GetCurrentThreadId()); -DWORD TLSThreadPointer = 0xFFFFFFFF; - -// the IThread static creator -IThread *IThread::create (IRunnable *runnable, uint32 stackSize) -{ - return new CWinThread (runnable, stackSize); -} - -IThread *IThread::getCurrentThread () -{ - // TLS alloc must have been done - nlassert (TLSThreadPointer != 0xffffffff); - - // Get the thread pointer - IThread *thread = (IThread*)TlsGetValue (TLSThreadPointer); - - // Return current thread - return thread; -} - -static unsigned long __stdcall ProxyFunc (void *arg) -{ - CWinThread *parent = (CWinThread *) arg; - - // TLS alloc must have been done - nlassert (TLSThreadPointer != 0xffffffff); - - // Set the thread pointer in TLS memory - nlverify (TlsSetValue (TLSThreadPointer, (void*)parent) != 0); - - // Run the thread - parent->Runnable->run(); - - return 0; -} - -CWinThread::CWinThread (IRunnable *runnable, uint32 stackSize) -{ - _StackSize = stackSize; - this->Runnable = runnable; - ThreadHandle = NULL; - _SuspendCount = -1; - _MainThread = false; -} - -namespace { -class CWinCriticalSection -{ -private: - CRITICAL_SECTION cs; -public: - CWinCriticalSection() { InitializeCriticalSection(&cs); } - ~CWinCriticalSection() { DeleteCriticalSection(&cs); } - inline void enter() { EnterCriticalSection(&cs); } - inline void leave() { LeaveCriticalSection(&cs); } -}; -CWinCriticalSection s_CS; -}/* anonymous namespace */ - -CWinThread::CWinThread (void* threadHandle, uint32 threadId) -{ - // Main thread - _MainThread = true; - this->Runnable = NULL; - ThreadHandle = threadHandle; - ThreadId = threadId; - - // TLS alloc must have been done - TLSThreadPointer = TlsAlloc (); - nlassert (TLSThreadPointer!=0xffffffff); - - // Set the thread pointer in TLS memory - nlverify (TlsSetValue (TLSThreadPointer, (void*)this) != 0); - - if (GetCurrentThreadId() == threadId) - { - _SuspendCount = 0; // is calling thread call this itself, well, if we reach this place - // there are chances that it is not suspended ... - } - else - { - // initialized from another thread (very unlikely ...) - nlassert(0); // WARNING: following code has not tested! don't know if it work fo real ... - // This is just a suggestion of a possible solution, should this situation one day occur ... - // Ensure that this thread don't get deleted, or we could suspend the main thread - s_CS.enter(); - // the 2 following statement must be executed atomicaly among the threads of the current process ! - SuspendThread(threadHandle); - _SuspendCount = ResumeThread(threadHandle); - s_CS.leave(); - } -} - - -void CWinThread::incSuspendCount() -{ - nlassert(ThreadHandle); // start was not called !! - int newSuspendCount = ::SuspendThread(ThreadHandle) + 1; - nlassert(newSuspendCount != 0xffffffff); // more infos with 'GetLastError' - nlassert(newSuspendCount == _SuspendCount + 1); // is this assert fire , then 'SuspendThread' or 'ResumeThread' - // have been called outside of this object interface! (on this thread handle ...) - _SuspendCount = newSuspendCount; -} - -void CWinThread::decSuspendCount() -{ - nlassert(ThreadHandle); // 'start' was not called !! - nlassert(_SuspendCount > 0); - int newSuspendCount = ::ResumeThread(ThreadHandle) - 1; - nlassert(newSuspendCount != 0xffffffff); // more infos with 'GetLastError' - nlassert(newSuspendCount == _SuspendCount - 1); // is this assert fire , then 'SuspendThread' or 'ResumeThread' - // have been called outside of this object interface! (on this thread handle ...) - _SuspendCount = newSuspendCount; -} - -void CWinThread::suspend() -{ - if (getSuspendCount() == 0) - { - incSuspendCount(); - } -} - -void CWinThread::resume() -{ - while (getSuspendCount() != 0) - { - decSuspendCount(); - } -} - -void CWinThread::setPriority(TThreadPriority priority) -{ - nlassert(ThreadHandle); // 'start' was not called !! - BOOL result = SetThreadPriority(ThreadHandle, (int)priority); - nlassert(result); -} - -void CWinThread::enablePriorityBoost(bool enabled) -{ - nlassert(ThreadHandle); // 'start' was not called !! - SetThreadPriorityBoost(ThreadHandle, enabled ? TRUE : FALSE); -} - - -CWinThread::~CWinThread () -{ - // If not the main thread - if (_MainThread) - { - // Free TLS memory - nlassert (TLSThreadPointer!=0xffffffff); - TlsFree (TLSThreadPointer); - } - else - { - if (ThreadHandle != NULL) terminate(); - } -} - -void CWinThread::start () -{ - if (isRunning()) - throw EThread("Starting a thread that is already started, existing thread will continue running, this should not happen"); - -// ThreadHandle = (void *) ::CreateThread (NULL, _StackSize, ProxyFunc, this, 0, (DWORD *)&ThreadId); - ThreadHandle = (void *) ::CreateThread (NULL, 0, ProxyFunc, this, 0, (DWORD *)&ThreadId); -// nldebug("NLMISC: thread %x started for runnable '%x'", typeid( Runnable ).name()); -// OutputDebugString(toString(NL_LOC_MSG " NLMISC: thread %x started for runnable '%s'\n", ThreadId, typeid( *Runnable ).name()).c_str()); - SetThreadPriorityBoost (ThreadHandle, TRUE); // FALSE == Enable Priority Boost - if (ThreadHandle == NULL) - { - throw EThread ( "Cannot create new thread" ); - } - - _SuspendCount = 0; -} - -bool CWinThread::isRunning() -{ - if (ThreadHandle == NULL) - return false; - - DWORD exitCode; - if (!GetExitCodeThread(ThreadHandle, &exitCode)) - return false; - - return exitCode == STILL_ACTIVE; -} - - -void CWinThread::terminate () -{ - TerminateThread((HANDLE)ThreadHandle, 0); - CloseHandle((HANDLE)ThreadHandle); - ThreadHandle = NULL; - _SuspendCount = -1; -} - -void CWinThread::wait () -{ - if (ThreadHandle == NULL) return; - - WaitForSingleObject(ThreadHandle, INFINITE); - CloseHandle(ThreadHandle); - ThreadHandle = NULL; - _SuspendCount = -1; -} - -bool CWinThread::setCPUMask(uint64 cpuMask) -{ - // Thread must exist - if (ThreadHandle == NULL) - return false; - - // Ask the system for number of processor available for this process - return SetThreadAffinityMask ((HANDLE)ThreadHandle, (DWORD_PTR)cpuMask) != 0; -} - -uint64 CWinThread::getCPUMask() -{ - // Thread must exist - if (ThreadHandle == NULL) - return 1; - - // Get the current process mask - uint64 mask=IProcess::getCurrentProcess ()->getCPUMask (); - - // Get thread affinity mask - DWORD_PTR old = SetThreadAffinityMask ((HANDLE)ThreadHandle, (DWORD_PTR)mask); - nlassert (old != 0); - if (old == 0) - return 1; - - // Reset it - SetThreadAffinityMask ((HANDLE)ThreadHandle, old); - - // Return the mask - return (uint64)old; -} - -std::string CWinThread::getUserName() -{ - char userName[512]; - DWORD size = 512; - GetUserName (userName, &size); - return (const char*)userName; -} - -// **** Process - -// The current process -CWinProcess CurrentProcess ((void*)GetCurrentProcess()); - -// Get the current process -IProcess *IProcess::getCurrentProcess () -{ - return &CurrentProcess; -} - -CWinProcess::CWinProcess (void *handle) -{ - // Get the current process handle - _ProcessHandle = handle; -} - -uint64 CWinProcess::getCPUMask() -{ - // Ask the system for number of processor available for this process - DWORD_PTR processAffinityMask; - DWORD_PTR systemAffinityMask; - if (GetProcessAffinityMask((HANDLE)_ProcessHandle, &processAffinityMask, &systemAffinityMask)) - { - // Return the CPU mask - return (uint64)processAffinityMask; - } - else - return 1; -} - -bool CWinProcess::setCPUMask(uint64 mask) -{ - // Ask the system for number of processor available for this process - DWORD_PTR processAffinityMask= (DWORD_PTR)mask; - return SetProcessAffinityMask((HANDLE)_ProcessHandle, processAffinityMask)!=0; -} - -// **************************************************************************************************************** -/** - * Simple wrapper around the PSAPI library - * \author Nicolas Vizerie - * \author GameForge - * \date 2007 - */ - -class CPSAPILib -{ -public: - typedef BOOL (WINAPI *EnumProcessesFunPtr)(DWORD *lpidProcess, DWORD cb, DWORD *cbNeeded); - typedef DWORD (WINAPI *GetModuleFileNameExAFunPtr)(HANDLE hProcess, HMODULE hModule, LPTSTR lpFilename, DWORD nSize); - typedef BOOL (WINAPI *EnumProcessModulesFunPtr)(HANDLE hProcess, HMODULE *lphModule, DWORD cb, LPDWORD lpcbNeeded); - EnumProcessesFunPtr EnumProcesses; - GetModuleFileNameExAFunPtr GetModuleFileNameExA; - EnumProcessModulesFunPtr EnumProcessModules; -public: - CPSAPILib(); - ~CPSAPILib(); - bool init(); -private: - HINSTANCE _PSAPILibHandle; - bool _LoadFailed; -}; - -// **************************************************************************************************************** -CPSAPILib::CPSAPILib() -{ - _LoadFailed = false; - _PSAPILibHandle = NULL; - EnumProcesses = NULL; - GetModuleFileNameExA = NULL; - EnumProcessModules = NULL; -} - -// **************************************************************************************************************** -CPSAPILib::~CPSAPILib() -{ - if (_PSAPILibHandle) - { - FreeLibrary(_PSAPILibHandle); - } -} - -// **************************************************************************************************************** -bool CPSAPILib::init() -{ - // - if (_LoadFailed) return false; - if (!_PSAPILibHandle) - { - _PSAPILibHandle = LoadLibrary("psapi.dll"); - if (!_PSAPILibHandle) - { - nlwarning("couldn't load psapi.dll, possibly not supported by os"); - _LoadFailed = true; - return false; - } - EnumProcesses = (EnumProcessesFunPtr) GetProcAddress(_PSAPILibHandle, "EnumProcesses"); - GetModuleFileNameExA = (GetModuleFileNameExAFunPtr) GetProcAddress(_PSAPILibHandle, "GetModuleFileNameExA"); - EnumProcessModules = (EnumProcessModulesFunPtr) GetProcAddress(_PSAPILibHandle, "EnumProcessModules"); - if (!EnumProcesses || - !GetModuleFileNameExA || - !EnumProcessModules - ) - { - nlwarning("Failed to import functions from psapi.dll!"); - _LoadFailed = true; - return false; - } - } - return true; -} - - -static CPSAPILib PSAPILib; - - - -// **************************************************************************************************************** -bool CWinProcess::enumProcessesId(std::vector &processesId) -{ - if (!PSAPILib.init()) return false; - // list of processes - std::vector prcIds(16); - for (;;) - { - DWORD cbNeeded; - if (!PSAPILib.EnumProcesses((DWORD *) &prcIds[0], (DWORD)(prcIds.size() * sizeof(DWORD)), &cbNeeded)) - { - nlwarning("Processes enumeration failed!"); - return false; - } - if (cbNeeded < prcIds.size() * sizeof(DWORD)) - { - prcIds.resize(cbNeeded / sizeof(DWORD)); - break; - } - // make some more room - prcIds.resize(prcIds.size() * 2); - } - processesId.swap(prcIds); - return true; -} - -// **************************************************************************************************************** -bool CWinProcess::enumProcessModules(uint32 processId, std::vector &moduleNames) -{ - if (!PSAPILib.init()) return false; - HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, FALSE, (DWORD) processId); - if (!hProcess) return false; - // list of modules - std::vector prcModules(2); - for (;;) - { - DWORD cbNeeded; - if (!PSAPILib.EnumProcessModules(hProcess, (HMODULE *) &prcModules[0], (DWORD)(prcModules.size() * sizeof(HMODULE)), &cbNeeded)) - { - //nlwarning("Processe modules enumeration failed!"); - return false; - } - if (cbNeeded < prcModules.size() * sizeof(HMODULE)) - { - prcModules.resize(cbNeeded / sizeof(HMODULE)); - break; - } - // make some more room - prcModules.resize(prcModules.size() * 2); - } - moduleNames.clear(); - std::vector resultModuleNames; - char moduleName[MAX_PATH + 1]; - for (uint m = 0; m < prcModules.size(); ++m) - { - if (PSAPILib.GetModuleFileNameExA(hProcess, prcModules[m], moduleName, MAX_PATH)) - { - moduleNames.push_back(moduleName); - } - } - CloseHandle(hProcess); - return true; -} - -// **************************************************************************************************************** -uint32 CWinProcess::getProcessIdFromModuleFilename(const std::string &moduleFileName) -{ - std::vector processesId; - if (!enumProcessesId(processesId)) return false; - std::vector moduleNames; - for (uint prc = 0; prc < processesId.size(); ++prc) - { - if (enumProcessModules(processesId[prc], moduleNames)) - { - for (uint m = 0; m < moduleNames.size(); ++m) - { - if (nlstricmp(CFile::getFilename(moduleNames[m]), moduleFileName) == 0) - { - return processesId[prc]; - } - } - } - } - return 0; -} - -// **************************************************************************************************************** -bool CWinProcess::terminateProcess(uint32 processId, uint exitCode) -{ - if (!processId) return false; - HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, (DWORD) processId); - if (!hProcess) return false; - BOOL ok = TerminateProcess(hProcess, (UINT) exitCode); - CloseHandle(hProcess); - return ok != FALSE; -} - -// **************************************************************************************************************** -bool CWinProcess::terminateProcessFromModuleName(const std::string &moduleName, uint exitCode) -{ - return terminateProcess(getProcessIdFromModuleFilename(moduleName), exitCode); -} - - -/////////////////// -// CProcessWatch // -/////////////////// - - -/* - -// I didn't use and test that code, eventually, but maybe useful in the future - -class CProcessWatchTask : public IRunnable -{ -public: - HANDLE HProcess; -public: - CProcessWatchTask(HANDLE hProcess) : HProcess(hProcess) - { - } - virtual void run() - { - WaitForSingleObject(HProcess, INFINITE); - } -}; - -class CProcessWatchImpl -{ -public: - bool Launched; - IThread *WatchThread; - CProcessWatchTask *WatchTask; -public: - CProcessWatchImpl() : Launched(false), WatchThread(NULL), WatchTask(NULL) - { - } - ~CProcessWatchImpl() - { - reset(); - } - void reset() - { - if (WatchThread) - { - if (WatchThread->isRunning()) - { - WatchThread->terminate(); - } - delete WatchTask; - delete WatchThread; - WatchTask = NULL; - WatchThread = NULL; - Launched = false; - } - } - bool launch(const std::string &programName, const std::string &arguments) - { - if (isRunning()) return false; - PROCESS_INFORMATION processInfo; - STARTUPINFO startupInfo = {0}; - startupInfo.cb = sizeof(STARTUPINFO); - if (CreateProcess(programName.c_str(), const_cast(arguments.c_str()), NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInfo)) - { - WatchTask = new CProcessWatchTask(processInfo.hProcess); - WatchThread = IThread::create(WatchTask); - WatchThread->start(); - Launched = true; - return true; - } - return false; - } - bool isRunning() - { - if (!Launched) return false; - nlassert(WatchThread); - nlassert(WatchTask); - if (WatchThread->isRunning()) return true; - reset(); - return false; - } -}; - - -CProcessWatch::CProcessWatch() -{ - _PImpl = new CProcessWatchImpl; -} - -CProcessWatch::~CProcessWatch() -{ - delete _PImpl; -} - -bool CProcessWatch::launch(const std::string &programName, const std::string &arguments) -{ - return _PImpl->launch(programName, arguments); -} - -bool CProcessWatch::isRunning() const -{ - return _PImpl->isRunning(); -} - -*/ -} // NLMISC - -#endif // NL_OS_WINDOWS diff --git a/code/nel/src/misc/window_displayer.cpp b/code/nel/src/misc/window_displayer.cpp index 5c9227933..87b93cf74 100644 --- a/code/nel/src/misc/window_displayer.cpp +++ b/code/nel/src/misc/window_displayer.cpp @@ -109,7 +109,7 @@ void CWindowDisplayer::setLabel (uint label, const string &value) void CWindowDisplayer::create (string windowNameEx, bool iconified, sint x, sint y, sint w, sint h, sint hs, sint fs, const std::string &fn, bool ww, CLog *log) { nlassert (_Thread == NULL); - _Thread = IThread::create (new CUpdateThread(this, windowNameEx, iconified, x, y, w, h, hs, fs, fn, ww, log)); + _Thread = new CThread (new CUpdateThread(this, windowNameEx, iconified, x, y, w, h, hs, fs, fn, ww, log)); Log = log; diff --git a/code/nel/src/net/buf_client.cpp b/code/nel/src/net/buf_client.cpp index 939dbc89a..5b2672808 100644 --- a/code/nel/src/net/buf_client.cpp +++ b/code/nel/src/net/buf_client.cpp @@ -99,7 +99,7 @@ void CBufClient::connect( const CInetAddress& addr ) delete _RecvThread; } - _RecvThread = IThread::create( _RecvTask, 1024*4*4 ); + _RecvThread = new CThread( _RecvTask ); _RecvThread->start(); } diff --git a/code/nel/src/net/buf_server.cpp b/code/nel/src/net/buf_server.cpp index 44c966e11..c63b61bc2 100644 --- a/code/nel/src/net/buf_server.cpp +++ b/code/nel/src/net/buf_server.cpp @@ -77,7 +77,7 @@ CBufServer::CBufServer( TThreadStategy strategy, if ( ! _ReplayMode ) { _ListenTask = new CListenTask( this ); - _ListenThread = IThread::create( _ListenTask, 1024*4*4 ); + _ListenThread = new CThread( _ListenTask ); } /*{ CSynchronized::CAccessor syncbpi ( &_BytesPushedIn ); @@ -949,7 +949,7 @@ void CBufServer::addNewThread( CThreadPool& threadpool, CServerBufSock *bufsock task->addNewSocket( bufsock ); // Add a new thread to the pool, with this task - IThread *thr = IThread::create( task, 1024*4*4 ); + CThread *thr = new CThread( task ); { threadpool.push_back( thr ); thr->start(); diff --git a/code/nel/src/net/service.cpp b/code/nel/src/net/service.cpp index 3a6991485..d0a2f0ecc 100644 --- a/code/nel/src/net/service.cpp +++ b/code/nel/src/net/service.cpp @@ -560,7 +560,7 @@ sint IService::main (const char *serviceShortName, const char *serviceLongName, bool userInitCalled = false; CConfigFile::CVar *var = NULL; - IThread *timeoutThread = NULL; + CThread *timeoutThread = NULL; // a short name service can't be a number uint tmp; @@ -1266,7 +1266,7 @@ sint IService::main (const char *serviceShortName, const char *serviceLongName, // Activate the timeout assertion thread // - timeoutThread = IThread::create(&MyTAT, 1024*4); + timeoutThread = new CThread(&MyTAT); timeoutThread->start(); // diff --git a/code/nel/src/net/stdin_monitor_thread.cpp b/code/nel/src/net/stdin_monitor_thread.cpp index 6e213c988..be40ada18 100644 --- a/code/nel/src/net/stdin_monitor_thread.cpp +++ b/code/nel/src/net/stdin_monitor_thread.cpp @@ -162,7 +162,7 @@ namespace NLNET private: // data for the singleton instance CStdinMonitorThread* _StdinMonitorThreadInstance; - NLMISC::IThread* _StdinMonitorThreadHandle; + NLMISC::CThread* _StdinMonitorThreadHandle; }; @@ -191,7 +191,7 @@ namespace NLNET void CStdinMonitorSingleton::init() { _StdinMonitorThreadInstance= new CStdinMonitorThread; - _StdinMonitorThreadHandle = NLMISC::IThread::create (_StdinMonitorThreadInstance, 1024*4*4); + _StdinMonitorThreadHandle = new NLMISC::CThread (_StdinMonitorThreadInstance); _StdinMonitorThreadHandle->start(); } @@ -219,7 +219,7 @@ namespace NLNET return; // terminate the thread and wait for it to finish - _StdinMonitorThreadHandle->terminate(); + // _StdinMonitorThreadHandle->terminate(); // FIXME: TERMINATE... _StdinMonitorThreadHandle->wait(); // destroy the thread object instance and reset the pointer to NULL to mark as 'uninitialised' diff --git a/code/nel/src/net/unified_network.cpp b/code/nel/src/net/unified_network.cpp index e8af9ceac..2e1fcecaf 100644 --- a/code/nel/src/net/unified_network.cpp +++ b/code/nel/src/net/unified_network.cpp @@ -450,7 +450,7 @@ public: }; CAliveCheck* CAliveCheck::Thread = NULL; -IThread* AliveThread = NULL; +CThread* AliveThread = NULL; void CAliveCheck::run() @@ -631,7 +631,7 @@ bool CUnifiedNetwork::init(const CInetAddress *addr, CCallbackNetBase::TRecordin nlinfo ("HNETL5: Server '%s' added, registered and listen to port %hu", _Name.c_str (), _ServerPort); } - AliveThread = IThread::create(new CAliveCheck(), 1024*4); + AliveThread = new CThread(new CAliveCheck()); AliveThread->start(); _Initialised = true; diff --git a/code/nel/src/sound/stream_file_source.cpp b/code/nel/src/sound/stream_file_source.cpp index 185b7514f..a75b69afe 100644 --- a/code/nel/src/sound/stream_file_source.cpp +++ b/code/nel/src/sound/stream_file_source.cpp @@ -47,7 +47,7 @@ namespace NLSOUND { CStreamFileSource::CStreamFileSource(CStreamFileSound *streamFileSound, bool spawn, TSpawnEndCallback cb, void *cbUserParam, NL3D::CCluster *cluster, CGroupController *groupController) : CStreamSource(streamFileSound, spawn, cb, cbUserParam, cluster, groupController), m_AudioDecoder(NULL), m_Paused(false) { - m_Thread = NLMISC::IThread::create(this); + m_Thread = new NLMISC::CThread(this); } CStreamFileSource::~CStreamFileSource() @@ -121,7 +121,7 @@ void CStreamFileSource::play() // else load audiodecoder in thread m_WaitingForPlay = true; m_Thread->start(); - m_Thread->setPriority(NLMISC::ThreadPriorityHighest); + m_Thread->setPriority(NLMISC::ThreadPriorityHigh); if (!getStreamFileSound()->getAsync()) { // wait until at least one buffer is ready @@ -304,6 +304,8 @@ inline bool CStreamFileSource::bufferMore(uint bytes) // buffer from bytes (mini void CStreamFileSource::run() { + NLMISC::CThread::setPriority(NLMISC::ThreadPriorityHigh); + #ifdef NLSOUND_STREAM_FILE_DEBUG nldebug("run %s", getStreamFileSound()->getFilePath().c_str()); uint dumpI = 0; diff --git a/code/nelns/admin_executor_service/log_report.cpp b/code/nelns/admin_executor_service/log_report.cpp index 7106fb9d1..5c3b07572 100644 --- a/code/nelns/admin_executor_service/log_report.cpp +++ b/code/nelns/admin_executor_service/log_report.cpp @@ -127,7 +127,7 @@ void CMakeLogTask::start() } _Stopping = false; _Complete = false; - _Thread = NLMISC::IThread::create( this ); + _Thread = new NLMISC::CThread( this ); _OutputLogReport = new CLogReport(); _Thread->start(); } diff --git a/code/nelns/admin_executor_service/log_report.h b/code/nelns/admin_executor_service/log_report.h index de9201f3a..8ad55ea07 100644 --- a/code/nelns/admin_executor_service/log_report.h +++ b/code/nelns/admin_executor_service/log_report.h @@ -92,7 +92,7 @@ private: std::string _LogTarget; std::vector _LogPaths; - NLMISC::IThread *_Thread; + NLMISC::CThread *_Thread; CLogReport *_OutputLogReport; }; diff --git a/code/ryzom/client/src/bg_downloader_access.cpp b/code/ryzom/client/src/bg_downloader_access.cpp index 1603cae0f..879420af6 100644 --- a/code/ryzom/client/src/bg_downloader_access.cpp +++ b/code/ryzom/client/src/bg_downloader_access.cpp @@ -21,15 +21,12 @@ // #include "nel/misc/shared_memory.h" #include "nel/misc/i18n.h" -#include "nel/misc/win_thread.h" #include "nel/misc/big_file.h" // #include "game_share/bg_downloader_msg.h" -#ifdef NL_OS_WINDOWS - -#include "nel/misc/win_thread.h" +#if 0 using namespace BGDownloader; using namespace NLMISC; diff --git a/code/ryzom/client/src/init.cpp b/code/ryzom/client/src/init.cpp index ee2464c2f..7eca96396 100644 --- a/code/ryzom/client/src/init.cpp +++ b/code/ryzom/client/src/init.cpp @@ -378,37 +378,11 @@ void outOfMemory() nlstopex (("OUT OF MEMORY")); } -// For multi cpu, active only one CPU for the main thread -uint64 Debug_OldCPUMask= 0; -uint64 Debug_NewCPUMask= 0; -void setCPUMask () -{ - uint64 cpuMask = IProcess::getCurrentProcess ()->getCPUMask(); - Debug_OldCPUMask= cpuMask; - - // get the processor to allow process - uint i = 0; - while ((i<64) && ((cpuMask&(SINT64_CONSTANT(1)<setCPUMask(1<setCPUMask (1<getCPUMask(); - Debug_NewCPUMask= cpuMask; -} - string getVersionString (uint64 version) { return toString ("%u.%u.%u.%u", (unsigned int) (version >> 48), (unsigned int) ((version >> 32) & 0xffff), (unsigned int) ((version >> 16) & 0xffff), (unsigned int) (version & 0xffff)); } - string getSystemInformation() { string s; @@ -742,8 +716,6 @@ void prelogInit() CTime::CTimerInfo timerInfo; NLMISC::CTime::probeTimerInfo(timerInfo); - if (timerInfo.RequiresSingleCore) // TODO: Also have a FV configuration value to force single core. - setCPUMask(); FPU_CHECKER_ONCE @@ -963,9 +935,11 @@ void prelogInit() CLoginProgressPostThread::getInstance().step(CLoginStep(LoginStep_VideoModeSetupHighColor, "login_step_video_mode_setup_high_color")); -#ifdef NL_OS_WINDOWS - +#if 0 CBGDownloaderAccess::getInstance().init(); +#endif + +#ifdef NL_OS_WINDOWS if (SlashScreen) DestroyWindow (SlashScreen); diff --git a/code/ryzom/client/src/init_main_loop.cpp b/code/ryzom/client/src/init_main_loop.cpp index b251689ea..b1f3260d8 100644 --- a/code/ryzom/client/src/init_main_loop.cpp +++ b/code/ryzom/client/src/init_main_loop.cpp @@ -299,7 +299,7 @@ void startStatThread() curl_global_init(CURL_GLOBAL_ALL); //nlinfo("startStatThread"); CStatThread *statThread = new CStatThread(); - IThread *thread = IThread::create (statThread); + CThread *thread = new CThread (statThread); nlassert (thread != NULL); thread->start (); } diff --git a/code/ryzom/client/src/interface_v3/group_html_webig.cpp b/code/ryzom/client/src/interface_v3/group_html_webig.cpp index 8ffa25878..161e5ac92 100644 --- a/code/ryzom/client/src/interface_v3/group_html_webig.cpp +++ b/code/ryzom/client/src/interface_v3/group_html_webig.cpp @@ -274,7 +274,7 @@ void startWebigNotificationThread() curl_global_init(CURL_GLOBAL_ALL); //nlinfo("startStatThread"); CWebigNotificationThread *webigThread = new CWebigNotificationThread(); - IThread *thread = IThread::create (webigThread); + CThread *thread = new CThread (webigThread); nlassert (thread != NULL); thread->start (); startedWebigNotificationThread = true; diff --git a/code/ryzom/client/src/login.cpp b/code/ryzom/client/src/login.cpp index 45e3fea51..8f44ada5d 100644 --- a/code/ryzom/client/src/login.cpp +++ b/code/ryzom/client/src/login.cpp @@ -467,7 +467,7 @@ void loginMainLoop() if (isBGDownloadEnabled()) { AvailablePatchs = bgDownloader.getAvailablePatchs(); - #ifdef NL_OS_WINDOWS + #if 0 { // Get the window HWND hWnd = Driver->getDisplay(); diff --git a/code/ryzom/client/src/login_patch.cpp b/code/ryzom/client/src/login_patch.cpp index 5b9a83c83..30b35c86d 100644 --- a/code/ryzom/client/src/login_patch.cpp +++ b/code/ryzom/client/src/login_patch.cpp @@ -404,7 +404,7 @@ void CPatchManager::startCheckThread(bool includeBackgroundPatch) CheckThread = new CCheckThread(includeBackgroundPatch); nlassert (CheckThread != NULL); - thread = IThread::create (CheckThread); + thread = new CThread (CheckThread); nlassert (thread != NULL); thread->start (); } @@ -651,7 +651,7 @@ void CPatchManager::startPatchThread(const vector &CategoriesSelected, b } // Launch the thread - thread = IThread::create (PatchThread); + thread = new CThread (PatchThread); nlassert (thread != NULL); thread->start (); } @@ -1986,7 +1986,7 @@ void CPatchManager::startScanDataThread() ScanDataThread = new CScanDataThread(); nlassert (ScanDataThread != NULL); - thread = IThread::create (ScanDataThread); + thread = new CThread (ScanDataThread); nlassert (thread != NULL); thread->start (); } @@ -3259,7 +3259,7 @@ IAsyncDownloader* CPatchManager::getAsyncDownloader() const void CPatchManager::startInstallThread(const std::vector& entries) { CInstallThread* installThread = new CInstallThread(entries); - thread = IThread::create (installThread); + thread = new CThread (installThread); nlassert (thread != NULL); thread->start (); } @@ -3267,7 +3267,7 @@ void CPatchManager::startInstallThread(const std::vector& e void CPatchManager::startDownloadThread(const std::vector& entries) { CDownloadThread* downloadThread = new CDownloadThread(entries); - thread = IThread::create (downloadThread); + thread = new CThread (downloadThread); nlassert (thread != NULL); thread->start (); } diff --git a/code/ryzom/client/src/login_patch.h b/code/ryzom/client/src/login_patch.h index de7351775..b0748dbd2 100644 --- a/code/ryzom/client/src/login_patch.h +++ b/code/ryzom/client/src/login_patch.h @@ -245,7 +245,7 @@ public: CProductDescriptionForClient &getDescFile() { return DescFile; } - NLMISC::IThread *getCurrThread() const { return thread; } + NLMISC::CThread *getCurrThread() const { return thread; } // set an external state listener (enable to log) infos void setStateListener(IPatchManagerStateListener* stateListener); @@ -422,7 +422,7 @@ private: CCheckThread *CheckThread; CScanDataThread *ScanDataThread; CInstallThread *InstallThread; - NLMISC::IThread *thread; + NLMISC::CThread *thread; // State struct CState diff --git a/code/ryzom/client/src/login_progress_post_thread.cpp b/code/ryzom/client/src/login_progress_post_thread.cpp index bc833fb04..d36e1e65b 100644 --- a/code/ryzom/client/src/login_progress_post_thread.cpp +++ b/code/ryzom/client/src/login_progress_post_thread.cpp @@ -296,7 +296,7 @@ void CLoginProgressPostThread::init(const std::string &startupHost, const std::s lpt->StartupHost = startupHost; lpt->StartupPage = startupPage; _Task = lpt; - _Thread = IThread::create(lpt); + _Thread = new CThread(lpt); if (!_Thread) { release(); diff --git a/code/ryzom/client/src/login_progress_post_thread.h b/code/ryzom/client/src/login_progress_post_thread.h index feeaffcbc..ad047ae9f 100644 --- a/code/ryzom/client/src/login_progress_post_thread.h +++ b/code/ryzom/client/src/login_progress_post_thread.h @@ -69,7 +69,7 @@ public: // Send the msg (wait until the message is send) return the answer string std::string forceStep(const CLoginStep &ls); private: - NLMISC::IThread *_Thread; + NLMISC::CThread *_Thread; NLMISC::IRunnable *_Task; }; diff --git a/code/ryzom/client/src/session_browser.cpp b/code/ryzom/client/src/session_browser.cpp index 4cae87fee..ead346b6c 100644 --- a/code/ryzom/client/src/session_browser.cpp +++ b/code/ryzom/client/src/session_browser.cpp @@ -107,7 +107,7 @@ CSessionBrowser::CSessionBrowser() _WaitingForMessage(false) { // start the comm thread - _CommThread = IThread::create(this); + _CommThread = new CThread(this); _CommThread->start(); } diff --git a/code/ryzom/client/src/session_browser.h b/code/ryzom/client/src/session_browser.h index 3fd523778..0932ca0d5 100644 --- a/code/ryzom/client/src/session_browser.h +++ b/code/ryzom/client/src/session_browser.h @@ -47,7 +47,7 @@ class CSessionBrowser : public RSMGR::CSessionBrowserServerWebClientItf, friend class CCallbackClientAdaptor; // the comm thread object - NLMISC::IThread *_CommThread; + NLMISC::CThread *_CommThread; // the thread termination flag bool _TerminateComm; diff --git a/code/ryzom/server/src/entities_game_service/admin.cpp b/code/ryzom/server/src/entities_game_service/admin.cpp index 20941e77f..07380da43 100644 --- a/code/ryzom/server/src/entities_game_service/admin.cpp +++ b/code/ryzom/server/src/entities_game_service/admin.cpp @@ -3027,7 +3027,7 @@ void audit(const CAdminCommand *cmd, const string &rawCommand, const CEntityId & char params[1024]; sprintf(params, "action=audit&cmd=%s&raw=%s&name=(%s,%s)&target=%s", cmd->Name.c_str(), rawCommand.c_str(), eid.toString().c_str(), name.c_str(), targetName.c_str()); - IThread *thread = IThread::create(new CHttpPostTask(host, page, params)); + CThread *thread = new CThread(new CHttpPostTask(host, page, params)); thread->start(); } diff --git a/code/ryzom/server/src/entities_game_service/phrase_manager/fg_prospection_phrase.cpp b/code/ryzom/server/src/entities_game_service/phrase_manager/fg_prospection_phrase.cpp index 010176023..1d7ec2baa 100644 --- a/code/ryzom/server/src/entities_game_service/phrase_manager/fg_prospection_phrase.cpp +++ b/code/ryzom/server/src/entities_game_service/phrase_manager/fg_prospection_phrase.cpp @@ -1806,7 +1806,7 @@ public: return; _Stopping = false; _Complete = false; - _Thread = NLMISC::IThread::create( this ); + _Thread = new NLMISC::CThread( this ); _Thread->start(); } @@ -1842,7 +1842,7 @@ private: volatile bool _Stopping; volatile bool _Complete; - NLMISC::IThread *_Thread; + NLMISC::CThread *_Thread; }; diff --git a/code/ryzom/server/src/frontend_service/fe_receive_sub.cpp b/code/ryzom/server/src/frontend_service/fe_receive_sub.cpp index e2098d7b8..fa5ca98c8 100644 --- a/code/ryzom/server/src/frontend_service/fe_receive_sub.cpp +++ b/code/ryzom/server/src/frontend_service/fe_receive_sub.cpp @@ -129,7 +129,7 @@ void CFeReceiveSub::init( uint16 firstAcceptableFrontendPort, uint16 lastAccepta _CurrentReadQueue = &_Queue2; _ReceiveTask->setWriteQueue( &_Queue1 ); nlassert( _ReceiveTask != NULL ); - _ReceiveThread = IThread::create( _ReceiveTask ); + _ReceiveThread = new CThread( _ReceiveTask ); nlassert( _ReceiveThread != NULL ); _ReceiveThread->start(); diff --git a/code/ryzom/server/src/frontend_service/fe_receive_sub.h b/code/ryzom/server/src/frontend_service/fe_receive_sub.h index 6eedab09e..782f9a4a4 100644 --- a/code/ryzom/server/src/frontend_service/fe_receive_sub.h +++ b/code/ryzom/server/src/frontend_service/fe_receive_sub.h @@ -212,7 +212,7 @@ private: CFEReceiveTask *_ReceiveTask; /// Receive thread - NLMISC::IThread *_ReceiveThread; + NLMISC::CThread *_ReceiveThread; /// Client map by address THostMap _ClientMap; diff --git a/code/ryzom/server/src/frontend_service/frontend_service.cpp b/code/ryzom/server/src/frontend_service/frontend_service.cpp index e43b9ccce..18080591e 100644 --- a/code/ryzom/server/src/frontend_service/frontend_service.cpp +++ b/code/ryzom/server/src/frontend_service/frontend_service.cpp @@ -257,7 +257,7 @@ public: }; CSendRunnable SendTask; -IThread* SendThread = NULL; +CThread* SendThread = NULL; /* * Receive task @@ -1323,7 +1323,7 @@ void CFrontEndService::init() { // Init send thread nlinfo("UseSendThread on, initialise send thread"); - SendThread = IThread::create(&SendTask); + SendThread = new CThread(&SendTask); SendThread->start(); } diff --git a/code/ryzom/server/src/frontend_service/module_manager.cpp b/code/ryzom/server/src/frontend_service/module_manager.cpp index 24def9d18..e9929367d 100644 --- a/code/ryzom/server/src/frontend_service/module_manager.cpp +++ b/code/ryzom/server/src/frontend_service/module_manager.cpp @@ -59,7 +59,7 @@ CModuleManager::~CModuleManager() if (_Thread != NULL) { nlwarning("FEMMAN: [%s] Execution is not finished yet. Brutal thread killing", _StackName.c_str()); - _Thread->terminate(); + _Thread->wait(); // _Thread->terminate(); // FIXME: THREAD: Have a proper way to kill this thread delete _Thread; } } @@ -207,7 +207,7 @@ void CModuleManager::addWait(uint id) void CModuleManager::start() { - _Thread = IThread::create(this); + _Thread = new CThread(this); _StopThread = false; _ThreadStopped = false; @@ -284,7 +284,7 @@ void CModuleManager::stop(bool blockingMode, TTime timeout) if (!_ThreadStopped) { nlwarning("FEMMAN: [%s] Can't stop. Brutal thread killing", _StackName.c_str()); - _Thread->terminate(); + _Thread->wait(); // _Thread->terminate(); // FIXME: THREAD: Have a proper way to kill this thread } delete _Thread; diff --git a/code/ryzom/server/src/frontend_service/module_manager.h b/code/ryzom/server/src/frontend_service/module_manager.h index 60d7db851..4df1b83f0 100644 --- a/code/ryzom/server/src/frontend_service/module_manager.h +++ b/code/ryzom/server/src/frontend_service/module_manager.h @@ -90,7 +90,7 @@ private: /// The thread associated to this manager - NLMISC::IThread *_Thread; + NLMISC::CThread *_Thread; /// @name The stop flags //@{ diff --git a/code/ryzom/server/src/general_utilities_service/stdin_monitor_thread.cpp b/code/ryzom/server/src/general_utilities_service/stdin_monitor_thread.cpp index b5cae3c35..a3d08c761 100644 --- a/code/ryzom/server/src/general_utilities_service/stdin_monitor_thread.cpp +++ b/code/ryzom/server/src/general_utilities_service/stdin_monitor_thread.cpp @@ -133,7 +133,7 @@ public: private: CStdinMonitorThread* _StdinMonitorThreadInstance; - NLMISC::IThread* _StdinMonitorThreadHandle; + NLMISC::CThread* _StdinMonitorThreadHandle; }; CStdinMonitorSingleton StdinMonitorSingleton; @@ -146,7 +146,7 @@ CStdinMonitorSingleton StdinMonitorSingleton; void CStdinMonitorSingleton::init() { _StdinMonitorThreadInstance= new CStdinMonitorThread; - _StdinMonitorThreadHandle = NLMISC::IThread::create (_StdinMonitorThreadInstance); + _StdinMonitorThreadHandle = new NLMISC::CThread (_StdinMonitorThreadInstance); _StdinMonitorThreadHandle->start(); } @@ -161,6 +161,6 @@ void CStdinMonitorSingleton::serviceUpdate() void CStdinMonitorSingleton::release() { - _StdinMonitorThreadHandle->terminate(); + _StdinMonitorThreadHandle->wait(); // _StdinMonitorThreadHandle->terminate(); // FIXME: THREAD: Have a proper way to kill this thread } diff --git a/code/ryzom/server/src/log_analyser_service/log_analyser_service.cpp b/code/ryzom/server/src/log_analyser_service/log_analyser_service.cpp index 3725299d6..2c849f801 100644 --- a/code/ryzom/server/src/log_analyser_service/log_analyser_service.cpp +++ b/code/ryzom/server/src/log_analyser_service/log_analyser_service.cpp @@ -215,7 +215,7 @@ bool CLogAnalyserService::update() LogTask.Query = _Current; - _Thread = IThread::create(&LogTask); + _Thread = new CThread(&LogTask); _Thread->start(); } _Mutex.leave(); diff --git a/code/ryzom/server/src/log_analyser_service/log_analyser_service.h b/code/ryzom/server/src/log_analyser_service/log_analyser_service.h index 1bddb5b81..35c56a6f7 100644 --- a/code/ryzom/server/src/log_analyser_service/log_analyser_service.h +++ b/code/ryzom/server/src/log_analyser_service/log_analyser_service.h @@ -105,7 +105,7 @@ private: NLMISC::CMutex _Mutex; - NLMISC::IThread* _Thread; + NLMISC::CThread* _Thread; CQuery* _Current; diff --git a/code/ryzom/server/src/logger_service/logger_service.cpp b/code/ryzom/server/src/logger_service/logger_service.cpp index dba4cae57..11666544a 100644 --- a/code/ryzom/server/src/logger_service/logger_service.cpp +++ b/code/ryzom/server/src/logger_service/logger_service.cpp @@ -390,7 +390,7 @@ class CLoggerServiceMod friend class CLoggerServiceMod::CQueryThread; /// the query thread - IThread *_QueryThread; + CThread *_QueryThread; @@ -430,7 +430,7 @@ public: consolidatePreviousFiles(); // start the query thread - _QueryThread = IThread::create(new CQueryThread(this)); + _QueryThread = new CThread(new CQueryThread(this)); _QueryThread->start(); return true; diff --git a/code/ryzom/server/src/pd_reference_builder/reference_builder_service.cpp b/code/ryzom/server/src/pd_reference_builder/reference_builder_service.cpp index 6bb687e8e..d8467dbe4 100644 --- a/code/ryzom/server/src/pd_reference_builder/reference_builder_service.cpp +++ b/code/ryzom/server/src/pd_reference_builder/reference_builder_service.cpp @@ -338,7 +338,7 @@ void CReferenceBuilderService::killTasks(TServiceId serviceId) void IRefTask::start() { - _Thread = IThread::create(this); + _Thread = new CThread(this); _Thread->start(); } diff --git a/code/ryzom/server/src/pd_reference_builder/reference_builder_service.h b/code/ryzom/server/src/pd_reference_builder/reference_builder_service.h index 9f8a04676..2770de597 100644 --- a/code/ryzom/server/src/pd_reference_builder/reference_builder_service.h +++ b/code/ryzom/server/src/pd_reference_builder/reference_builder_service.h @@ -75,7 +75,7 @@ public: private: - NLMISC::IThread *_Thread; + NLMISC::CThread *_Thread; };