@@ -1460,8 +1460,22 @@ CF_PRIVATE int asprintf(char **ret, const char *format, ...) {
1460
1460
extern void swift_retain (void * );
1461
1461
extern void swift_release (void * );
1462
1462
1463
+ #if TARGET_OS_WIN32
1464
+ typedef struct _CFThreadSpecificData {
1465
+ CFTypeRef value ;
1466
+ _CFThreadSpecificKey key ;
1467
+ } _CFThreadSpecificData ;
1468
+ #endif
1469
+
1463
1470
static void _CFThreadSpecificDestructor (void * ctx ) {
1471
+ #if TARGET_OS_WIN32
1472
+ _CFThreadSpecificData * data = (_CFThreadSpecificData * )ctx ;
1473
+ FlsSetValue (data -> key , NULL );
1474
+ swift_release (data -> value );
1475
+ free (data );
1476
+ #else
1464
1477
swift_release (ctx );
1478
+ #endif
1465
1479
}
1466
1480
1467
1481
_CFThreadSpecificKey _CFThreadSpecificKeyCreate () {
@@ -1476,18 +1490,36 @@ _CFThreadSpecificKey _CFThreadSpecificKeyCreate() {
1476
1490
1477
1491
CFTypeRef _Nullable _CFThreadSpecificGet (_CFThreadSpecificKey key ) {
1478
1492
#if TARGET_OS_WIN32
1479
- return (CFTypeRef )FlsGetValue (key );
1493
+ _CFThreadSpecificData * data = (_CFThreadSpecificData * )FlsGetValue (key );
1494
+ if (data == NULL ) {
1495
+ return NULL ;
1496
+ }
1497
+ return data -> value ;
1480
1498
#else
1481
1499
return (CFTypeRef )pthread_getspecific (key );
1482
1500
#endif
1483
1501
}
1484
1502
1485
1503
void _CFThreadSpecificSet (_CFThreadSpecificKey key , CFTypeRef _Nullable value ) {
1504
+ // Intentionally not calling `swift_release` for previous value.
1505
+ // OperationQueue uses these API (through NSThreadSpecific), and balances
1506
+ // retain count manually.
1486
1507
#if TARGET_OS_WIN32
1508
+ free (FlsGetValue (key ));
1509
+
1510
+ _CFThreadSpecificData * data = NULL ;
1487
1511
if (value != NULL ) {
1512
+ data = malloc (sizeof (_CFThreadSpecificData ));
1513
+ if (!data ) {
1514
+ HALT_MSG ("Out of memory" );
1515
+ }
1516
+ data -> value = value ;
1517
+ data -> key = key ;
1518
+
1488
1519
swift_retain ((void * )value );
1489
1520
}
1490
- FlsSetValue (key , value );
1521
+
1522
+ FlsSetValue (key , data );
1491
1523
#else
1492
1524
if (value != NULL ) {
1493
1525
swift_retain ((void * )value );
0 commit comments