mirror of
https://github.com/HackPlan/AsyncDisplayKit.git
synced 2026-04-28 19:55:34 +08:00
Properly lock layoutableContextMap
Signed-off-by: Huy Nguyen <huy@pinterest.com>
This commit is contained in:
@@ -9,8 +9,13 @@
|
||||
#import "ASLayoutablePrivate.h"
|
||||
#import "pthread.h"
|
||||
#import <map>
|
||||
#import <iterator>
|
||||
#import "ASThread.h"
|
||||
|
||||
ASLayoutableContext ASLayoutableContextMake(int32_t transitionID, BOOL needsVisualizeNode)
|
||||
int32_t const ASLayoutableContextInvalidTransitionID = 0;
|
||||
int32_t const ASLayoutableContextDefaultTransitionID = ASLayoutableContextInvalidTransitionID + 1;
|
||||
|
||||
static inline ASLayoutableContext _ASLayoutableContextMake(int32_t transitionID, BOOL needsVisualizeNode)
|
||||
{
|
||||
struct ASLayoutableContext context;
|
||||
context.transitionID = transitionID;
|
||||
@@ -18,6 +23,26 @@ ASLayoutableContext ASLayoutableContextMake(int32_t transitionID, BOOL needsVisu
|
||||
return context;
|
||||
}
|
||||
|
||||
static inline BOOL _IsValidTransitionID(int32_t transitionID)
|
||||
{
|
||||
return transitionID > ASLayoutableContextInvalidTransitionID;
|
||||
}
|
||||
|
||||
struct ASLayoutableContext const ASLayoutableContextNull = _ASLayoutableContextMake(ASLayoutableContextInvalidTransitionID, NO);
|
||||
|
||||
BOOL ASLayoutableContextIsNull(struct ASLayoutableContext context)
|
||||
{
|
||||
return !_IsValidTransitionID(context.transitionID);
|
||||
}
|
||||
|
||||
ASLayoutableContext ASLayoutableContextMake(int32_t transitionID, BOOL needsVisualizeNode)
|
||||
{
|
||||
NSCAssert(_IsValidTransitionID(transitionID), @"Invalid transition ID");
|
||||
return _ASLayoutableContextMake(transitionID, needsVisualizeNode);
|
||||
}
|
||||
|
||||
// Note: This is a non-recursive static lock. If it needs to be recursive, use ASDISPLAYNODE_MUTEX_RECURSIVE_INITIALIZER
|
||||
static ASDN::StaticMutex _layoutableContextLock = ASDISPLAYNODE_MUTEX_INITIALIZER;
|
||||
static std::map<mach_port_t, ASLayoutableContext> layoutableContextMap;
|
||||
|
||||
static inline mach_port_t ASLayoutableGetCurrentContextKey()
|
||||
@@ -27,14 +52,26 @@ static inline mach_port_t ASLayoutableGetCurrentContextKey()
|
||||
|
||||
void ASLayoutableSetCurrentContext(struct ASLayoutableContext context)
|
||||
{
|
||||
layoutableContextMap[ASLayoutableGetCurrentContextKey()] = context;
|
||||
const mach_port_t key = ASLayoutableGetCurrentContextKey();
|
||||
ASDN::StaticMutexLocker l(_layoutableContextLock);
|
||||
layoutableContextMap[key] = context;
|
||||
}
|
||||
|
||||
struct ASLayoutableContext ASLayoutableGetCurrentContext()
|
||||
{
|
||||
return layoutableContextMap[ASLayoutableGetCurrentContextKey()];
|
||||
const mach_port_t key = ASLayoutableGetCurrentContextKey();
|
||||
ASDN::StaticMutexLocker l(_layoutableContextLock);
|
||||
const auto it = layoutableContextMap.find(key);
|
||||
if (it != layoutableContextMap.end()) {
|
||||
// Found an interator with above key. "it->first" is the key itself, "it->second" is the context value.
|
||||
return it->second;
|
||||
}
|
||||
return ASLayoutableContextNull;
|
||||
}
|
||||
|
||||
void ASLayoutableClearCurrentContext() {
|
||||
layoutableContextMap.erase(ASLayoutableGetCurrentContextKey());
|
||||
void ASLayoutableClearCurrentContext()
|
||||
{
|
||||
const mach_port_t key = ASLayoutableGetCurrentContextKey();
|
||||
ASDN::StaticMutexLocker l(_layoutableContextLock);
|
||||
layoutableContextMap.erase(key);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user