Skip to content

Commit

Permalink
ReactiveObjc: Replace OSAtomic with stdatomic.
Browse files Browse the repository at this point in the history
OSAtomic is deprecated as of iOS10. This change is mainly a cherry pick
of upstream PR: ReactiveCocoa#178.
  • Loading branch information
arangato committed Aug 24, 2020
1 parent a9c9b53 commit 04a81a1
Show file tree
Hide file tree
Showing 13 changed files with 50 additions and 53 deletions.
1 change: 0 additions & 1 deletion ReactiveObjC/NSObject+RACPropertySubscribing.m
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
#import "RACSubscriber.h"
#import "RACSignal+Operations.h"
#import "RACTuple.h"
#import <libkern/OSAtomic.h>

@implementation NSObject (RACPropertySubscribing)

Expand Down
8 changes: 4 additions & 4 deletions ReactiveObjC/RACCommand.m
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#import "RACScheduler.h"
#import "RACSequence.h"
#import "RACSignal+Operations.h"
#import <libkern/OSAtomic.h>
#import <stdatomic.h>

NSString * const RACCommandErrorDomain = @"RACCommandErrorDomain";
NSString * const RACUnderlyingCommandErrorKey = @"RACUnderlyingCommandErrorKey";
Expand All @@ -26,7 +26,7 @@

@interface RACCommand () {
// Atomic backing variable for `allowsConcurrentExecution`.
volatile uint32_t _allowsConcurrentExecution;
atomic_bool _allowsConcurrentExecution;
}

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

- (void)setAllowsConcurrentExecution:(BOOL)allowed {
if (allowed) {
OSAtomicOr32Barrier(1, &_allowsConcurrentExecution);
atomic_fetch_or(&_allowsConcurrentExecution, 1);
} else {
OSAtomicAnd32Barrier(0, &_allowsConcurrentExecution);
atomic_fetch_and(&_allowsConcurrentExecution, 0);
}

[self.allowsConcurrentExecutionSubject sendNext:@(_allowsConcurrentExecution)];
Expand Down
12 changes: 6 additions & 6 deletions ReactiveObjC/RACDisposable.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@

#import "RACDisposable.h"
#import "RACScopedDisposable.h"
#import <libkern/OSAtomic.h>
#import <stdatomic.h>

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

@end
Expand All @@ -35,7 +35,7 @@ - (instancetype)init {
self = [super init];

_disposeBlock = (__bridge void *)self;
OSMemoryBarrier();
atomic_thread_fence(memory_order_seq_cst);

return self;
}
Expand All @@ -45,8 +45,8 @@ - (instancetype)initWithBlock:(void (^)(void))block {

self = [super init];

_disposeBlock = (void *)CFBridgingRetain([block copy]);
OSMemoryBarrier();
_disposeBlock = (void *)CFBridgingRetain([block copy]);
atomic_thread_fence(memory_order_seq_cst);

return self;
}
Expand All @@ -69,7 +69,7 @@ - (void)dispose {

while (YES) {
void *blockPtr = _disposeBlock;
if (OSAtomicCompareAndSwapPtrBarrier(blockPtr, NULL, &_disposeBlock)) {
if (atomic_compare_exchange_strong(&_disposeBlock, &blockPtr, NULL)) {
if (blockPtr != (__bridge void *)self) {
disposeBlock = CFBridgingRelease(blockPtr);
}
Expand Down
8 changes: 4 additions & 4 deletions ReactiveObjC/RACDynamicSequence.m
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//

#import "RACDynamicSequence.h"
#import <libkern/OSAtomic.h>
#import <stdatomic.h>

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

- (void)dealloc {
static volatile int32_t directDeallocCount = 0;
static atomic_int directDeallocCount = 0;

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

// Put this sequence's tail onto the autorelease pool so we stop
// recursing.
Expand Down
1 change: 0 additions & 1 deletion ReactiveObjC/RACDynamicSignal.m
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
#import "RACPassthroughSubscriber.h"
#import "RACScheduler+Private.h"
#import "RACSubscriber.h"
#import <libkern/OSAtomic.h>

@interface RACDynamicSignal ()

Expand Down
13 changes: 7 additions & 6 deletions ReactiveObjC/RACMulticastConnection.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#import "RACDisposable.h"
#import "RACSerialDisposable.h"
#import "RACSubject.h"
#import <libkern/OSAtomic.h>
#import <stdatomic.h>

@interface RACMulticastConnection () {
RACSubject *_signal;
Expand All @@ -24,7 +24,7 @@ @interface RACMulticastConnection () {
//
// If the swap is unsuccessful it means that `_sourceSignal` has already been
// connected and the caller has no action to take.
int32_t volatile _hasConnected;
_Atomic(BOOL) _hasConnected;
}

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

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

if (shouldConnect) {
self.serialDisposable.disposable = [self.sourceSignal subscribe:_signal];
Expand All @@ -61,19 +62,19 @@ - (RACDisposable *)connect {
}

- (RACSignal *)autoconnect {
__block volatile int32_t subscriberCount = 0;
__block atomic_int subscriberCount = 0;

return [[RACSignal
createSignal:^(id<RACSubscriber> subscriber) {
OSAtomicIncrement32Barrier(&subscriberCount);
atomic_fetch_add(&subscriberCount, 1);

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

return [RACDisposable disposableWithBlock:^{
[subscriptionDisposable dispose];

if (OSAtomicDecrement32Barrier(&subscriberCount) == 0) {
if (atomic_fetch_sub(&subscriberCount, 1) - 1 == 0) {
[connectionDisposable dispose];
}
}];
Expand Down
16 changes: 8 additions & 8 deletions ReactiveObjC/RACSignal+Operations.m
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
#import "RACSubscriber.h"
#import "RACTuple.h"
#import "RACUnit.h"
#import <libkern/OSAtomic.h>
#import <stdatomic.h>
#import <objc/runtime.h>
#import <os/lock.h>

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

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

RACDisposable *subscriptionDisposable = [self subscribeNext:^(id x) {
// Possibly spec, possibly compiler bug, but this __bridge cast does not
Expand Down Expand Up @@ -752,7 +752,7 @@ - (RACDisposable *)setKeyPath:(NSString *)keyPath onObject:(NSObject *)object ni

while (YES) {
void *ptr = objectPtr;
if (OSAtomicCompareAndSwapPtrBarrier(ptr, NULL, &objectPtr)) {
if (atomic_compare_exchange_strong(&objectPtr, &ptr, NULL)) {
break;
}
}
Expand Down Expand Up @@ -1151,17 +1151,17 @@ - (RACSignal *)subscribeOn:(RACScheduler *)scheduler {

- (RACSignal *)deliverOnMainThread {
return [[RACSignal createSignal:^(id<RACSubscriber> subscriber) {
__block volatile int32_t queueLength = 0;
__block atomic_int queueLength = 0;

void (^performOnMainThread)(dispatch_block_t) = ^(dispatch_block_t block) {
int32_t queued = OSAtomicIncrement32(&queueLength);
int32_t queued = atomic_fetch_add(&queueLength, 1) + 1;
if (NSThread.isMainThread && queued == 1) {
block();
OSAtomicDecrement32(&queueLength);
atomic_fetch_sub(&queueLength, 1);
} else {
dispatch_async(dispatch_get_main_queue(), ^{
block();
OSAtomicDecrement32(&queueLength);
atomic_fetch_sub(&queueLength, 1);
});
}
};
Expand Down
16 changes: 8 additions & 8 deletions ReactiveObjC/RACSignal.m
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#import "RACSubject.h"
#import "RACSubscriber+Private.h"
#import "RACTuple.h"
#import <libkern/OSAtomic.h>
#import <stdatomic.h>

@implementation RACSignal

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

__block volatile int32_t signalCount = 1; // indicates self
__block atomic_int signalCount = 1; // indicates self

RACCompoundDisposable *compoundDisposable = [RACCompoundDisposable compoundDisposable];

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

void (^addSignal)(RACSignal *) = ^(RACSignal *signal) {
OSAtomicIncrement32Barrier(&signalCount);
atomic_fetch_add(&signalCount, 1);

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

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

RACCompoundDisposable *disposable = [RACCompoundDisposable compoundDisposable];

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

OSAtomicIncrement32(&subscriptionCount);
atomic_fetch_add(&subscriptionCount, 1);

RACDisposable *innerDisposable = [signal subscribeNext:^(id x) {
[subscriber sendNext:x];
} error:^(NSError *error) {
[subscriber sendError:error];
[disposable dispose];
} completed:^{
if (!OSAtomicDecrement32(&subscriptionCount)) {
if (atomic_fetch_sub(&subscriptionCount, 1) - 1 == 0) {
[subscriber sendCompleted];
}
}];
Expand All @@ -395,7 +395,7 @@ - (instancetype)flattenMap:(RACSignal *(^)(id))block {
} error:^(NSError *error) {
[subscriber sendError:error];
} completed:^{
if (!OSAtomicDecrement32(&subscriptionCount)) {
if (atomic_fetch_sub(&subscriptionCount, 1) - 1 == 0) {
[subscriber sendCompleted];
}
}];
Expand Down
1 change: 0 additions & 1 deletion ReactiveObjC/extobjc/EXTRuntimeExtensions.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

#import <ctype.h>
#import <Foundation/Foundation.h>
#import <libkern/OSAtomic.h>
#import <objc/message.h>
#import <pthread.h>
#import <stdio.h>
Expand Down
1 change: 0 additions & 1 deletion ReactiveObjCTests/RACMulticastConnectionSpec.m
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
#import "RACSubscriber.h"
#import "RACReplaySubject.h"
#import "RACScheduler.h"
#import <libkern/OSAtomic.h>

QuickSpecBegin(RACMulticastConnectionSpec)

Expand Down
2 changes: 1 addition & 1 deletion ReactiveObjCTests/RACSignalSpec.m
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ + (void)configure:(Configuration *)configuration {
}];

return [RACDisposable disposableWithBlock:^{
++done;
atomic_fetch_add(&done, 1);
}];
}];

Expand Down
12 changes: 6 additions & 6 deletions ReactiveObjCTests/RACSubscriberSpec.m
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@

#import "RACSubscriber.h"
#import "RACSubscriber+Private.h"
#import <libkern/OSAtomic.h>
#import <stdatomic.h>

QuickSpecBegin(RACSubscriberSpec)

__block RACSubscriber *subscriber;
__block NSMutableArray *values;

__block volatile BOOL finished;
__block volatile int32_t nextsAfterFinished;
__block _Atomic(BOOL) finished;
__block atomic_int nextsAfterFinished;

__block BOOL success;
__block NSError *error;
Expand All @@ -36,7 +36,7 @@
error = nil;

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

[values addObject:value];
} error:^(NSError *e) {
Expand Down Expand Up @@ -111,7 +111,7 @@
[subscriber sendCompleted];

finished = YES;
OSMemoryBarrier();
atomic_thread_fence(memory_order_seq_cst);
});
});

Expand All @@ -122,7 +122,7 @@
[subscriber sendError:nil];

finished = YES;
OSMemoryBarrier();
atomic_thread_fence(memory_order_seq_cst);
});
});
});
Expand Down
12 changes: 6 additions & 6 deletions ReactiveObjCTests/RACTargetQueueSchedulerSpec.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
@import Nimble;

#import "RACTargetQueueScheduler.h"
#import <libkern/OSAtomic.h>
#import <stdatomic.h>

QuickSpecBegin(RACTargetQueueSchedulerSpec)

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

[scheduler schedule:^{
OSAtomicIncrement32Barrier(&startedCount);
atomic_fetch_add(&startedCount, 1);
}];

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

OSAtomicAnd32Barrier(0, &waitInFirst);
atomic_fetch_and(&waitInFirst, 0);

expect(@(startedCount)).toEventually(equal(@2));
});
Expand Down

0 comments on commit 04a81a1

Please sign in to comment.