bool FSEventsEventPublisher::isStreamRunning() const { if (stream_ == nullptr || !stream_started_ || run_loop_ == nullptr) { return false; } return CFRunLoopIsWaiting(run_loop_); }
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // Reset() //----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- void CFMachPortThread::Reset(CFMachPortCallBack portCallBack, void* userData) { // Wait for the thread to be running or invalid prior to tearing it down. while (kStarting == mState) pthread_yield_np(); if (kRunning == mState) { // Wait for the thread's run loop to be "waiting." This will avoid a small window of having set 'mState = kRunning' but not having invoked CFRunLoopRun() yet. while (not CFRunLoopIsWaiting(mRunLoop.GetCFObject())) pthread_yield_np(); // Stop the thread's run loop CFRunLoopStop(mRunLoop.GetCFObject()); // Set the thread's state to kStopping mState = kStopping; // Wait for the thread to run to completion (it will set the state to kInvalid) while (kStopping == mState) { (void) pthread_cond_signal(mStoppingCondition); pthread_yield_np(); } } mPort = MACH_PORT_NULL; mPortCallBack = 0; mUserData = 0; mPThread = 0; mRunLoop = 0; mState = kInvalid; if (0 != portCallBack) { typedef void* (*PThreadStart)(void*); mPortCallBack = portCallBack; mUserData = userData; mState = kStarting; int err = pthread_create(&mPThread, 0, reinterpret_cast<PThreadStart>(Start), this); ThrowIfError(err, CAException(err), "CMIO::PTA::CFMachPortThread::Reset: pthread_create() failed"); (void) pthread_detach(mPThread); } }
/* CF_EXPORT */ void CFNetServiceBrowserStopSearch(CFNetServiceBrowserRef b, CFStreamError* error) { __CFNetServiceBrowser* browser = (__CFNetServiceBrowser*)b; // By default, the error is marked as a cancel CFStreamError extra = {kCFStreamErrorDomainNetServices , kCFNetServicesErrorCancel}; // Make sure error has a value. if (!error) error = &extra; // Lock down the browser __CFSpinLock(&(browser->_lock)); // Make sure there is something to cancel. if (browser->_trigger) { CFRunLoopSourceContext ctxt = { 0, // version browser, // info NULL, // retain NULL, // release NULL, // copyDescription NULL, // equal NULL, // hash NULL, // schedule NULL, // cancel (void(*)(void*))(&_BrowserCancel) // perform }; // Remove the trigger from run loops and modes _CFTypeUnscheduleFromMultipleRunLoops(browser->_trigger, browser->_schedules); // Go ahead and invalidate the trigger _CFTypeInvalidate(browser->_trigger); // Release the trigger now. CFRelease(browser->_trigger); // Need to clean up the service discovery stuff if there is if (browser->_browse) { // Release the underlying service discovery reference DNSServiceRefDeallocate(browser->_browse); browser->_browse = NULL; // Dump all the lists of items. CFDictionaryRemoveAllValues(browser->_found); CFArrayRemoveAllValues(browser->_adds); CFArrayRemoveAllValues(browser->_removes); } // Copy the error into place memmove(&(browser->_error), error, sizeof(error[0])); // Create the cancel source browser->_trigger = CFRunLoopSourceCreate(CFGetAllocator(browser), 0, &ctxt); // If the cancel was created, need to schedule and signal it. if (browser->_trigger) { CFArrayRef schedules = browser->_schedules; CFIndex i, count = CFArrayGetCount(schedules); // Schedule the new trigger _CFTypeScheduleOnMultipleRunLoops(browser->_trigger, schedules); // Signal the cancel for immediate attention. CFRunLoopSourceSignal((CFRunLoopSourceRef)(browser->_trigger)); // Make sure the signal can make it through for (i = 0; i < count; i += 2) { // Grab the run loop for checking CFRunLoopRef runloop = (CFRunLoopRef)CFArrayGetValueAtIndex(schedules, i); // If it's sleeping, need to further check it. if (CFRunLoopIsWaiting(runloop)) { // Grab the mode for further check CFStringRef mode = CFRunLoopCopyCurrentMode(runloop); if (mode) { // If the trigger is in the right mode, need to wake up the run loop. if (CFRunLoopContainsSource(runloop, (CFRunLoopSourceRef)(browser->_trigger), mode)) { CFRunLoopWakeUp(runloop); } // Don't need this anymore. CFRelease(mode); } } } } } // Unlock the browser __CFSpinUnlock(&(browser->_lock)); }