Skip to content

Commit 48cacd9

Browse files
committed
ReactiveObjc: Replace OSAtomic with stdatomic.
OSAtomic is deprecated as of iOS10. This change is mainly a cherry pick of upstream PR: ReactiveCocoa#178.
1 parent a9c9b53 commit 48cacd9

14 files changed

+251
-255
lines changed

ReactiveObjC.xcodeproj/project.pbxproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1967,7 +1967,7 @@
19671967
isa = PBXProject;
19681968
attributes = {
19691969
LastSwiftUpdateCheck = 0730;
1970-
LastUpgradeCheck = 0900;
1970+
LastUpgradeCheck = 1160;
19711971
ORGANIZATIONNAME = GitHub;
19721972
TargetAttributes = {
19731973
57A4D1AF1BA13D7A00F7D4B1 = {
@@ -1991,11 +1991,11 @@
19911991
};
19921992
D047260B19E49F82006002AA = {
19931993
CreatedOnToolsVersion = 6.1;
1994-
LastSwiftMigration = 0800;
1994+
LastSwiftMigration = 1160;
19951995
};
19961996
D047261519E49F82006002AA = {
19971997
CreatedOnToolsVersion = 6.1;
1998-
LastSwiftMigration = 0800;
1998+
LastSwiftMigration = 1160;
19991999
};
20002000
};
20012001
};

ReactiveObjC/NSObject+RACPropertySubscribing.m

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
#import "RACSubscriber.h"
1818
#import "RACSignal+Operations.h"
1919
#import "RACTuple.h"
20-
#import <libkern/OSAtomic.h>
2120

2221
@implementation NSObject (RACPropertySubscribing)
2322

ReactiveObjC/RACCommand.m

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,16 @@
1717
#import "RACScheduler.h"
1818
#import "RACSequence.h"
1919
#import "RACSignal+Operations.h"
20-
#import <libkern/OSAtomic.h>
20+
#import <stdatomic.h>
2121

2222
NSString * const RACCommandErrorDomain = @"RACCommandErrorDomain";
2323
NSString * const RACUnderlyingCommandErrorKey = @"RACUnderlyingCommandErrorKey";
2424

2525
const NSInteger RACCommandErrorNotEnabled = 1;
2626

2727
@interface RACCommand () {
28-
// Atomic backing variable for `allowsConcurrentExecution`.
29-
volatile uint32_t _allowsConcurrentExecution;
28+
// Atomic backing variable for `allowsConcurrentExecution`.
29+
atomic_uint _allowsConcurrentExecution;
3030
}
3131

3232
/// A subject that sends added execution signals.
@@ -54,11 +54,11 @@ - (BOOL)allowsConcurrentExecution {
5454
}
5555

5656
- (void)setAllowsConcurrentExecution:(BOOL)allowed {
57-
if (allowed) {
58-
OSAtomicOr32Barrier(1, &_allowsConcurrentExecution);
59-
} else {
60-
OSAtomicAnd32Barrier(0, &_allowsConcurrentExecution);
61-
}
57+
if (allowed) {
58+
atomic_fetch_or(&_allowsConcurrentExecution, 1);
59+
} else {
60+
atomic_fetch_and(&_allowsConcurrentExecution, 0);
61+
}
6262

6363
[self.allowsConcurrentExecutionSubject sendNext:@(_allowsConcurrentExecution)];
6464
}

ReactiveObjC/RACDisposable.m

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@
88

99
#import "RACDisposable.h"
1010
#import "RACScopedDisposable.h"
11-
#import <libkern/OSAtomic.h>
11+
#import <stdatomic.h>
1212

1313
@interface RACDisposable () {
14-
// A copied block of type void (^)(void) containing the logic for disposal,
15-
// a pointer to `self` if no logic should be performed upon disposal, or
16-
// NULL if the receiver is already disposed.
17-
//
18-
// This should only be used atomically.
19-
void * volatile _disposeBlock;
14+
// A copied block of type void (^)(void) containing the logic for disposal,
15+
// a pointer to `self` if no logic should be performed upon disposal, or
16+
// NULL if the receiver is already disposed.
17+
//
18+
// This should only be used atomically.
19+
_Atomic(void *) _disposeBlock;
2020
}
2121

2222
@end
@@ -34,8 +34,8 @@ - (BOOL)isDisposed {
3434
- (instancetype)init {
3535
self = [super init];
3636

37-
_disposeBlock = (__bridge void *)self;
38-
OSMemoryBarrier();
37+
_disposeBlock = (__bridge void *)self;
38+
atomic_thread_fence(memory_order_seq_cst);
3939

4040
return self;
4141
}
@@ -45,8 +45,8 @@ - (instancetype)initWithBlock:(void (^)(void))block {
4545

4646
self = [super init];
4747

48-
_disposeBlock = (void *)CFBridgingRetain([block copy]);
49-
OSMemoryBarrier();
48+
_disposeBlock = (void *)CFBridgingRetain([block copy]);
49+
atomic_thread_fence(memory_order_seq_cst);
5050

5151
return self;
5252
}
@@ -67,12 +67,12 @@ - (void)dealloc {
6767
- (void)dispose {
6868
void (^disposeBlock)(void) = NULL;
6969

70-
while (YES) {
71-
void *blockPtr = _disposeBlock;
72-
if (OSAtomicCompareAndSwapPtrBarrier(blockPtr, NULL, &_disposeBlock)) {
73-
if (blockPtr != (__bridge void *)self) {
74-
disposeBlock = CFBridgingRelease(blockPtr);
75-
}
70+
while (YES) {
71+
void *blockPtr = _disposeBlock;
72+
if (atomic_compare_exchange_strong(&_disposeBlock, &blockPtr, NULL)) {
73+
if (blockPtr != (__bridge void *)self) {
74+
disposeBlock = CFBridgingRelease(blockPtr);
75+
}
7676

7777
break;
7878
}

ReactiveObjC/RACDynamicSequence.m

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
//
88

99
#import "RACDynamicSequence.h"
10-
#import <libkern/OSAtomic.h>
10+
#import <stdatomic.h>
1111

1212
// Determines how RACDynamicSequences will be deallocated before the next one is
1313
// shifted onto the autorelease pool.
@@ -114,10 +114,10 @@ + (RACSequence *)sequenceWithLazyDependency:(id (^)(void))dependencyBlock headBl
114114
}
115115

116116
- (void)dealloc {
117-
static volatile int32_t directDeallocCount = 0;
117+
static atomic_int directDeallocCount = 0;
118118

119-
if (OSAtomicIncrement32(&directDeallocCount) >= DEALLOC_OVERFLOW_GUARD) {
120-
OSAtomicAdd32(-DEALLOC_OVERFLOW_GUARD, &directDeallocCount);
119+
if (atomic_fetch_add(&directDeallocCount, 1) + 1 >= DEALLOC_OVERFLOW_GUARD) {
120+
atomic_fetch_add(&directDeallocCount, -DEALLOC_OVERFLOW_GUARD);
121121

122122
// Put this sequence's tail onto the autorelease pool so we stop
123123
// recursing.

ReactiveObjC/RACDynamicSignal.m

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
#import "RACPassthroughSubscriber.h"
1313
#import "RACScheduler+Private.h"
1414
#import "RACSubscriber.h"
15-
#import <libkern/OSAtomic.h>
1615

1716
@interface RACDynamicSignal ()
1817

ReactiveObjC/RACMulticastConnection.m

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,20 @@
1111
#import "RACDisposable.h"
1212
#import "RACSerialDisposable.h"
1313
#import "RACSubject.h"
14-
#import <libkern/OSAtomic.h>
14+
#import <stdatomic.h>
1515

1616
@interface RACMulticastConnection () {
17-
RACSubject *_signal;
18-
19-
// When connecting, a caller should attempt to atomically swap the value of this
20-
// from `0` to `1`.
21-
//
22-
// If the swap is successful the caller is resposible for subscribing `_signal`
23-
// to `sourceSignal` and storing the returned disposable in `serialDisposable`.
24-
//
25-
// If the swap is unsuccessful it means that `_sourceSignal` has already been
26-
// connected and the caller has no action to take.
27-
int32_t volatile _hasConnected;
17+
RACSubject *_signal;
18+
19+
// When connecting, a caller should attempt to atomically swap the value of this
20+
// from `0` to `1`.
21+
//
22+
// If the swap is successful the caller is resposible for subscribing `_signal`
23+
// to `sourceSignal` and storing the returned disposable in `serialDisposable`.
24+
//
25+
// If the swap is unsuccessful it means that `_sourceSignal` has already been
26+
// connected and the caller has no action to take.
27+
_Atomic(BOOL) _hasConnected;
2828
}
2929

3030
@property (nonatomic, readonly, strong) RACSignal *sourceSignal;
@@ -51,7 +51,8 @@ - (instancetype)initWithSourceSignal:(RACSignal *)source subject:(RACSubject *)s
5151
#pragma mark Connecting
5252

5353
- (RACDisposable *)connect {
54-
BOOL shouldConnect = OSAtomicCompareAndSwap32Barrier(0, 1, &_hasConnected);
54+
BOOL expected = NO;
55+
BOOL shouldConnect = atomic_compare_exchange_strong(&_hasConnected, &expected, YES);
5556

5657
if (shouldConnect) {
5758
self.serialDisposable.disposable = [self.sourceSignal subscribe:_signal];
@@ -61,24 +62,24 @@ - (RACDisposable *)connect {
6162
}
6263

6364
- (RACSignal *)autoconnect {
64-
__block volatile int32_t subscriberCount = 0;
65+
__block atomic_int subscriberCount = 0;
6566

66-
return [[RACSignal
67-
createSignal:^(id<RACSubscriber> subscriber) {
68-
OSAtomicIncrement32Barrier(&subscriberCount);
67+
return [[RACSignal
68+
createSignal:^(id<RACSubscriber> subscriber) {
69+
atomic_fetch_add(&subscriberCount, 1);
6970

7071
RACDisposable *subscriptionDisposable = [self.signal subscribe:subscriber];
7172
RACDisposable *connectionDisposable = [self connect];
7273

7374
return [RACDisposable disposableWithBlock:^{
7475
[subscriptionDisposable dispose];
7576

76-
if (OSAtomicDecrement32Barrier(&subscriberCount) == 0) {
77-
[connectionDisposable dispose];
78-
}
79-
}];
80-
}]
81-
setNameWithFormat:@"[%@] -autoconnect", self.signal.name];
77+
if (atomic_fetch_sub(&subscriberCount, 1) - 1 == 0) {
78+
[connectionDisposable dispose];
79+
}
80+
}];
81+
}]
82+
setNameWithFormat:@"[%@] -autoconnect", self.signal.name];
8283
}
8384

8485
@end

ReactiveObjC/RACSignal+Operations.m

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
#import "RACSubscriber.h"
2727
#import "RACTuple.h"
2828
#import "RACUnit.h"
29-
#import <libkern/OSAtomic.h>
29+
#import <stdatomic.h>
3030
#import <objc/runtime.h>
3131
#import <os/lock.h>
3232

@@ -698,9 +698,9 @@ - (RACDisposable *)setKeyPath:(NSString *)keyPath onObject:(NSObject *)object ni
698698

699699
RACCompoundDisposable *disposable = [RACCompoundDisposable compoundDisposable];
700700

701-
// Purposely not retaining 'object', since we want to tear down the binding
702-
// when it deallocates normally.
703-
__block void * volatile objectPtr = (__bridge void *)object;
701+
// Purposely not retaining 'object', since we want to tear down the binding
702+
// when it deallocates normally.
703+
__block _Atomic(void *) objectPtr = (__bridge void *)object;
704704

705705
RACDisposable *subscriptionDisposable = [self subscribeNext:^(id x) {
706706
// Possibly spec, possibly compiler bug, but this __bridge cast does not
@@ -750,13 +750,13 @@ - (RACDisposable *)setKeyPath:(NSString *)keyPath onObject:(NSObject *)object ni
750750
}
751751
#endif
752752

753-
while (YES) {
754-
void *ptr = objectPtr;
755-
if (OSAtomicCompareAndSwapPtrBarrier(ptr, NULL, &objectPtr)) {
756-
break;
757-
}
758-
}
759-
}];
753+
while (YES) {
754+
void *ptr = objectPtr;
755+
if (atomic_compare_exchange_strong(&objectPtr, &ptr, NULL)) {
756+
break;
757+
}
758+
}
759+
}];
760760

761761
[disposable addDisposable:clearPointerDisposable];
762762

@@ -1150,36 +1150,36 @@ - (RACSignal *)subscribeOn:(RACScheduler *)scheduler {
11501150
}
11511151

11521152
- (RACSignal *)deliverOnMainThread {
1153-
return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
1154-
__block volatile int32_t queueLength = 0;
1155-
1156-
void (^performOnMainThread)(dispatch_block_t) = ^(dispatch_block_t block) {
1157-
int32_t queued = OSAtomicIncrement32(&queueLength);
1158-
if (NSThread.isMainThread && queued == 1) {
1159-
block();
1160-
OSAtomicDecrement32(&queueLength);
1161-
} else {
1162-
dispatch_async(dispatch_get_main_queue(), ^{
1163-
block();
1164-
OSAtomicDecrement32(&queueLength);
1165-
});
1166-
}
1167-
};
1168-
1169-
return [self subscribeNext:^(id x) {
1170-
performOnMainThread(^{
1171-
[subscriber sendNext:x];
1172-
});
1173-
} error:^(NSError *error) {
1174-
performOnMainThread(^{
1175-
[subscriber sendError:error];
1176-
});
1177-
} completed:^{
1178-
performOnMainThread(^{
1179-
[subscriber sendCompleted];
1180-
});
1181-
}];
1182-
}] setNameWithFormat:@"[%@] -deliverOnMainThread", self.name];
1153+
return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
1154+
__block atomic_int queueLength = 0;
1155+
1156+
void (^performOnMainThread)(dispatch_block_t) = ^(dispatch_block_t block) {
1157+
int32_t queued = atomic_fetch_add(&queueLength, 1) + 1;
1158+
if (NSThread.isMainThread && queued == 1) {
1159+
block();
1160+
atomic_fetch_sub(&queueLength, 1);
1161+
} else {
1162+
dispatch_async(dispatch_get_main_queue(), ^{
1163+
block();
1164+
atomic_fetch_sub(&queueLength, 1);
1165+
});
1166+
}
1167+
};
1168+
1169+
return [self subscribeNext:^(id x) {
1170+
performOnMainThread(^{
1171+
[subscriber sendNext:x];
1172+
});
1173+
} error:^(NSError *error) {
1174+
performOnMainThread(^{
1175+
[subscriber sendError:error];
1176+
});
1177+
} completed:^{
1178+
performOnMainThread(^{
1179+
[subscriber sendCompleted];
1180+
});
1181+
}];
1182+
}] setNameWithFormat:@"[%@] -deliverOnMainThread", self.name];
11831183
}
11841184

11851185
- (RACSignal *)groupBy:(id<NSCopying> (^)(id object))keyBlock transform:(id (^)(id object))transformBlock {

0 commit comments

Comments
 (0)