static void waitForThreads() { // Wait for all threads to be created. while (NumOfThreads() != ROLE_SIZE) { DoYield(); } // Wait for the ROLE_CANCELED thread to be ready for cancelation while (!readyToCancel) { DoYield(); } // Send a cancel request to the ROLE_CANCELED thread. CancelThread(threads[ROLE_CANCELED]); // Wait for all threads that are supposed to exit. WaitForThread(threads[ROLE_FINISH]); WaitForThread(threads[ROLE_EXIT]); // The timing of the effect of pthread_cancel is undefined, this could cause the aplication to hang. // Currently commented out. WaitForThread(threads[ROLE_CANCELED]); }
static void waitOrExit() { switch(exitType) { case EXIT_TOOL_APP: doExit(true); // never returns case EXIT_TOOL_INTERNAL: doExit(false); // never returns case EXIT_RETURN: return; case EXIT_MAIN_EXIT: Print("main thread is calling exit()"); // FOR DEBUG exit(RES_SUCCESS); case EXIT_SEC_EXIT: while (1) { DoYield(); // wait here for the ROLE_EXIT thread to call exit() } } }
/************************************************** * Secondary threads main function * **************************************************/ void* DoNewThread(void* threadNumArg) { int threadNum = *((int*)threadNumArg); Print(roleStrings[threadNum] + " thread was created succesfully."); // FOR DEBUG IncThreads(); switch (threadNum) { case ROLE_WAIT: DoSleep(1000); ErrorExit(RES_EXIT_TIMEOUT); // the ROLE_WAIT thread reached its timeout of 1000 seconds - something is wrong case ROLE_LOOP: while (1); // never exits from here break; case ROLE_FINISH: break; // exits normally, process continues case ROLE_EXIT: if (exitType == EXIT_SEC_EXIT) { while (NumOfThreads() != ROLE_SIZE) { DoYield(); // wait here until all threads are ready } Print("ROLE_EXIT thread is calling exit()"); // FOR DEBUG // exit and kill the entire process exit(RES_SUCCESS); // never returns } // thread exits but process continues ThreadExit(); // never returns case ROLE_CANCELED: // On Windows, this thread will be canceled using the TerminateThread API. The documentation states that // it is unsafe to use this function if the target thread is executing certain kernel32 calls etc. // On Linux, the thread must enter a function which is defined as a cancellation point. See pthreads entry // in the chapter 7 of the manual for further details. readyToCancel = true; EnterSafeCancellationPoint(); } return NULL; }
void* DoDummyThread(void* dummy) { IncThreads(); DoYield(); return NULL; }
// The tool will kill the process, either by the main thread or an internal tool thread. void doExit(bool appThread) { Print("main thread is in doExit"); while (1) { // wait here until the tool kills the process DoYield(); } }