mirror of
https://github.com/HackPlan/AsyncDisplayKit.git
synced 2026-01-12 22:44:08 +08:00
Remove dependencies for ASAssert and ASThread in the async transaction system (#2333)
This commit is contained in:
committed by
Adlai Holler
parent
f369be43dd
commit
2de129008f
@@ -10,10 +10,12 @@
|
||||
|
||||
#import "_ASAsyncTransaction.h"
|
||||
#import "_ASAsyncTransactionGroup.h"
|
||||
#import "ASAssert.h"
|
||||
#import "ASThread.h"
|
||||
|
||||
#import <list>
|
||||
#import <map>
|
||||
#import <mutex>
|
||||
|
||||
#define ASAsyncTransactionAssertMainThread() NSAssert(0 != pthread_main_np(), @"This method must be called on the main thread");
|
||||
|
||||
NSInteger const ASDefaultTransactionPriority = 0;
|
||||
|
||||
@@ -35,7 +37,7 @@ NSInteger const ASDefaultTransactionPriority = 0;
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
ASDisplayNodeAssertNil(_operationCompletionBlock, @"Should have been called and released before -dealloc");
|
||||
NSAssert(_operationCompletionBlock == nil, @"Should have been called and released before -dealloc");
|
||||
}
|
||||
|
||||
- (void)callAndReleaseCompletionBlock:(BOOL)canceled;
|
||||
@@ -115,7 +117,7 @@ private:
|
||||
|
||||
int _pendingOperations;
|
||||
std::list<GroupNotify> _notifyList;
|
||||
ASDN::Condition _condition;
|
||||
std::condition_variable _condition;
|
||||
BOOL _releaseCalled;
|
||||
ASAsyncTransactionQueue &_queue;
|
||||
};
|
||||
@@ -142,7 +144,7 @@ private:
|
||||
};
|
||||
|
||||
std::map<dispatch_queue_t, DispatchEntry> _entries;
|
||||
ASDN::Mutex _mutex;
|
||||
std::mutex _mutex;
|
||||
};
|
||||
|
||||
ASAsyncTransactionQueue::Group* ASAsyncTransactionQueue::createGroup()
|
||||
@@ -153,7 +155,7 @@ ASAsyncTransactionQueue::Group* ASAsyncTransactionQueue::createGroup()
|
||||
|
||||
void ASAsyncTransactionQueue::GroupImpl::release()
|
||||
{
|
||||
ASDN::MutexLocker locker(_queue._mutex);
|
||||
std::lock_guard<std::mutex> l(_queue._mutex);
|
||||
|
||||
if (_pendingOperations == 0) {
|
||||
delete this;
|
||||
@@ -202,7 +204,7 @@ void ASAsyncTransactionQueue::DispatchEntry::pushOperation(ASAsyncTransactionQue
|
||||
void ASAsyncTransactionQueue::GroupImpl::schedule(NSInteger priority, dispatch_queue_t queue, dispatch_block_t block)
|
||||
{
|
||||
ASAsyncTransactionQueue &q = _queue;
|
||||
ASDN::MutexLocker locker(q._mutex);
|
||||
std::lock_guard<std::mutex> l(q._mutex);
|
||||
|
||||
DispatchEntry &entry = q._entries[queue];
|
||||
|
||||
@@ -231,19 +233,19 @@ void ASAsyncTransactionQueue::GroupImpl::schedule(NSInteger priority, dispatch_q
|
||||
++entry._threadCount;
|
||||
|
||||
dispatch_async(queue, ^{
|
||||
ASDN::MutexLocker lock(q._mutex);
|
||||
std::unique_lock<std::mutex> lock(q._mutex);
|
||||
|
||||
// go until there are no more pending operations
|
||||
while (!entry._operationQueue.empty()) {
|
||||
Operation operation = entry.popNextOperation(respectPriority);
|
||||
{
|
||||
ASDN::MutexUnlocker unlock(q._mutex);
|
||||
if (operation._block) {
|
||||
operation._block();
|
||||
}
|
||||
operation._group->leave();
|
||||
operation._block = nil; // the block must be freed while mutex is unlocked
|
||||
|
||||
lock.unlock();
|
||||
if (operation._block) {
|
||||
operation._block();
|
||||
}
|
||||
operation._group->leave();
|
||||
operation._block = nil; // the block must be freed while mutex is unlocked
|
||||
lock.lock();
|
||||
}
|
||||
--entry._threadCount;
|
||||
|
||||
@@ -257,8 +259,8 @@ void ASAsyncTransactionQueue::GroupImpl::schedule(NSInteger priority, dispatch_q
|
||||
|
||||
void ASAsyncTransactionQueue::GroupImpl::notify(dispatch_queue_t queue, dispatch_block_t block)
|
||||
{
|
||||
ASDN::MutexLocker locker(_queue._mutex);
|
||||
|
||||
std::lock_guard<std::mutex> l(_queue._mutex);
|
||||
|
||||
if (_pendingOperations == 0) {
|
||||
dispatch_async(queue, block);
|
||||
} else {
|
||||
@@ -271,13 +273,13 @@ void ASAsyncTransactionQueue::GroupImpl::notify(dispatch_queue_t queue, dispatch
|
||||
|
||||
void ASAsyncTransactionQueue::GroupImpl::enter()
|
||||
{
|
||||
ASDN::MutexLocker locker(_queue._mutex);
|
||||
std::lock_guard<std::mutex> l(_queue._mutex);
|
||||
++_pendingOperations;
|
||||
}
|
||||
|
||||
void ASAsyncTransactionQueue::GroupImpl::leave()
|
||||
{
|
||||
ASDN::MutexLocker locker(_queue._mutex);
|
||||
std::lock_guard<std::mutex> l(_queue._mutex);
|
||||
--_pendingOperations;
|
||||
|
||||
if (_pendingOperations == 0) {
|
||||
@@ -288,7 +290,7 @@ void ASAsyncTransactionQueue::GroupImpl::leave()
|
||||
dispatch_async(notify._queue, notify._block);
|
||||
}
|
||||
|
||||
_condition.signal();
|
||||
_condition.notify_one();
|
||||
|
||||
// there was attempt to release the group before, but we still
|
||||
// had operations scheduled so now is good time
|
||||
@@ -300,9 +302,9 @@ void ASAsyncTransactionQueue::GroupImpl::leave()
|
||||
|
||||
void ASAsyncTransactionQueue::GroupImpl::wait()
|
||||
{
|
||||
ASDN::MutexLocker locker(_queue._mutex);
|
||||
std::unique_lock<std::mutex> lock(_queue._mutex);
|
||||
while (_pendingOperations > 0) {
|
||||
_condition.wait(_queue._mutex);
|
||||
_condition.wait(lock);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,7 +341,7 @@ ASAsyncTransactionQueue & ASAsyncTransactionQueue::instance()
|
||||
- (void)dealloc
|
||||
{
|
||||
// Uncommitted transactions break our guarantees about releasing completion blocks on callbackQueue.
|
||||
ASDisplayNodeAssert(__atomic_load_n(&_state, __ATOMIC_SEQ_CST) != ASAsyncTransactionStateOpen, @"Uncommitted ASAsyncTransactions are not allowed");
|
||||
NSAssert(__atomic_load_n(&_state, __ATOMIC_SEQ_CST) != ASAsyncTransactionStateOpen, @"Uncommitted ASAsyncTransactions are not allowed");
|
||||
if (_group) {
|
||||
_group->release();
|
||||
}
|
||||
@@ -363,8 +365,8 @@ ASAsyncTransactionQueue & ASAsyncTransactionQueue::instance()
|
||||
queue:(dispatch_queue_t)queue
|
||||
completion:(asyncdisplaykit_async_transaction_operation_completion_block_t)completion
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
ASDisplayNodeAssert(__atomic_load_n(&_state, __ATOMIC_SEQ_CST) == ASAsyncTransactionStateOpen, @"You can only add operations to open transactions");
|
||||
ASAsyncTransactionAssertMainThread();
|
||||
NSAssert(__atomic_load_n(&_state, __ATOMIC_SEQ_CST) == ASAsyncTransactionStateOpen, @"You can only add operations to open transactions");
|
||||
|
||||
[self _ensureTransactionData];
|
||||
|
||||
@@ -398,8 +400,8 @@ ASAsyncTransactionQueue & ASAsyncTransactionQueue::instance()
|
||||
queue:(dispatch_queue_t)queue
|
||||
completion:(asyncdisplaykit_async_transaction_operation_completion_block_t)completion
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
ASDisplayNodeAssert(__atomic_load_n(&_state, __ATOMIC_SEQ_CST) == ASAsyncTransactionStateOpen, @"You can only add operations to open transactions");
|
||||
ASAsyncTransactionAssertMainThread();
|
||||
NSAssert(__atomic_load_n(&_state, __ATOMIC_SEQ_CST) == ASAsyncTransactionStateOpen, @"You can only add operations to open transactions");
|
||||
|
||||
[self _ensureTransactionData];
|
||||
|
||||
@@ -425,15 +427,15 @@ ASAsyncTransactionQueue & ASAsyncTransactionQueue::instance()
|
||||
|
||||
- (void)cancel
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
ASDisplayNodeAssert(__atomic_load_n(&_state, __ATOMIC_SEQ_CST) != ASAsyncTransactionStateOpen, @"You can only cancel a committed or already-canceled transaction");
|
||||
ASAsyncTransactionAssertMainThread();
|
||||
NSAssert(__atomic_load_n(&_state, __ATOMIC_SEQ_CST) != ASAsyncTransactionStateOpen, @"You can only cancel a committed or already-canceled transaction");
|
||||
__atomic_store_n(&_state, ASAsyncTransactionStateCanceled, __ATOMIC_SEQ_CST);
|
||||
}
|
||||
|
||||
- (void)commit
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
ASDisplayNodeAssert(__atomic_load_n(&_state, __ATOMIC_SEQ_CST) == ASAsyncTransactionStateOpen, @"You cannot double-commit a transaction");
|
||||
ASAsyncTransactionAssertMainThread();
|
||||
NSAssert(__atomic_load_n(&_state, __ATOMIC_SEQ_CST) == ASAsyncTransactionStateOpen, @"You cannot double-commit a transaction");
|
||||
__atomic_store_n(&_state, ASAsyncTransactionStateCommitted, __ATOMIC_SEQ_CST);
|
||||
|
||||
if ([_operations count] == 0) {
|
||||
@@ -442,12 +444,12 @@ ASAsyncTransactionQueue & ASAsyncTransactionQueue::instance()
|
||||
_completionBlock(self, NO);
|
||||
}
|
||||
} else {
|
||||
ASDisplayNodeAssert(_group != NULL, @"If there are operations, dispatch group should have been created");
|
||||
NSAssert(_group != NULL, @"If there are operations, dispatch group should have been created");
|
||||
|
||||
_group->notify(_callbackQueue, ^{
|
||||
// _callbackQueue is the main queue in current practice (also asserted in -waitUntilComplete).
|
||||
// This code should be reviewed before taking on significantly different use cases.
|
||||
ASDisplayNodeAssertMainThread();
|
||||
ASAsyncTransactionAssertMainThread();
|
||||
[self completeTransaction];
|
||||
});
|
||||
}
|
||||
@@ -474,10 +476,10 @@ ASAsyncTransactionQueue & ASAsyncTransactionQueue::instance()
|
||||
|
||||
- (void)waitUntilComplete
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
ASAsyncTransactionAssertMainThread();
|
||||
if (__atomic_load_n(&_state, __ATOMIC_SEQ_CST) != ASAsyncTransactionStateComplete) {
|
||||
if (_group) {
|
||||
ASDisplayNodeAssertTrue(_callbackQueue == dispatch_get_main_queue());
|
||||
NSAssert(_callbackQueue == dispatch_get_main_queue(), nil);
|
||||
_group->wait();
|
||||
|
||||
// At this point, the asynchronous operation may have completed, but the runloop
|
||||
@@ -487,7 +489,7 @@ ASAsyncTransactionQueue & ASAsyncTransactionQueue::instance()
|
||||
// to continue, e.g. in the implementation of -[ASDisplayNode recursivelyEnsureDisplay].
|
||||
if (__atomic_load_n(&_state, __ATOMIC_SEQ_CST) == ASAsyncTransactionStateOpen) {
|
||||
[_ASAsyncTransactionGroup commit];
|
||||
ASDisplayNodeAssert(__atomic_load_n(&_state, __ATOMIC_SEQ_CST) != ASAsyncTransactionStateOpen, @"Transaction should not be open after committing group");
|
||||
NSAssert(__atomic_load_n(&_state, __ATOMIC_SEQ_CST) != ASAsyncTransactionStateOpen, @"Transaction should not be open after committing group");
|
||||
}
|
||||
// If we needed to commit the group above, -completeTransaction may have already been run.
|
||||
// It is designed to accommodate this by checking _state to ensure it is not complete.
|
||||
|
||||
Reference in New Issue
Block a user