int CFSThread::WaitForEnd() { if (m_hThread) { #if defined (WIN32) WaitForSingleObjectEx(m_hThread, INFINITE, false); CloseHandle(m_hThread); #elif defined (UNIX) pthread_join(m_hThread, 0); #elif defined (MAC) OSStatus err; MPWaitOnQueue(m_WaitQueue, NULL, NULL, (void**) &err, kDurationForever); #endif } return 0; }
void wxThreadInternal::Wait() { wxCHECK_RET( !m_isDetached, wxT("can't wait for a detached thread") ); // if the thread we're waiting for is waiting for the GUI mutex, we will // deadlock so make sure we release it temporarily if ( wxThread::IsMain() ) { // give the thread we're waiting for chance to do the GUI call // it might be in, we don't do this conditionally as the to be waited on // thread might have to acquire the mutex later but before terminating if ( wxGuiOwnedByMainThread() ) wxMutexGuiLeave(); } { wxCriticalSectionLocker lock(m_csJoinFlag); if ( m_shouldBeJoined ) { void *param1, *param2, *rc; OSStatus err = MPWaitOnQueue( m_notifyQueueId, ¶m1, ¶m2, &rc, kDurationForever ); if (err != noErr) { wxLogSysError( wxT( "Cannot wait for thread termination.")); rc = (void*) -1; } // actually param1 would be the address of m_exitcode // but we don't need this here m_exitcode = rc; m_shouldBeJoined = false; } } }
void cFUThread::StopThread() { assert(thread != cFUThread_INVALID); isSuspendedCS.Enter(); terminate = true; bool _isSuspended = isSuspended; isSuspendedCS.Leave(); if (_isSuspended) StartThread(); //The real function will not start because terminate = true; #if defined(WIN32) WaitForSingleObject(thread, INFINITE); CloseHandle(thread); // delete the thread once it's finished #elif defined (FP_APPLE) OSStatus status; //MPTerminateTask(thread, status); status = MPWaitOnQueue(queue, nullptr, nullptr, nullptr, kDurationForever); status = MPDeleteQueue(queue); #elif defined(LINUX) || defined(IOS)|| defined(ANDROID) pthread_join(thread, nullptr); #endif thread = cFUThread_INVALID; }
static void SendFlowControlTest(void) { OSStatus err; OSStatus junk; MPQueueID deathQueue; MPTaskID rcvTask; MPTaskID sndTask; gRcvStarted = false; gLookerEP = NULL; gQuitLooker = false; deathQueue = kInvalidID; err = MPCreateQueue(&deathQueue); if (err == noErr) { err = MPCreateTask(SFCRcv, NULL, 65536, deathQueue, (void *) 1, (void *) 666, kNilOptions, &rcvTask); } if (err == noErr) { MPLogPrintf("Waiting for receiver to start.\n"); while ( ! gRcvStarted ) { printf("."); fflush(stdout); } MPLogPrintf("\n"); } if (err == noErr) { err = MPCreateTask(SFCSnd, NULL, 65536, deathQueue, (void *) 2, (void *) 666, kNilOptions, &sndTask); } if (err == noErr) { err = MPCreateTask(SFCLooker, NULL, 65536, deathQueue, (void *) 3, (void *) 666, kNilOptions, &rcvTask); } if (err == noErr) { UInt32 terminatedTaskCount; UInt32 taskNumber; OSStatus taskStatus; UInt32 lastPrinted; lastPrinted = 0; terminatedTaskCount = 0; do { err = MPWaitOnQueue(deathQueue, (void **) &taskNumber, NULL, (void **) &taskStatus, kDurationImmediate); if (err == noErr) { MPLogPrintf("Task number %ld completed with status %ld.\n", taskNumber, taskStatus); terminatedTaskCount += 1; } else if (err == kMPTimeoutErr) { #if !TARGET_API_MAC_CARBON SystemTask(); #endif if (TickCount() > (lastPrinted + 60)) { printf("."); fflush(stdout); lastPrinted = TickCount(); } err = noErr; } } while ( (err == noErr) && (terminatedTaskCount < 3) ); } // Clean up. if (deathQueue != kInvalidID) { junk = MPDeleteQueue(deathQueue); assert(junk == noErr); } printf("gLookCounter = %ld\n", gLookCounter); gLookCounter = 0; if (err == noErr) { printf("Success!\n"); } else { printf("Failed with error %ld.\n", err); } }