///////////////////////////////////////////////////////////////////////////// // Creation 18/12/2003 // // // APC.C // ----- // // // Sylvain MARECHAL - sylvain.marechal1@libertysurf.fr ///////////////////////////////////////////////////////////////////////////// // // Show how to use APC // ///////////////////////////////////////////////////////////////////////////// #define _WIN32_WINNT 0x0400 #include #include #include #include //write static CRITICAL_SECTION s_CriticalSection; ///////////////////////////////////////////////////////////////////////////// // // PRINTMESSAGE ///////////////////////////////////////////////////////////////////////////// // // DESCRIPTION // --PrintMessage-- // ARGUMENTS // Argument1: char * pszMessage // RETOUR/RESULTAT // void // REMARQUE // Rev 16/12/2003 ////////////////////////////////////////////////////////////////////////////// void PrintMessage( char * pszMessage ) { // printf not thread safe EnterCriticalSection( &s_CriticalSection ); write( 1, pszMessage, strlen(pszMessage) ); LeaveCriticalSection( &s_CriticalSection ); } ///////////////////////////////////////////////////////////////////////////// // // THREADPROC ///////////////////////////////////////////////////////////////////////////// // // DESCRIPTION // --ThreadProc-- // // The thread function // // ARGUMENTS // Argument1: LPVOID lpParameter // RETOUR/RESULTAT // DWORD WINAPI // REMARQUE // Rev 16/12/2003 ////////////////////////////////////////////////////////////////////////////// DWORD WINAPI ThreadProc( LPVOID lpParameter ) { char * pszString = (char *)lpParameter; char szBuffer[1024]; // A message sprintf( szBuffer, "Thread '%s' (%d) is created\n", pszString, GetCurrentThreadId() ); PrintMessage( szBuffer ); while( 1 ) { // A message to display before the APC is processed sprintf( szBuffer, "Thread '%s' (%d): Before SleepEx()\n", pszString, GetCurrentThreadId() ); PrintMessage( szBuffer ); // Wait 2 seconds for an APC. If no APC in 2 secons, then exit this thread if( SleepEx( 2000, TRUE ) != WAIT_IO_COMPLETION ) { sprintf( szBuffer, "Prepare to exit the thread '%s' (%d)\n", pszString, GetCurrentThreadId() ); PrintMessage( szBuffer ); return 0; } // A message to display after the APC is processed sprintf( szBuffer, "Thread '%s' (%d): After SleepEx()\n", pszString, GetCurrentThreadId() ); PrintMessage( szBuffer ); } // Never reached return 1; } ///////////////////////////////////////////////////////////////////////////// // // APCPROC ///////////////////////////////////////////////////////////////////////////// // // DESCRIPTION // --APCProc-- // // The APC callback // // ARGUMENTS // Argument1: DWORD dwData // RETOUR/RESULTAT // void WINAPI // REMARQUE // Rev 18/12/2003 ////////////////////////////////////////////////////////////////////////////// void WINAPI APCProc( DWORD dwData ) { char * pszBuffer = (char *)dwData; char szBuffer[1024]; sprintf( szBuffer, "APCProc (In thread %d): message is '%s'\n", GetCurrentThreadId(), pszBuffer ); PrintMessage( szBuffer ); } ///////////////////////////////////////////////////////////////////////////// // // MAIN ///////////////////////////////////////////////////////////////////////////// // // DESCRIPTION // --main-- // ARGUMENTS // RETOUR/RESULTAT // int // REMARQUE // Rev 16/12/2003 ////////////////////////////////////////////////////////////////////////////// int main() { HANDLE ahThread[2]; DWORD aIDThread[2]; char * aszString[] = { "Thread 1", "Thread 2" }; char szBuffer[1024]; int i; DWORD dwWait; // Initialize the critical section used by printMessage InitializeCriticalSection( &s_CriticalSection ); // Create the threads, and give a string as arguments for( i = 0; i < 2; i ++ ) { ahThread[i] = CreateThread( NULL, 0, ThreadProc, (LPVOID)aszString[i], 0, &aIDThread[i] ); if( ! ahThread[i] ) { sprintf( szBuffer, "CreateThread() error %d\n", GetLastError() ); PrintMessage( szBuffer ); return 1; } } // Send some messages to thread for( i = 0; i < 10; i ++ ) { // Print a message sprintf( szBuffer, "Message to thread '%s' (%d)", aszString[i%2], aIDThread[i%2] ); QueueUserAPC( APCProc, ahThread[i%2], (DWORD)szBuffer ); } // Wait for the thread end PrintMessage( "Before WaitForSingleObject() - 2\n" ); dwWait = WaitForMultipleObjects( 2, ahThread, TRUE, INFINITE ); if( dwWait != WAIT_OBJECT_0 ) { sprintf( szBuffer, "WaitForSingleObject() error %d (dwWait=%d)\n", GetLastError(), dwWait ); PrintMessage( szBuffer ); return 1; } // Destroy crtical section DeleteCriticalSection( &s_CriticalSection ); // printf( "Prepare to exit this example ...\n" ); getch(); return 0; }