Win32API ユーザーモード非同期プロシージャ呼び出し QueueUserAPC, WaitForSingleObjectEx
QueueUserAPCにより、FindFirstChangeNotification, FindNextChangeNotificationによるファイルシステムの変更イベントを待機している状態から、無理矢理制御を返すようにする
DWORD WaitForSingleObjectEx( HANDLE hHandle, // オブジェクトのハンドル DWORD dwMilliseconds, // タイムアウト時間 BOOL bAlertable // アラート可能な待機のオプション ); 参考:http://msdn.microsoft.com/ja-jp/library/cc429429.aspx
使用するAPI
#include <windows.h> #include <process.h> void WINAPI APCFunc(ULONG_PTR arg) { printf("APCFunc is called\n"); } UINT WINAPI ThreadFunc(LPVOID arg) { HANDLE hNotify; DWORD dwFilter; DWORD dwRet; //ファイル名の変更イベントを検知するように設定する dwFilter = FILE_NOTIFY_CHANGE_FILE_NAME; hNotify = FindFirstChangeNotification( "C:\\", TRUE, dwFilter); if (hNotify == INVALID_HANDLE_VALUE) { return 1; } do { dwRet = WaitForSingleObjectEx( hNotify, INFINITE, TRUE); switch (dwRet) { //ファイルシステムの変更イベントにより //WaitForSingleObjectExから制御が //返されると戻り値として //WAIT_OBJECT_0が返される case WAIT_OBJECT_0: puts("WAIT_OBJECT_0"); break; case WAIT_ABANDONED: puts("WAIT_ABANDONED"); break; case WAIT_IO_COMPLETION: //QueueUserAPC呼び出しにより、 //WaitForSingleObjectExから制御が //返ると、戻り値として //WAIT_IO_COMPLETION が返される。 puts("WAIT_IO_COMPLETION"); break; case WAIT_TIMEOUT: puts("WAIT_TIMEOUT"); break; } //QueueUserAPCの呼び出しにより、 //WaitForSingleObjectExから制御が //返されたら、ループから脱出する if (dwRet == WAIT_IO_COMPLETION) { break; } } while (FindNextChangeNotification(hNotify)); FindCloseChangeNotification(hNotify); return 0; } int main() { HANDLE hThread; UINT uiThreadId; //スレッドを起動 hThread = (HANDLE)_beginthreadex(NULL, 0, ThreadFunc, NULL, 0, &uiThreadId); Sleep(2000); //QueueUserAPCを呼び出すことにより、 //ThreadFunc関数中のWaitForSingleObjectExから //制御が返される QueueUserAPC(APCFunc, hThread, 0); //スレッドの終了を待つ WaitForSingleObject(hThread, INFINITE); //スレッドのハンドルを閉じる CloseHandle(hThread); return 0; }