That's what I was expecting, too, but then I found this: https://github.com/apple/swift-corelibs-foundation/blob/1a76e814212e781a9d50782ee24117760cfe9b48/CoreFoundation/Base.subproj/CFInternal.h#L387-L389 <https://github.com/apple/swift-corelibs-foundation/blob/1a76e814212e781a9d50782ee24117760cfe9b48/CoreFoundation/Base.subproj/CFInternal.h#L387-L389>
#if DEPLOYMENT_RUNTIME_SWIFT // TODO: Pinned retain count for constants? #define __CFSTR_RC_INIT _CF_CONSTANT_OBJECT_STRONG_RC, 0, Alex > On 7 Oct 2016, at 17:51, Tony Parker <anthony.par...@apple.com> wrote: > > Hi Alex, > > Thanks for digging into this. This seems like a correct solution for now. > > I think there is a larger question though, which is why it’s possible to > overrelease kCFEmptyString. I think we skirted the issue early in bringup of > SCL-Foundation, but constant strings are supposed to be “pinned” and ref > count operations on them a no-op. > > - Tony > >> On Oct 7, 2016, at 6:47 AM, Alex Blewitt via swift-corelibs-dev >> <swift-corelibs-dev@swift.org <mailto:swift-corelibs-dev@swift.org>> wrote: >> >> I'm looking at https://bugs.swift.org/browse/SR-2879 >> <https://bugs.swift.org/browse/SR-2879> which is exposing itself through an >> over-release of a constant CF string (in this case, kCFEmptyString). I don't >> believe it to be a Swift related problem, because Swift doesn't get into the >> internals of CFCalendar where the problem occurs. >> >> The problem is that CFCalendar releases the localeID when it's deallocated: >> >> if (calendar->_localeID) CFRelease(calendar->_localeID); >> >> https://github.com/apple/swift-corelibs-foundation/blob/1a76e814212e781a9d50782ee24117760cfe9b48/CoreFoundation/Locale.subproj/CFCalendar.c#L54 >> >> <https://github.com/apple/swift-corelibs-foundation/blob/1a76e814212e781a9d50782ee24117760cfe9b48/CoreFoundation/Locale.subproj/CFCalendar.c#L54> >> >> >> The problem is that when the localeID is assigned, it doesn't appear to be >> copied or renamed: >> >> calendar->_localeID = CFLocaleGetIdentifier(CFLocaleGetSystem()); >> >> https://github.com/apple/swift-corelibs-foundation/blob/1a76e814212e781a9d50782ee24117760cfe9b48/CoreFoundation/Locale.subproj/CFCalendar.c#L252 >> >> <https://github.com/apple/swift-corelibs-foundation/blob/1a76e814212e781a9d50782ee24117760cfe9b48/CoreFoundation/Locale.subproj/CFCalendar.c#L252> >> >> https://github.com/apple/swift-corelibs-foundation/blob/1a76e814212e781a9d50782ee24117760cfe9b48/CoreFoundation/Locale.subproj/CFCalendar.c#L281 >> >> <https://github.com/apple/swift-corelibs-foundation/blob/1a76e814212e781a9d50782ee24117760cfe9b48/CoreFoundation/Locale.subproj/CFCalendar.c#L281> >> >> >> but elsewhere in the code, we do retain it: >> >> CFStringRef localeID = CFLocaleGetIdentifier(locale); >> if (localeID != calendar->_localeID) { >> CFRelease(calendar->_localeID); >> CFRetain(localeID); >> >> https://github.com/apple/swift-corelibs-foundation/blob/1a76e814212e781a9d50782ee24117760cfe9b48/CoreFoundation/Locale.subproj/CFCalendar.c#L303-L306 >> >> <https://github.com/apple/swift-corelibs-foundation/blob/1a76e814212e781a9d50782ee24117760cfe9b48/CoreFoundation/Locale.subproj/CFCalendar.c#L303-L306> >> >> >> When a locale isn't supplied, it uses the default global one, which is >> defined to be an empty string: >> >> CFLocaleRef CFLocaleGetSystem(void) { >> CFLocaleRef locale; >> CFLocaleRef uselessLocale = NULL; //if we lose the race creating the >> global locale, we need to release the one we created, but we want to do it >> outside the lock. >> __CFLocaleLockGlobal(); >> if (NULL == __CFLocaleSystem) { >> __CFLocaleUnlockGlobal(); >> locale = CFLocaleCreate(kCFAllocatorSystemDefault, CFSTR("")); >> if (!locale) return NULL; >> >> https://github.com/apple/swift-corelibs-foundation/blob/1a76e814212e781a9d50782ee24117760cfe9b48/CoreFoundation/Locale.subproj/CFLocale.c#L255-L261 >> >> <https://github.com/apple/swift-corelibs-foundation/blob/1a76e814212e781a9d50782ee24117760cfe9b48/CoreFoundation/Locale.subproj/CFLocale.c#L255-L261> >> >> >> The CFSTR("") results in a reference to kCFEmptyString, which reduces by one >> each time a CFCalendar is created and destroyed, leading to the (unrelated) >> test failures of https://github.com/apple/swift-corelibs-foundation/pull/667 >> <https://github.com/apple/swift-corelibs-foundation/pull/667> as documented >> in https://bugs.swift.org/browse/SR-2879 >> <https://bugs.swift.org/browse/SR-2879> >> >> My suggestion is to insert a CFRetain when the calendar->locale is set, to >> balance out the CFRelease that's being performed in the deallocator. >> Building with this simple change and checking the retain count of >> kCFEmptyString verifies that it does fix the problem, although I'm open to >> suggestions as to improvements of where the retain takes place, if not on >> lines 252 and 282. >> >> 1> import Foundation >> 2> :p (int)swift_retainCount(&__kCFEmptyString) >> (int) $11 = 1 >> 2> _ = Calendar(identifier:.gregorian) >> 3> :p (int)swift_retainCount(&__kCFEmptyString) >> (int) $12 = 3 >> 3> _ = Calendar(identifier:.chinese) >> 4> :p (int)swift_retainCount(&__kCFEmptyString) >> (int) $13 = 3 >> 4> _ = Calendar(identifier:.hebrew) >> 5> :p (int)swift_retainCount(&__kCFEmptyString) >> (int) $14 = 3 >> 5> ^D >> >> Alex >> _______________________________________________ >> swift-corelibs-dev mailing list >> swift-corelibs-dev@swift.org <mailto:swift-corelibs-dev@swift.org> >> https://lists.swift.org/mailman/listinfo/swift-corelibs-dev >
_______________________________________________ swift-corelibs-dev mailing list swift-corelibs-dev@swift.org https://lists.swift.org/mailman/listinfo/swift-corelibs-dev