I think this can do the trick. Derive the Event class and overload the Process () function.
Here are the classes that do magic.
namespace os { // ********************************************************************** /// Windows implementation to spawn a thread. static uintptr_t Thread (void (*StartAddress)(void *), void *ArgList) { return _beginthread(StartAddress, 0, ArgList); } // ********************************************************************** /// Windows implementation of a critical section. class Mutex { public: // Initialize section on construction Mutex() { InitializeCriticalSection( &cs_ ); } // Delete section on destruction ~Mutex() { DeleteCriticalSection( &cs_ ); } // Lock it void lock() { EnterCriticalSection( &cs_ ); } // Unlock it void unlock() { LeaveCriticalSection( &cs_ ); } private: CRITICAL_SECTION cs_; }; // class Mutex /// Locks/Unlocks a mutex class Locker { public: // Lock the mutex on construction Locker( Mutex& mutex ): mutex_( mutex ) { mutex_.lock(); } // Unlock on destruction ~Locker() { mutex_.unlock(); } private: Mutex& mutex_; }; // class Locker // ********************************************************************** // Windows implementation of event handler #define ProcessEvent hEvents[0] #define SetTimerEvent hEvents[1] #define ShutdownEvent hEvents[2] /// Windows implementation of events class Event { /// Flag set when shutdown is complete bool Shutdown; /// Max time to wait for events DWORD Timer; /// The three events - process, reset timer, and shutdown HANDLE hEvents[3]; public: /// Timeout is disabled by default and Events assigned Event( DWORD timer = INFINITE) : Timer(timer) { Shutdown = false; ProcessEvent = CreateEvent( NULL,TRUE,FALSE,NULL ); SetTimerEvent = CreateEvent( NULL,TRUE,FALSE,NULL ); ShutdownEvent = CreateEvent( NULL,TRUE,FALSE,NULL ); } /// Close the event handles virtual ~Event() { CloseHandle(ProcessEvent); CloseHandle(SetTimerEvent); CloseHandle(ShutdownEvent); } /// os::Thread calls this to start the Event handler static void StartEventHandler(void *pMyInstance) { ((Event *)pMyInstance)->EventHandler(); } /// Call here to Change/Reset the timeout timer void ResetTimer(DWORD timer) { Timer = timer; SetEvent(SetTimerEvent); } /// Set the signal to shutdown the worker thread processing events void SignalShutdown() { SetEvent(ShutdownEvent); while (!Shutdown) Sleep(30);} /// Set the signal to run the process void SignalProcess() { SetEvent(ProcessEvent); } protected: /// Overload in derived class to process events with worker thread virtual void Process(){} /// Override to process timeout- return true to terminate thread virtual bool Timeout(){ return true;} /// Monitor thread events void EventHandler() { DWORD WaitEvents; while (!Shutdown) { // Wait here, looking to be signaled what to do next WaitEvents = WaitForMultipleObjects(3, hEvents, FALSE, Timer); switch (WaitEvents) { // Process event - process event then reset for the next one case WAIT_OBJECT_0 + 0: Process(); ResetEvent(ProcessEvent); break; // Change timer event - see ResetTimer(DWORD timer) case WAIT_OBJECT_0 + 1: ResetEvent(SetTimerEvent); continue; // Shutdown requested so exit this thread case WAIT_OBJECT_0 + 2: Shutdown = true; break; // Timed out waiting for an event case WAIT_TIMEOUT: Shutdown = Timeout(); break; // Failed - should never happen case WAIT_FAILED: break; default: break; } } } }; } // namespace os
source share