00001
00004
00005
00006 #include "stdafx.h"
00007 #include "WaitCallback.h"
00008
00010
00012
00016 WaitCallback::WaitCallback()
00017 {
00018 waitEvents[0] = CreateEvent(NULL, true, false, NULL);
00019 waitEvents[1] = INVALID_HANDLE_VALUE;
00020 }
00021
00025 WaitCallback::~WaitCallback()
00026 {
00027 unregisterWait();
00028 CloseHandle(waitEvents[0]);
00029 CloseHandle(waitEvents[1]);
00030 }
00031
00033
00035
00039 bool WaitCallback::hasWaitRegistered() const
00040 {
00041 return waitEvents[1] != INVALID_HANDLE_VALUE;
00042 }
00043
00059 bool WaitCallback::registerWaitForSingleObject(
00060 HANDLE hEvent,
00061 const WAITCALLBACK cB,
00062 const PVOID cBP,
00063 const DWORD tO,
00064 const bool once)
00065 {
00066 if( hasWaitRegistered() )
00067 return false;
00068
00069 hWaitThread = chBEGINTHREADEX(
00070 NULL,
00071 0,
00072 &waitThread,
00073 this,
00074 CREATE_SUSPENDED,
00075 NULL);
00076
00077 if(hWaitThread == NULL)
00078 return false;
00079
00080
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]);
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:
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