// ThreadManager.h // // Revision Log // // Date Who SAR Notes // ========== === ======= ===================================== // 2000-12-21 mph Initial coding by Mark Henri of // MPH Software - markhenri@attbi.com // 2001-10-18 mph revamp all the logic; make dynamic types // 2001-10-26 mph Change again; create global logic // // A good place to put a loop for ensuring the completion of all // threads is right after the message loop just before program // exit. Beware of trying to second guess your program's message // logic; especially with MDI apps. // // note: once you've put this into a project, find all occurances // of CThreadTracker in the code and make sure that none of // the thread type numbers you've assigned is duplicated or // out of range. // #ifdef SAMPLE_CODE void myThread(void*) { CThreadTracker tt(0 /* thread type */); // defaults to 0 // more code here } // putting this after the message loop could save your life-- // blocks until all threads are finished. if (! g_threadManager.WaitForThreadsToTerminate()) throw WinException("still waiting on active threads to terminate", __FILE__, __LINE__); #endif #ifndef ACTIVETHREADCOUNT_H__ #define ACTIVETHREADCOUNT_H__ #include "CriticalSection.h" #if _MSC_VER >= 1000 #pragma once #endif // _MSC_VER >= 1000 class CThreadManager { public: CThreadManager(); virtual ~CThreadManager(); friend class CThreadTracker; void SetTypes(int numberOfTypes); // reallocation resets all counts int GetTypes() { return types; } int GetActiveThreads(int type=-1); // -1 == all bool WaitForThreadsToTerminate(int SecondsMax=60); // one minute default private: CThreadManager(CThreadManager&); // not allowed operator=(CThreadManager&); // also, not allowed int Increment(int threadType=0); int Decrement(int threadType=0); void InitializeCounts(); virtual void Changed() {;} // override with specialized "callback" behavior CCriticalSection criticalSection; int* active; int types; }; #ifdef IN_THREADMANAGER_CPP CThreadManager g_threadManager; // global variable #else extern CThreadManager g_threadManager; #endif class CThreadTracker { public: CThreadTracker(int threadType=0) { g_threadManager.Increment(_threadType = threadType); } ~CThreadTracker() { g_threadManager.Decrement(_threadType); } protected: private: CThreadTracker(CThreadTracker&); // not allowed operator=(CThreadTracker&); // also not allowed int _threadType; }; #endif