CFPreferencesDomainRef _CFPreferencesStandardDomain(CFStringRef  domainName, CFStringRef  userName, CFStringRef  hostName) {
    CFPreferencesDomainRef domain;
    CFStringRef  domainKey;
    Boolean shouldReleaseDomain = true;
     domainKey = _CFPreferencesStandardDomainCacheKey(domainName, userName, hostName);
    __CFSpinLock(&domainCacheLock);
    if (!domainCache) {
        CFAllocatorRef alloc = __CFPreferencesAllocator();
        domainCache = CFDictionaryCreateMutable(alloc, 0, & kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
    }
    domain = (CFPreferencesDomainRef)CFDictionaryGetValue(domainCache, domainKey);
    __CFSpinUnlock(&domainCacheLock);
    if (!domain) {
        // Domain's not in the cache; load from permanent storage
		CFURLRef  theURL = _CFPreferencesURLForStandardDomain(domainName, userName, hostName);
        if (theURL) {
			domain = _CFPreferencesDomainCreate(theURL, &__kCFXMLPropertyListDomainCallBacks);

            if (userName == kCFPreferencesAnyUser) {
                _CFPreferencesDomainSetIsWorldReadable(domain, true);
            }
            CFRelease(theURL);
        }
	__CFSpinLock(&domainCacheLock);
        if (domain && domainCache) {
            // We've just synthesized a domain & we're about to throw it in the domain cache. The problem is that someone else might have gotten in here behind our backs, so we can't just blindly set the domain (3021920). We'll need to check to see if this happened, and compensate.
            CFPreferencesDomainRef checkDomain = (CFPreferencesDomainRef)CFDictionaryGetValue(domainCache, domainKey);
            if(checkDomain) {
                // Someone got in here ahead of us, so we shouldn't smash the domain we're given. checkDomain is the current version, we should use that.
                // checkDomain was retrieved with a Get, so we don't want to over-release.
                shouldReleaseDomain = false;
                CFRelease(domain);	// release the domain we synthesized earlier.
                domain = checkDomain;	// repoint it at the domain picked up out of the cache.
            } else {
                // We must not have found the domain in the cache, so it's ok for us to put this in.
                CFDictionarySetValue(domainCache, domainKey, domain);                
            }
            if(shouldReleaseDomain) CFRelease(domain);
        }
	__CFSpinUnlock(&domainCacheLock);
    }
    CFRelease(domainKey);
    return domain;
}
void CFErrorSetCallBackForDomain(CFStringRef domainName, CFErrorUserInfoKeyCallBack callBack) {
    if (!_CFErrorCallBackTable) _CFErrorInitializeCallBackTable();
    __CFSpinLock(&_CFErrorSpinlock);
    if (callBack) {
        CFDictionarySetValue(_CFErrorCallBackTable, domainName, callBack);
    } else {
        CFDictionaryRemoveValue(_CFErrorCallBackTable, domainName);
    }
    __CFSpinUnlock(&_CFErrorSpinlock);
}
void _CFApplicationPreferencesAddDomain(_CFApplicationPreferences *self, CFPreferencesDomainRef domain, Boolean addAtTop) {
    __CFSpinLock(&__CFApplicationPreferencesLock);
    if (addAtTop) {
        CFArrayInsertValueAtIndex(self->_search, 0, domain);
    } else {
        CFArrayAppendValue(self->_search, domain);
    }
    updateDictRep(self);
    __CFSpinUnlock(&__CFApplicationPreferencesLock);
}
__private_extern__ _CFPFactoryRef _CFPFactoryCreate(CFAllocatorRef allocator, CFUUIDRef factoryID, CFPlugInFactoryFunction func) {
    _CFPFactoryRef factory = _CFPFactoryCommonCreate(allocator, factoryID);

    __CFSpinLock(&factory->_lock);    
    factory->_func = func;
    factory->_plugIn = NULL;
    factory->_funcName = NULL;
    __CFSpinUnlock(&factory->_lock);

    return factory;
}
__private_extern__ _CFPFactory *_CFPFactoryFind(CFUUIDRef factoryID, Boolean enabled) {
    _CFPFactory *result = NULL;
    
    __CFSpinLock(&CFPlugInGlobalDataLock);
    if (_factoriesByFactoryID) {
        result = (_CFPFactory *)CFDictionaryGetValue(_factoriesByFactoryID, factoryID);
        if (result && result->_enabled != enabled) result = NULL;
    }
    __CFSpinUnlock(&CFPlugInGlobalDataLock);
    return result;
}
__private_extern__ void _CFPFactoryRemoveInstance(_CFPFactoryRef factory) {
    __CFSpinLock(&factory->_lock);
    CFPlugInRef plugin = factory->_plugIn;
    if (plugin) CFRetain(plugin);
    __CFSpinUnlock(&factory->_lock);
    if (plugin) {
        _CFPlugInRemovePlugInInstance(factory->_plugIn);
        CFRelease(plugin);
    }
    CFRelease(factory);
}
__private_extern__ CFArrayRef _CFPFactoryFindCopyForType(CFUUIDRef typeID) {
    CFArrayRef result = NULL;
    __CFSpinLock(&CFPlugInGlobalDataLock);
    if (_factoriesByTypeID) {
        result = (CFArrayRef)CFDictionaryGetValue(_factoriesByTypeID, typeID);
        if (result) CFRetain(result);
    }
    __CFSpinUnlock(&CFPlugInGlobalDataLock);

    return result;
}
__private_extern__ void _CFPFactoryAddType(_CFPFactoryRef factory, CFUUIDRef typeID) {
    /* Add the factory to the type's array of factories */
    __CFSpinLock(&factory->_lock);
    /* Add the type to the factory's type list */
    CFArrayAppendValue(factory->_types, typeID);
    __CFSpinUnlock(&factory->_lock);

    __CFSpinLock(&CFPlugInGlobalDataLock);
    if (!_factoriesByTypeID) _factoriesByTypeID = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
    CFMutableArrayRef array = (CFMutableArrayRef)CFDictionaryGetValue(_factoriesByTypeID, typeID);
    if (!array) {
        CFArrayCallBacks _factoryArrayCallbacks = {0, NULL, NULL, NULL, NULL};
        // Create this from default allocator
        array = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &_factoryArrayCallbacks);
        CFDictionarySetValue(_factoriesByTypeID, typeID, array);
        CFRelease(array);
    }
    CFArrayAppendValue(array, factory);
    __CFSpinUnlock(&CFPlugInGlobalDataLock);
}
static void _CFApplicationPreferencesSetSearchList(_CFApplicationPreferences *self, CFArrayRef newSearchList) {
    CFIndex idx, count;
    __CFSpinLock(&__CFApplicationPreferencesLock);
    CFArrayRemoveAllValues(self->_search);
    count = CFArrayGetCount(newSearchList);
    for (idx = 0; idx < count; idx ++) {
        CFArrayAppendValue(self->_search, CFArrayGetValueAtIndex(newSearchList, idx));
    }
    updateDictRep(self);
    __CFSpinUnlock(&__CFApplicationPreferencesLock);
}
CF_INLINE CFDictionaryRef URLPropertyDictForPOSIXMode(SInt32 mode) {
    static CFMutableDictionaryRef _propertyDict = NULL;
    CFNumberRef num = CFNumberCreate(__CFPreferencesAllocator(), kCFNumberSInt32Type, &mode);
    __CFSpinLock(&_propDictLock);
    if (!_propertyDict) {
        _propertyDict = CFDictionaryCreateMutable(__CFPreferencesAllocator(), 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
    }
    CFDictionarySetValue(_propertyDict, kCFURLFilePOSIXMode, num);
    CFRelease(num);
    return _propertyDict;
}
/* These methods are called by CFPlugInInstance when an instance is created or destroyed.  If a factory's instance count goes to 0 and the factory has been disabled, the factory is destroyed. */
__private_extern__ void _CFPFactoryAddInstance(_CFPFactoryRef factory) {
    /* MF:!!! Assert that factory is enabled. */
    CFRetain(factory);
    __CFSpinLock(&factory->_lock);
    CFPlugInRef plugin = factory->_plugIn;
    if (plugin) CFRetain(plugin);
    __CFSpinUnlock(&factory->_lock);
    if (plugin) {
        _CFPlugInAddPlugInInstance(plugin);
        CFRelease(plugin);
    }    
}
__private_extern__ _CFPFactoryRef _CFPFactoryCreateByName(CFAllocatorRef allocator, CFUUIDRef factoryID, CFPlugInRef plugIn, CFStringRef funcName) {
    _CFPFactoryRef factory = _CFPFactoryCommonCreate(allocator, factoryID);

    __CFSpinLock(&factory->_lock);    
    factory->_func = NULL;
    factory->_plugIn = (CFPlugInRef)CFRetain(plugIn);
    if (plugIn) _CFPlugInAddFactory(plugIn, factory);
    factory->_funcName = (funcName ? (CFStringRef)CFStringCreateCopy(allocator, funcName) : NULL);
    __CFSpinUnlock(&factory->_lock);

    return factory;
}
Boolean _CFApplicationPreferencesContainsDomain(_CFApplicationPreferences *self, CFPreferencesDomainRef domain) {
    Boolean result;

    if (!domain) {
        return false;
    }

    __CFSpinLock(&__CFApplicationPreferencesLock);
    result = CFArrayContainsValue(self->_search, CFRangeMake(0, CFArrayGetCount(self->_search)), domain);
    __CFSpinUnlock(&__CFApplicationPreferencesLock);
    return result;
}
Exemple #14
0
/* static */ Boolean
_BrowserBlockUntilComplete(__CFNetServiceBrowser* browser) {

	// Assume success by default
	Boolean result = TRUE;
	CFRunLoopRef rl = CFRunLoopGetCurrent();

	// Schedule in the blocking mode.
	CFNetServiceBrowserScheduleWithRunLoop((CFNetServiceBrowserRef)browser, rl, _kCFNetServiceBrowserBlockingMode);

	// Lock in order to check for trigger
	__CFSpinLock(&(browser->_lock));

	// Check that search exists.
	while (browser->_trigger) {

		// Unlock again so the browser can continue to be processed.
		__CFSpinUnlock(&(browser->_lock));

		// Run the loop in a private mode with it returning whenever a source
		// has been handled.
		CFRunLoopRunInMode(_kCFNetServiceBrowserBlockingMode, DBL_MAX, TRUE);

		// Lock again in preparation for trigger check
		__CFSpinLock(&(browser->_lock));
	}

	// Fail if there was an error.
	if (browser->_error.error)
		result = FALSE;

	// Unlock the browser again.
	__CFSpinUnlock(&(browser->_lock));

	// Unschedule from the blocking mode
	CFNetServiceBrowserUnscheduleFromRunLoop((CFNetServiceBrowserRef)browser, rl, _kCFNetServiceBrowserBlockingMode);

	return result;
}
// CACHING here - we will only return a value as current as the last time computeDictRep() was called
static CFTypeRef _CFApplicationPreferencesCreateValueForKey2(_CFApplicationPreferences *self, CFStringRef defaultName) {
    CFTypeRef result;
    __CFSpinLock(&__CFApplicationPreferencesLock);
    if (!self->_dictRep) {
        self->_dictRep = computeDictRep(self, true);
    }
    result = (self->_dictRep) ? (CFTypeRef )CFDictionaryGetValue(self->_dictRep, defaultName) : NULL;
    if (result) {
        CFRetain(result);
    }
    __CFSpinUnlock(&__CFApplicationPreferencesLock);
    return result;
}
static CFTypeRef fetchXMLValue(CFTypeRef context, void *xmlDomain, CFStringRef key) {
    _CFXMLPreferencesDomain *domain = (_CFXMLPreferencesDomain *)xmlDomain;
    CFTypeRef result;
 
    // Never reload if we've looked at the file system within the last 5 seconds.
    __CFSpinLock(&domain->_lock);
    if (domain->_domainDict == NULL) _loadXMLDomainIfStale((CFURLRef )context, domain);
    result = CFDictionaryGetValue(domain->_domainDict, key);
    if (result) CFRetain(result); 
    __CFSpinUnlock(&domain->_lock);

    return result;
}
__private_extern__ void _CFPFactoryRemoveType(_CFPFactoryRef factory, CFUUIDRef typeID) {
    /* Remove it from the factory's type list */
    SInt32 idx;

    __CFSpinLock(&factory->_lock);
    idx = CFArrayGetFirstIndexOfValue(factory->_types, CFRangeMake(0, CFArrayGetCount(factory->_types)), typeID);
    if (idx >= 0) CFArrayRemoveValueAtIndex(factory->_types, idx);
    __CFSpinUnlock(&factory->_lock);

    /* Remove the factory from the type's list of factories */
    __CFSpinLock(&CFPlugInGlobalDataLock);
    if (_factoriesByTypeID) {
        CFMutableArrayRef array = (CFMutableArrayRef)CFDictionaryGetValue(_factoriesByTypeID, typeID);
        if (array) {
            idx = CFArrayGetFirstIndexOfValue(array, CFRangeMake(0, CFArrayGetCount(array)), factory);
            if (idx >= 0) {
                CFArrayRemoveValueAtIndex(array, idx);
                if (CFArrayGetCount(array) == 0) CFDictionaryRemoveValue(_factoriesByTypeID, typeID);
            }
        }
    }
    __CFSpinUnlock(&CFPlugInGlobalDataLock);
}
static CFDictionaryRef copyXMLDomainDictionary(CFTypeRef context, void *xmlDomain) {
    _CFXMLPreferencesDomain *domain = (_CFXMLPreferencesDomain *)xmlDomain;
    CFDictionaryRef result;
    
    __CFSpinLock(&domain->_lock);
    if(!domain->_domainDict) {
        _loadXMLDomainIfStale((CFURLRef)context, domain);
    }
    
    result = (CFDictionaryRef)CFPropertyListCreateDeepCopy(__CFPreferencesAllocator(), domain->_domainDict, kCFPropertyListImmutable);
    
    __CFSpinUnlock(&domain->_lock);
    return result;
}
void _CFApplicationPreferencesRemoveDomain(_CFApplicationPreferences *self, CFPreferencesDomainRef domain) {
    CFIndex idx;
    CFRange range;
    __CFSpinLock(&__CFApplicationPreferencesLock);
    range.location = 0;
    range.length = CFArrayGetCount(self->_search);
    while ((idx = CFArrayGetFirstIndexOfValue(self->_search, range, domain)) != kCFNotFound) {
        CFArrayRemoveValueAtIndex(self->_search, idx);
        range.location = idx;
        range.length  = range.length - idx - 1;
    }
    updateDictRep(self);
    __CFSpinUnlock(&__CFApplicationPreferencesLock);
}
void _CFApplicationPreferencesRemoveSuitePreferences(_CFApplicationPreferences *appPrefs, CFStringRef suiteName) {
    CFPreferencesDomainRef domain;

    __CFSpinLock(&__CFApplicationPreferencesLock);
    domain = _CFPreferencesStandardDomain(suiteName, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
    __CFSpinUnlock(&__CFApplicationPreferencesLock);
    if (domain) _CFApplicationPreferencesRemoveDomain(appPrefs, domain);

    __CFSpinLock(&__CFApplicationPreferencesLock);
    domain = _CFPreferencesStandardDomain(suiteName, kCFPreferencesCurrentUser, kCFPreferencesCurrentHost);
    __CFSpinUnlock(&__CFApplicationPreferencesLock);
    if (domain) _CFApplicationPreferencesRemoveDomain(appPrefs, domain);

    __CFSpinLock(&__CFApplicationPreferencesLock);
    domain = _CFPreferencesStandardDomain(suiteName, kCFPreferencesAnyUser, kCFPreferencesAnyHost);
    __CFSpinUnlock(&__CFApplicationPreferencesLock);
    if (domain) _CFApplicationPreferencesRemoveDomain(appPrefs, domain);

    __CFSpinLock(&__CFApplicationPreferencesLock);
    domain = _CFPreferencesStandardDomain(suiteName, kCFPreferencesAnyUser, kCFPreferencesCurrentHost);
    __CFSpinUnlock(&__CFApplicationPreferencesLock);
    if (domain) _CFApplicationPreferencesRemoveDomain(appPrefs, domain);
}
CF_EXPORT
CFDictionaryRef _CFApplicationPreferencesCopyRepresentation(_CFApplicationPreferences *self) {
    CFDictionaryRef dict;
    __CFSpinLock(&__CFApplicationPreferencesLock);
    if (!self->_dictRep) {
        self->_dictRep = computeDictRep(self, true);
    }
    if (self->_dictRep) {
        CFRetain(self->_dictRep);
    }
    dict = self->_dictRep;
    __CFSpinUnlock(&__CFApplicationPreferencesLock);
    return dict;
}
void _CFApplicationPreferencesRemove(_CFApplicationPreferences *self, CFStringRef defaultName) {
    CFPreferencesDomainRef appDomain;

    __CFSpinLock(&__CFApplicationPreferencesLock);
    appDomain = _CFPreferencesStandardDomain(self->_appName, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
    if(appDomain) {
        _CFPreferencesDomainSet(appDomain, defaultName, NULL);
        if (CFArrayContainsValue(self->_search, CFRangeMake(0, CFArrayGetCount(self->_search)), appDomain)) {
            // If key exists, it will be in the _dictRep (but possibly overridden)
            updateDictRep(self);
        }
    }
    __CFSpinUnlock(&__CFApplicationPreferencesLock);
}
void _CFApplicationPreferencesSet(_CFApplicationPreferences *self, CFStringRef defaultName, CFTypeRef value) {
    CFPreferencesDomainRef applicationDomain;

    __CFSpinLock(&__CFApplicationPreferencesLock);
    applicationDomain = _CFPreferencesStandardDomain(self->_appName, kCFPreferencesCurrentUser, kCFPreferencesAnyHost);
    if(applicationDomain) {
        _CFPreferencesDomainSet(applicationDomain, defaultName, value);
        if (CFArrayContainsValue(self->_search, CFRangeMake(0, CFArrayGetCount(self->_search)), applicationDomain)) {
            // Expensive; can't we just check the relevant value throughout the appropriate sets of domains? -- REW, 7/19/99
            updateDictRep(self);
        }
    }
    __CFSpinUnlock(&__CFApplicationPreferencesLock);
}
static void
createPair(CFAllocatorRef alloc, CFStringRef host, UInt32 port, CFSocketNativeHandle sock, const CFSocketSignature* sig, CFReadStreamRef *readStream, CFWriteStreamRef *writeStream)
{
    if (readStream)
        *readStream = NULL;
        
    if (writeStream)
        *writeStream = NULL;

    __CFSpinLock(&(CFNetworkSupport.lock));
    if (!__CFBitIsSet(CFNetworkSupport.flags, kTriedToLoad)) initializeCFNetworkSupport();
    __CFSpinUnlock(&(CFNetworkSupport.lock));

    CFNETWORK_CALL(_CFSocketStreamCreatePair, (alloc, host, port, sock, sig, readStream, writeStream));
}
// Exclusively for Foundation's use
void _CFApplicationPreferencesSetCacheForApp(_CFApplicationPreferences *appPrefs, CFStringRef appName) {
    __CFSpinLock(&__CFApplicationPreferencesLock);
    if (!__CFStandardUserPreferences) {
        __CFStandardUserPreferences = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeDictionaryKeyCallBacks, NULL);
        CFDictionarySetValue(__CFStandardUserPreferences, appName, appPrefs);
        __CFSpinUnlock(&__CFApplicationPreferencesLock);
    } else {
        _CFApplicationPreferences *oldPrefs = (_CFApplicationPreferences *)CFDictionaryGetValue(__CFStandardUserPreferences, appName);
        CFDictionarySetValue(__CFStandardUserPreferences, appName, appPrefs);
        __CFSpinUnlock(&__CFApplicationPreferencesLock);
        if (oldPrefs) {
            _CFDeallocateApplicationPreferences(oldPrefs);
        }
    }
}
__private_extern__ void *_CFPFactoryCreateInstance(CFAllocatorRef allocator, _CFPFactoryRef factory, CFUUIDRef typeID) {
    void *result = NULL;

    __CFSpinLock(&factory->_lock);
    if (factory->_enabled) {
        if (!factory->_func) {
            factory->_func = (CFPlugInFactoryFunction)CFBundleGetFunctionPointerForName(factory->_plugIn, factory->_funcName);
            if (!factory->_func) CFLog(__kCFLogPlugIn, CFSTR("Cannot find function pointer %@ for factory %@ in %@"), factory->_funcName, factory->_uuid, factory->_plugIn);
        }
        if (factory->_func) {
            // UPPGOOP
            CFPlugInFactoryFunction f = factory->_func;
            __CFSpinUnlock(&factory->_lock);
            FAULT_CALLBACK((void **)&(f));
            result = (void *)INVOKE_CALLBACK2(f, allocator, typeID);
            __CFSpinLock(&factory->_lock);
        }
    } else {
        CFLog(__kCFLogPlugIn, CFSTR("Factory %@ is disabled"), factory->_uuid);
    }    
    __CFSpinUnlock(&factory->_lock);

    return result;
}
Exemple #27
0
/* static */ void
_NetServiceBrowserDestroy(__CFNetServiceBrowser* browser) {

	// Prevent anything else from taking hold
	__CFSpinLock(&(browser->_lock));

	// Release the user's context info if there is some and a release method
	if (browser->_client.info && browser->_client.release)
		browser->_client.release(browser->_client.info);

	// Cancel the outstanding trigger
	if (browser->_trigger) {

		// Remove the trigger from run loops and modes
		if (browser->_schedules)
			_CFTypeUnscheduleFromMultipleRunLoops(browser->_trigger, browser->_schedules);

		// Go ahead and invalidate the trigger
		_CFTypeInvalidate(browser->_trigger);

		// Release the browse 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);
	}

	// Release the found list
	if (browser->_found)
		CFRelease(browser->_found);

	// Release the list of adds
	if (browser->_adds)
		CFRelease(browser->_adds);

	// Release the list of removes
	if (browser->_removes)
		CFRelease(browser->_removes);

	// Release the list of loops and modes
	if (browser->_schedules)
		CFRelease(browser->_schedules);
}
static Boolean synchronizeXMLDomain(CFTypeRef context, void *xmlDomain) {
    _CFXMLPreferencesDomain *domain = (_CFXMLPreferencesDomain *)xmlDomain;
    CFMutableDictionaryRef cachedDict;
    CFMutableArrayRef changedKeys;
    SInt32 idx,  count;
    Boolean success, tryAgain;
    
    __CFSpinLock(&domain->_lock);
    cachedDict = domain->_domainDict;
    changedKeys = domain->_dirtyKeys;
    count = CFArrayGetCount(changedKeys);
    
    if (count == 0) {
        // no changes were made to this domain; just remove it from the cache to guarantee it will be taken from disk next access
        if (cachedDict) {
            CFRelease(cachedDict);
            domain->_domainDict = NULL;
        }
        __CFSpinUnlock(&domain->_lock);
        return true;
    }

    domain->_domainDict = NULL; // This forces a reload.  Note that we now have a retain on cachedDict
    do {
        _loadXMLDomainIfStale((CFURLRef )context, domain);
        // now cachedDict holds our changes; domain->_domainDict has the latest version from the disk
        for (idx = 0; idx < count; idx ++) {
            CFStringRef key = (CFStringRef) CFArrayGetValueAtIndex(changedKeys, idx);
            CFTypeRef value = CFDictionaryGetValue(cachedDict, key);
            if (value)
                CFDictionarySetValue(domain->_domainDict, key, value);
            else
                CFDictionaryRemoveValue(domain->_domainDict, key);
        }
        success = _writeXMLFile((CFURLRef )context, domain->_domainDict, domain->_isWorldReadable, &tryAgain);
        if (tryAgain) {
            __CFMilliSleep((((uint32_t)__CFReadTSR() & 0xf) + 1) * 50);
        }
    } while (tryAgain);
    CFRelease(cachedDict);
    if (success) {
	CFArrayRemoveAllValues(domain->_dirtyKeys);
    }
    domain->_lastReadTime = CFAbsoluteTimeGetCurrent();
    __CFSpinUnlock(&domain->_lock);
    return success;
}
Exemple #29
0
CF_EXPORT CFTypeRef _CFRetain(CFTypeRef cf) {
    if (NULL == cf) return NULL;
#if __LP64__
    uint32_t lowBits;
    do {
        lowBits = ((CFRuntimeBase *)cf)->_rc;
        if (0 == lowBits) return cf;	// Constant CFTypeRef
    } while (!_CFAtomicCompareAndSwap32Barrier(lowBits, lowBits + 1, (int32_t *)&((CFRuntimeBase *)cf)->_rc));
#else
#define RC_START 24
#define RC_END 31
    volatile UInt32 *infoLocation = (UInt32 *)&(((CFRuntimeBase *)cf)->_cfinfo);
    CFIndex rcLowBits = __CFBitfieldGetValue(*infoLocation, RC_END, RC_START);
    if (__builtin_expect(0 == rcLowBits, 0)) return cf;	// Constant CFTypeRef
    bool success = 0;
    do {
        UInt32 initialCheckInfo = *infoLocation;
        UInt32 prospectiveNewInfo = initialCheckInfo; // don't want compiler to generate prospectiveNewInfo = *infoLocation.  This is why infoLocation is declared as a pointer to volatile memory.
        prospectiveNewInfo += (1 << RC_START);
        rcLowBits = __CFBitfieldGetValue(prospectiveNewInfo, RC_END, RC_START);
        if (__builtin_expect((rcLowBits & 0x7f) == 0, 0)) {
            /* Roll over another bit to the external ref count
             Real ref count = low 7 bits of info[CF_RC_BITS]  + external ref count << 6
             Bit 8 of low bits indicates that external ref count is in use.
             External ref count is shifted by 6 rather than 7 so that we can set the low
            bits to to 1100 0000 rather than 1000 0000.
            	This prevents needing to access the external ref count for successive retains and releases
            	when the composite retain count is right around a multiple of 1 << 7.
                       */
            prospectiveNewInfo = initialCheckInfo;
            __CFBitfieldSetValue(prospectiveNewInfo, RC_END, RC_START, ((1 << 7) | (1 << 6)));
            __CFSpinLock(&__CFRuntimeExternRefCountTableLock);
            success = _CFAtomicCompareAndSwap32Barrier(*(int32_t *)&initialCheckInfo, *(int32_t *)&prospectiveNewInfo, (int32_t *)infoLocation);
            if (__builtin_expect(success, 1)) {
                CFBagAddValue(__CFRuntimeExternRefCountTable, DISGUISE(cf));
            }
            __CFSpinUnlock(&__CFRuntimeExternRefCountTableLock);
        } else {
            success = _CFAtomicCompareAndSwap32Barrier(*(int32_t *)&initialCheckInfo, *(int32_t *)&prospectiveNewInfo, (int32_t *)infoLocation);
        }
    } while (__builtin_expect(!success, 0));
#endif
    if (__builtin_expect(__CFOASafe, 0)) {
        __CFRecordAllocationEvent(__kCFRetainEvent, (void *)cf, 0, _CFGetRetainCount(cf), NULL);
    }
    return cf;
}
Boolean CFPreferencesAppSynchronize(CFStringRef appName) {
    _CFApplicationPreferences *standardPrefs;
    Boolean result;
    CFAssert1(appName != NULL, __kCFLogAssertion, "%s(): Cannot access application preferences with a NULL application name", __PRETTY_FUNCTION__);
    
    // Do not call _CFStandardApplicationPreferences(), as we do not want to create the preferences only to synchronize
    __CFSpinLock(&__CFApplicationPreferencesLock);
    if (__CFStandardUserPreferences)  {
        standardPrefs = (_CFApplicationPreferences *)CFDictionaryGetValue(__CFStandardUserPreferences, appName);
    } else {
        standardPrefs = NULL;
    }

    result = standardPrefs ? _CFApplicationPreferencesSynchronizeNoLock(standardPrefs) : _CFSynchronizeDomainCache();
    __CFSpinUnlock(&__CFApplicationPreferencesLock);
    return result;
}