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;
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.
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> wrote:
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;
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.
That's what I was expecting, too, but then I found this:
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.parker@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:
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;
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.
It’s likely not a huge deal in the end; since CF is an implementation detail of swift-corelibs-foundation, we just need to remember to retain/release constant strings as we would others and we would be ok. However, I suspect there are other places in CF where we get away with it on Darwin but can’t on Swift. So it would be nice to have them be consistent, for our own sanity.
- Tony
···
On Oct 7, 2016, at 10:31 AM, Alex Blewitt <alblue@apple.com> wrote:
That's what I was expecting, too, but then I found this:
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.parker@apple.com <mailto:anthony.parker@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:
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;
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.