Skip to content

Commit e0f9f1c

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 e0f9f1c

13 files changed

+50
-53
lines changed

ReactiveObjC/NSObject+RACPropertySubscribing.m

-1
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

+4-4
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
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";
@@ -26,7 +26,7 @@
2626

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

3232
/// A subject that sends added execution signals.
@@ -55,9 +55,9 @@ - (BOOL)allowsConcurrentExecution {
5555

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

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

ReactiveObjC/RACDisposable.m

+6-6
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 () {
1414
// A copied block of type void (^)(void) containing the logic for disposal,
1515
// a pointer to `self` if no logic should be performed upon disposal, or
1616
// NULL if the receiver is already disposed.
1717
//
1818
// This should only be used atomically.
19-
void * volatile _disposeBlock;
19+
_Atomic(void *) _disposeBlock;
2020
}
2121

2222
@end
@@ -35,7 +35,7 @@ - (instancetype)init {
3535
self = [super init];
3636

3737
_disposeBlock = (__bridge void *)self;
38-
OSMemoryBarrier();
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
}
@@ -69,7 +69,7 @@ - (void)dispose {
6969

7070
while (YES) {
7171
void *blockPtr = _disposeBlock;
72-
if (OSAtomicCompareAndSwapPtrBarrier(blockPtr, NULL, &_disposeBlock)) {
72+
if (atomic_compare_exchange_strong(&_disposeBlock, &blockPtr, NULL)) {
7373
if (blockPtr != (__bridge void *)self) {
7474
disposeBlock = CFBridgingRelease(blockPtr);
7575
}

ReactiveObjC/RACDynamicSequence.m

+4-4
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

-1
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

+7-6
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
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 () {
1717
RACSubject *_signal;
@@ -24,7 +24,7 @@ @interface RACMulticastConnection () {
2424
//
2525
// If the swap is unsuccessful it means that `_sourceSignal` has already been
2626
// connected and the caller has no action to take.
27-
int32_t volatile _hasConnected;
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,19 +62,19 @@ - (RACDisposable *)connect {
6162
}
6263

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

6667
return [[RACSignal
6768
createSignal:^(id<RACSubscriber> subscriber) {
68-
OSAtomicIncrement32Barrier(&subscriberCount);
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+
if (atomic_fetch_sub(&subscriberCount, 1) - 1 == 0) {
7778
[connectionDisposable dispose];
7879
}
7980
}];

ReactiveObjC/RACSignal+Operations.m

+8-8
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

@@ -700,7 +700,7 @@ - (RACDisposable *)setKeyPath:(NSString *)keyPath onObject:(NSObject *)object ni
700700

701701
// Purposely not retaining 'object', since we want to tear down the binding
702702
// when it deallocates normally.
703-
__block void * volatile objectPtr = (__bridge void *)object;
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
@@ -752,7 +752,7 @@ - (RACDisposable *)setKeyPath:(NSString *)keyPath onObject:(NSObject *)object ni
752752

753753
while (YES) {
754754
void *ptr = objectPtr;
755-
if (OSAtomicCompareAndSwapPtrBarrier(ptr, NULL, &objectPtr)) {
755+
if (atomic_compare_exchange_strong(&objectPtr, &ptr, NULL)) {
756756
break;
757757
}
758758
}
@@ -1151,17 +1151,17 @@ - (RACSignal *)subscribeOn:(RACScheduler *)scheduler {
11511151

11521152
- (RACSignal *)deliverOnMainThread {
11531153
return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
1154-
__block volatile int32_t queueLength = 0;
1155-
1154+
__block atomic_int queueLength = 0;
1155+
11561156
void (^performOnMainThread)(dispatch_block_t) = ^(dispatch_block_t block) {
1157-
int32_t queued = OSAtomicIncrement32(&queueLength);
1157+
int32_t queued = atomic_fetch_add(&queueLength, 1) + 1;
11581158
if (NSThread.isMainThread && queued == 1) {
11591159
block();
1160-
OSAtomicDecrement32(&queueLength);
1160+
atomic_fetch_sub(&queueLength, 1);
11611161
} else {
11621162
dispatch_async(dispatch_get_main_queue(), ^{
11631163
block();
1164-
OSAtomicDecrement32(&queueLength);
1164+
atomic_fetch_sub(&queueLength, 1);
11651165
});
11661166
}
11671167
};

ReactiveObjC/RACSignal.m

+8-8
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
#import "RACSubject.h"
2424
#import "RACSubscriber+Private.h"
2525
#import "RACTuple.h"
26-
#import <libkern/OSAtomic.h>
26+
#import <stdatomic.h>
2727

2828
@implementation RACSignal
2929

@@ -108,12 +108,12 @@ - (RACSignal *)bind:(RACSignalBindBlock (^)(void))block {
108108
return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
109109
RACSignalBindBlock bindingBlock = block();
110110

111-
__block volatile int32_t signalCount = 1; // indicates self
111+
__block atomic_int signalCount = 1; // indicates self
112112

113113
RACCompoundDisposable *compoundDisposable = [RACCompoundDisposable compoundDisposable];
114114

115115
void (^completeSignal)(RACDisposable *) = ^(RACDisposable *finishedDisposable) {
116-
if (OSAtomicDecrement32Barrier(&signalCount) == 0) {
116+
if (atomic_fetch_sub(&signalCount, 1) - 1 == 0) {
117117
[subscriber sendCompleted];
118118
[compoundDisposable dispose];
119119
} else {
@@ -122,7 +122,7 @@ - (RACSignal *)bind:(RACSignalBindBlock (^)(void))block {
122122
};
123123

124124
void (^addSignal)(RACSignal *) = ^(RACSignal *signal) {
125-
OSAtomicIncrement32Barrier(&signalCount);
125+
atomic_fetch_add(&signalCount, 1);
126126

127127
RACSerialDisposable *selfDisposable = [[RACSerialDisposable alloc] init];
128128
[compoundDisposable addDisposable:selfDisposable];
@@ -363,7 +363,7 @@ - (instancetype)filter:(BOOL (^)(id))block {
363363

364364
- (instancetype)flattenMap:(RACSignal *(^)(id))block {
365365
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
366-
__block volatile int32_t subscriptionCount = 1;
366+
__block atomic_int subscriptionCount = 1;
367367

368368
RACCompoundDisposable *disposable = [RACCompoundDisposable compoundDisposable];
369369

@@ -378,15 +378,15 @@ - (instancetype)flattenMap:(RACSignal *(^)(id))block {
378378
}
379379
NSCAssert([signal isKindOfClass:RACSignal.class], @"Expected a RACSignal, got %@", signal);
380380

381-
OSAtomicIncrement32(&subscriptionCount);
381+
atomic_fetch_add(&subscriptionCount, 1);
382382

383383
RACDisposable *innerDisposable = [signal subscribeNext:^(id x) {
384384
[subscriber sendNext:x];
385385
} error:^(NSError *error) {
386386
[subscriber sendError:error];
387387
[disposable dispose];
388388
} completed:^{
389-
if (!OSAtomicDecrement32(&subscriptionCount)) {
389+
if (atomic_fetch_sub(&subscriptionCount, 1) - 1 == 0) {
390390
[subscriber sendCompleted];
391391
}
392392
}];
@@ -395,7 +395,7 @@ - (instancetype)flattenMap:(RACSignal *(^)(id))block {
395395
} error:^(NSError *error) {
396396
[subscriber sendError:error];
397397
} completed:^{
398-
if (!OSAtomicDecrement32(&subscriptionCount)) {
398+
if (atomic_fetch_sub(&subscriptionCount, 1) - 1 == 0) {
399399
[subscriber sendCompleted];
400400
}
401401
}];

ReactiveObjC/extobjc/EXTRuntimeExtensions.m

-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
#import <ctype.h>
1313
#import <Foundation/Foundation.h>
14-
#import <libkern/OSAtomic.h>
1514
#import <objc/message.h>
1615
#import <pthread.h>
1716
#import <stdio.h>

ReactiveObjCTests/RACMulticastConnectionSpec.m

-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
#import "RACSubscriber.h"
1616
#import "RACReplaySubject.h"
1717
#import "RACScheduler.h"
18-
#import <libkern/OSAtomic.h>
1918

2019
QuickSpecBegin(RACMulticastConnectionSpec)
2120

ReactiveObjCTests/RACSignalSpec.m

+1-1
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ + (void)configure:(Configuration *)configuration {
121121
}];
122122

123123
return [RACDisposable disposableWithBlock:^{
124-
++done;
124+
atomic_fetch_add(&done, 1);
125125
}];
126126
}];
127127

ReactiveObjCTests/RACSubscriberSpec.m

+6-6
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@
1313

1414
#import "RACSubscriber.h"
1515
#import "RACSubscriber+Private.h"
16-
#import <libkern/OSAtomic.h>
16+
#import <stdatomic.h>
1717

1818
QuickSpecBegin(RACSubscriberSpec)
1919

2020
__block RACSubscriber *subscriber;
2121
__block NSMutableArray *values;
2222

23-
__block volatile BOOL finished;
24-
__block volatile int32_t nextsAfterFinished;
23+
__block _Atomic(BOOL) finished;
24+
__block atomic_int nextsAfterFinished;
2525

2626
__block BOOL success;
2727
__block NSError *error;
@@ -36,7 +36,7 @@
3636
error = nil;
3737

3838
subscriber = [RACSubscriber subscriberWithNext:^(id value) {
39-
if (finished) OSAtomicIncrement32Barrier(&nextsAfterFinished);
39+
if (finished) atomic_fetch_add(&nextsAfterFinished, 1);
4040

4141
[values addObject:value];
4242
} error:^(NSError *e) {
@@ -111,7 +111,7 @@
111111
[subscriber sendCompleted];
112112

113113
finished = YES;
114-
OSMemoryBarrier();
114+
atomic_thread_fence(memory_order_seq_cst);
115115
});
116116
});
117117

@@ -122,7 +122,7 @@
122122
[subscriber sendError:nil];
123123

124124
finished = YES;
125-
OSMemoryBarrier();
125+
atomic_thread_fence(memory_order_seq_cst);
126126
});
127127
});
128128
});

ReactiveObjCTests/RACTargetQueueSchedulerSpec.m

+6-6
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
@import Nimble;
1111

1212
#import "RACTargetQueueScheduler.h"
13-
#import <libkern/OSAtomic.h>
13+
#import <stdatomic.h>
1414

1515
QuickSpecBegin(RACTargetQueueSchedulerSpec)
1616

@@ -28,20 +28,20 @@
2828
qck_it(@"should schedule blocks FIFO even when given a concurrent queue", ^{
2929
dispatch_queue_t queue = dispatch_queue_create("test-queue", DISPATCH_QUEUE_CONCURRENT);
3030
RACScheduler *scheduler = [[RACTargetQueueScheduler alloc] initWithName:@"test-scheduler" targetQueue:queue];
31-
__block volatile int32_t startedCount = 0;
32-
__block volatile uint32_t waitInFirst = 1;
31+
__block atomic_int startedCount = 0;
32+
__block atomic_uint waitInFirst = 1;
3333
[scheduler schedule:^{
34-
OSAtomicIncrement32Barrier(&startedCount);
34+
atomic_fetch_add(&startedCount, 1);
3535
while (waitInFirst == 1) ;
3636
}];
3737

3838
[scheduler schedule:^{
39-
OSAtomicIncrement32Barrier(&startedCount);
39+
atomic_fetch_add(&startedCount, 1);
4040
}];
4141

4242
expect(@(startedCount)).toEventually(equal(@1));
4343

44-
OSAtomicAnd32Barrier(0, &waitInFirst);
44+
atomic_fetch_and(&waitInFirst, 0);
4545

4646
expect(@(startedCount)).toEventually(equal(@2));
4747
});

0 commit comments

Comments
 (0)