@@ -1390,8 +1390,22 @@ CF_PRIVATE int asprintf(char **ret, const char *format, ...) {
1390
1390
extern void swift_retain (void * );
1391
1391
extern void swift_release (void * );
1392
1392
1393
+ #if TARGET_OS_WIN32
1394
+ typedef struct _CFThreadSpecificData {
1395
+ CFTypeRef value ;
1396
+ _CFThreadSpecificKey key ;
1397
+ } _CFThreadSpecificData ;
1398
+ #endif
1399
+
1393
1400
static void _CFThreadSpecificDestructor (void * ctx ) {
1401
+ #if TARGET_OS_WIN32
1402
+ _CFThreadSpecificData * data = (_CFThreadSpecificData * )ctx ;
1403
+ FlsSetValue (data -> key , NULL );
1404
+ swift_release (data -> value );
1405
+ free (data );
1406
+ #else
1394
1407
swift_release (ctx );
1408
+ #endif
1395
1409
}
1396
1410
1397
1411
_CFThreadSpecificKey _CFThreadSpecificKeyCreate () {
@@ -1406,18 +1420,36 @@ _CFThreadSpecificKey _CFThreadSpecificKeyCreate() {
1406
1420
1407
1421
CFTypeRef _Nullable _CFThreadSpecificGet (_CFThreadSpecificKey key ) {
1408
1422
#if TARGET_OS_WIN32
1409
- return (CFTypeRef )FlsGetValue (key );
1423
+ _CFThreadSpecificData * data = (_CFThreadSpecificData * )FlsGetValue (key );
1424
+ if (data == NULL ) {
1425
+ return NULL ;
1426
+ }
1427
+ return data -> value ;
1410
1428
#else
1411
1429
return (CFTypeRef )pthread_getspecific (key );
1412
1430
#endif
1413
1431
}
1414
1432
1415
1433
void _CFThreadSpecificSet (_CFThreadSpecificKey key , CFTypeRef _Nullable value ) {
1434
+ // Intentionally not calling `swift_release` for previous value.
1435
+ // OperationQueue uses these API (through NSThreadSpecific), and balances
1436
+ // retain count manually.
1416
1437
#if TARGET_OS_WIN32
1438
+ free (FlsGetValue (key ));
1439
+
1440
+ _CFThreadSpecificData * data = NULL ;
1417
1441
if (value != NULL ) {
1442
+ data = malloc (sizeof (_CFThreadSpecificData ));
1443
+ if (!data ) {
1444
+ HALT_MSG ("Out of memory" );
1445
+ }
1446
+ data -> value = value ;
1447
+ data -> key = key ;
1448
+
1418
1449
swift_retain ((void * )value );
1419
1450
}
1420
- FlsSetValue (key , value );
1451
+
1452
+ FlsSetValue (key , data );
1421
1453
#else
1422
1454
if (value != NULL ) {
1423
1455
swift_retain ((void * )value );
0 commit comments