<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Yes, that was the “skirting of the issue”. =)<div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">- Tony</div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Oct 7, 2016, at 10:31 AM, Alex Blewitt &lt;<a href="mailto:alblue@apple.com" class="">alblue@apple.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">That's what I was expecting, too, but then I found this:<div class=""><br class=""><div class=""><a href="https://github.com/apple/swift-corelibs-foundation/blob/1a76e814212e781a9d50782ee24117760cfe9b48/CoreFoundation/Base.subproj/CFInternal.h#L387-L389" class="">https://github.com/apple/swift-corelibs-foundation/blob/1a76e814212e781a9d50782ee24117760cfe9b48/CoreFoundation/Base.subproj/CFInternal.h#L387-L389</a></div><div class=""><br class=""></div><div class=""><div class="">#if&nbsp;DEPLOYMENT_RUNTIME_SWIFT<br class="">&nbsp;// TODO: Pinned retain count for constants?<br class="">&nbsp;#define&nbsp;__CFSTR_RC_INIT&nbsp;_CF_CONSTANT_OBJECT_STRONG_RC,&nbsp;0,</div></div><div class=""><br class=""></div><div class="">Alex</div><div class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On 7 Oct 2016, at 17:51, Tony Parker &lt;<a href="mailto:anthony.parker@apple.com" class="">anthony.parker@apple.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Hi Alex,<div class=""><br class=""></div><div class="">Thanks for digging into this. This seems like a correct solution for now.</div><div class=""><br class=""></div><div class="">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.</div><div class=""><br class=""></div><div class="">- Tony</div><div class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Oct 7, 2016, at 6:47 AM, Alex Blewitt via swift-corelibs-dev &lt;<a href="mailto:swift-corelibs-dev@swift.org" class="">swift-corelibs-dev@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=us-ascii" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div dir="auto" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">I'm looking at <a href="https://bugs.swift.org/browse/SR-2879" class="">https://bugs.swift.org/browse/SR-2879</a>&nbsp;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.<div class=""><br class=""></div><div class="">The problem is that CFCalendar releases the localeID when it's deallocated:</div><div class=""><br class=""></div><div class="">if&nbsp;(calendar-&gt;_localeID)&nbsp;CFRelease(calendar-&gt;_localeID);<br class=""></div><div class=""><br class=""></div><div class=""><a href="https://github.com/apple/swift-corelibs-foundation/blob/1a76e814212e781a9d50782ee24117760cfe9b48/CoreFoundation/Locale.subproj/CFCalendar.c#L54" class="">https://github.com/apple/swift-corelibs-foundation/blob/1a76e814212e781a9d50782ee24117760cfe9b48/CoreFoundation/Locale.subproj/CFCalendar.c#L54</a>&nbsp;</div><div class=""><br class=""></div><div class="">The problem is that when the localeID is assigned, it doesn't appear to be copied or renamed:</div><div class=""><br class=""></div><div class="">calendar-&gt;_localeID =&nbsp;CFLocaleGetIdentifier(CFLocaleGetSystem());<br class=""><br class=""></div><div class=""><a href="https://github.com/apple/swift-corelibs-foundation/blob/1a76e814212e781a9d50782ee24117760cfe9b48/CoreFoundation/Locale.subproj/CFCalendar.c#L252" class="">https://github.com/apple/swift-corelibs-foundation/blob/1a76e814212e781a9d50782ee24117760cfe9b48/CoreFoundation/Locale.subproj/CFCalendar.c#L252</a>&nbsp;</div><div class=""><a href="https://github.com/apple/swift-corelibs-foundation/blob/1a76e814212e781a9d50782ee24117760cfe9b48/CoreFoundation/Locale.subproj/CFCalendar.c#L281" class="">https://github.com/apple/swift-corelibs-foundation/blob/1a76e814212e781a9d50782ee24117760cfe9b48/CoreFoundation/Locale.subproj/CFCalendar.c#L281</a> &nbsp;</div><br class="">but elsewhere in the code, we do retain it:</div><div dir="auto" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""></div><div dir="auto" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">&nbsp; &nbsp;CFStringRef&nbsp;localeID =&nbsp;CFLocaleGetIdentifier(locale);<br class="">&nbsp; &nbsp;&nbsp;if&nbsp;(localeID != calendar-&gt;_localeID) {<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>CFRelease(calendar-&gt;_localeID);<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>CFRetain(localeID);</div><div dir="auto" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""></div><div dir="auto" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><a href="https://github.com/apple/swift-corelibs-foundation/blob/1a76e814212e781a9d50782ee24117760cfe9b48/CoreFoundation/Locale.subproj/CFCalendar.c#L303-L306" class="">https://github.com/apple/swift-corelibs-foundation/blob/1a76e814212e781a9d50782ee24117760cfe9b48/CoreFoundation/Locale.subproj/CFCalendar.c#L303-L306</a>&nbsp;</div><div dir="auto" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""></div><div dir="auto" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">When a locale isn't supplied, it uses the default global one, which is defined to be an empty string:</div><div dir="auto" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""></div><div dir="auto" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">CFLocaleRef&nbsp;CFLocaleGetSystem(void) {<br class="">&nbsp; &nbsp;&nbsp;CFLocaleRef&nbsp;locale;<br class="">&nbsp; &nbsp;&nbsp;CFLocaleRef&nbsp;uselessLocale =&nbsp;NULL;&nbsp;//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.<br class="">&nbsp; &nbsp;&nbsp;__CFLocaleLockGlobal();<br class="">&nbsp; &nbsp;&nbsp;if&nbsp;(NULL&nbsp;== __CFLocaleSystem) {<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>__CFLocaleUnlockGlobal();<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>locale =&nbsp;CFLocaleCreate(kCFAllocatorSystemDefault,&nbsp;CFSTR(""));<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>if&nbsp;(!locale)&nbsp;return&nbsp;NULL;</div><div dir="auto" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""></div><div dir="auto" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><a href="https://github.com/apple/swift-corelibs-foundation/blob/1a76e814212e781a9d50782ee24117760cfe9b48/CoreFoundation/Locale.subproj/CFLocale.c#L255-L261" class="">https://github.com/apple/swift-corelibs-foundation/blob/1a76e814212e781a9d50782ee24117760cfe9b48/CoreFoundation/Locale.subproj/CFLocale.c#L255-L261</a>&nbsp;</div><div dir="auto" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""></div><div dir="auto" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">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&nbsp;<a href="https://github.com/apple/swift-corelibs-foundation/pull/667" class="">https://github.com/apple/swift-corelibs-foundation/pull/667</a>&nbsp;as documented in&nbsp;<a href="https://bugs.swift.org/browse/SR-2879" class="">https://bugs.swift.org/browse/SR-2879</a></div><div dir="auto" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""></div><div dir="auto" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">My suggestion is to insert a CFRetain when the calendar-&gt;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.</div><div dir="auto" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""></div><div dir="auto" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">&nbsp;&nbsp;1&gt;&nbsp;import Foundation&nbsp;<br class="">&nbsp;&nbsp;2&gt;&nbsp;:p (int)swift_retainCount(&amp;__kCFEmptyString)&nbsp;<br class="">(int) $11 = 1<br class="">&nbsp;&nbsp;2&gt;&nbsp;_ = Calendar(identifier:.gregorian)<br class="">&nbsp;&nbsp;3&gt;&nbsp;:p (int)swift_retainCount(&amp;__kCFEmptyString)&nbsp;<br class="">(int) $12 = 3<br class="">&nbsp;&nbsp;3&gt;&nbsp;_ = Calendar(identifier:.chinese)<br class="">&nbsp;&nbsp;4&gt;&nbsp;:p (int)swift_retainCount(&amp;__kCFEmptyString)&nbsp;<br class="">(int) $13 = 3<br class="">&nbsp;&nbsp;4&gt;&nbsp;_ = Calendar(identifier:.hebrew)<br class="">&nbsp;&nbsp;5&gt;&nbsp;:p (int)swift_retainCount(&amp;__kCFEmptyString)&nbsp;<br class="">(int) $14 = 3<br class="">&nbsp;&nbsp;5&gt;&nbsp;^D<br class=""><br class=""></div><div dir="auto" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Alex</div></div>_______________________________________________<br class="">swift-corelibs-dev mailing list<br class=""><a href="mailto:swift-corelibs-dev@swift.org" class="">swift-corelibs-dev@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-corelibs-dev" class="">https://lists.swift.org/mailman/listinfo/swift-corelibs-dev</a><br class=""></div></blockquote></div><br class=""></div></div></div></blockquote></div><br class=""></div></div></div></div></blockquote></div><br class=""></div></body></html>