Main Page   Modules   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

WaitCallback.cpp

Go to the documentation of this file.
00001 // WaitCallback.cpp: implementation of the WaitCallback class.
00004 
00005 
00006 #include "stdafx.h"
00007 #include "WaitCallback.h"
00008 
00010 // Construction/Destruction
00012 
00016 WaitCallback::WaitCallback()
00017 {
00018     waitEvents[0] = CreateEvent(NULL, true, false, NULL);
00019     waitEvents[1] = INVALID_HANDLE_VALUE;   // Important, see hasWaitRegistered
00020 }
00021 
00025 WaitCallback::~WaitCallback()
00026 {
00027     unregisterWait();
00028     CloseHandle(waitEvents[0]);
00029     CloseHandle(waitEvents[1]);
00030 }
00031 
00033 // Member Functions
00035 
00039 bool WaitCallback::hasWaitRegistered() const
00040 {
00041     return waitEvents[1] != INVALID_HANDLE_VALUE;
00042 }
00043 
00059 bool WaitCallback::registerWaitForSingleObject(
00060     HANDLE hEvent,      // handle to wait object (takes possesion)
00061     const WAITCALLBACK cB,  // callback function        
00062     const PVOID cBP,    // callback context 
00063     const DWORD tO,     // time-out interval
00064     const bool once)    // execute just once?
00065 {
00066     if( hasWaitRegistered() )
00067         return false;
00068 
00069     hWaitThread = chBEGINTHREADEX(
00070         NULL,           // Default Security, non inheritable
00071         0,              // use default stack size  
00072         &waitThread,    // thread function
00073         this,           // thread argument
00074         CREATE_SUSPENDED,   // Create suspended
00075         NULL);          // don't need thread identifier
00076 
00077     if(hWaitThread == NULL)
00078         return false;
00079 
00080     // Take possesion of the event handle
00081     waitEvents[1] = hEvent;
00082     cBack = cB;
00083     cBackParam = cBP;
00084     timeOut = tO;
00085     justOnce = once;
00086 
00087     ResumeThread(hWaitThread);
00088 
00089     return true;
00090 }
00091 
00095 void WaitCallback::unregisterWait()
00096 {
00097     if( hasWaitRegistered() ){
00098         SetEvent(waitEvents[0]);    // Signal waitThread to exit
00099 
00100         if( WaitForSingleObject(hWaitThread, 6000) == WAIT_TIMEOUT ){
00101             TerminateThread(hWaitThread, 0);
00102             chMB("Warning couldn't unregister a wait gracefully.\nCheck for Deadlock");
00103         }
00104 
00105         CloseHandle(waitEvents[1]);
00106         waitEvents[1] = INVALID_HANDLE_VALUE;
00107         CloseHandle(hWaitThread);
00108         ResetEvent(waitEvents[0]);
00109     }
00110 }
00111 
00115 DWORD WINAPI WaitCallback::waitThread(LPVOID param)
00116 {
00117     WaitCallback* thisWait = (WaitCallback*) param;
00118 
00119     do{
00120         switch( WaitForMultipleObjects(2, thisWait->waitEvents, false, thisWait->timeOut) ) {
00121         case WAIT_OBJECT_0: // wait is being unregistered
00122             return true;
00123             break;
00124         case WAIT_FAILED:
00125             assert(WAIT_FAILED != WAIT_FAILED);
00126             return false;
00127             break;
00128         case WAIT_TIMEOUT:
00129             (*thisWait->cBack)(thisWait->cBackParam, true);
00130             break;
00131         default:
00132             (*thisWait->cBack)(thisWait->cBackParam, false);
00133             break;
00134         }
00135 
00136     } while ( !thisWait->justOnce );
00137     
00138     return true;
00139 }
00140 
00141 

Generated on Mon Mar 25 06:29:59 2002 for Window Dressing by doxygen1.2.13.1 written by Dimitri van Heesch, © 1997-2001