Ejemplo n.º 1
0
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);
		}
	}
Ejemplo n.º 3
0
/* 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));
}