mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-10 08:20:16 +00:00
Replace pthread specifics with C11 thread-local variables (#811)
* Replace pthread specifics with C11 thread-local variables for speed and safety * Increment changelog
This commit is contained in:
parent
6b57b1cf1a
commit
a1055254f7
@ -30,6 +30,7 @@
|
||||
- Fix ASTextNode2 is accessing backgroundColor off main while sizing / layout is happening. [Michael Schneider](https://github.com/maicki) [#794](https://github.com/TextureGroup/Texture/pull/778/)
|
||||
- Pass scrollViewWillEndDragging delegation through in ASIGListAdapterDataSource for IGListKit integration. [#796](https://github.com/TextureGroup/Texture/pull/796)
|
||||
- Fix UIResponder handling with view backing ASDisplayNode. [Michael Schneider](https://github.com/maicki) [#789] (https://github.com/TextureGroup/Texture/pull/789/)
|
||||
- Optimized thread-local storage by replacing pthread_specific with C11 thread-local variables. [Adlai Holler](https://github.com/Adlai-Holler) [#811] (https://github.com/TextureGroup/Texture/pull/811/)
|
||||
|
||||
## 2.6
|
||||
- [Xcode 9] Updated to require Xcode 9 (to fix warnings) [Garrett Moon](https://github.com/garrettmoon)
|
||||
|
||||
@ -15,8 +15,6 @@
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
|
||||
#import <pthread.h>
|
||||
|
||||
#import <AsyncDisplayKit/ASBlockTypes.h>
|
||||
#import <AsyncDisplayKit/ASDisplayNode.h>
|
||||
|
||||
|
||||
@ -1046,15 +1046,11 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
|
||||
restrictedToSize:(ASLayoutElementSize)size
|
||||
relativeToParentSize:(CGSize)parentSize
|
||||
{
|
||||
// Use a pthread specific to mark when this method is called re-entrant on same thread.
|
||||
// We only want one calculateLayout signpost interval per thread.
|
||||
// This is fast enough to do it unconditionally.
|
||||
auto key = ASPthreadStaticKey(NULL);
|
||||
BOOL isRootCall = (pthread_getspecific(key) == NULL);
|
||||
static _Thread_local NSInteger tls_callDepth;
|
||||
as_activity_scope_verbose(as_activity_create("Calculate node layout", AS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT));
|
||||
as_log_verbose(ASLayoutLog(), "Calculating layout for %@ sizeRange %@", self, NSStringFromASSizeRange(constrainedSize));
|
||||
if (isRootCall) {
|
||||
pthread_setspecific(key, kCFBooleanTrue);
|
||||
if (tls_callDepth++ == 0) {
|
||||
ASSignpostStart(ASSignpostCalculateLayout);
|
||||
}
|
||||
|
||||
@ -1063,8 +1059,7 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
|
||||
ASLayout *result = [self calculateLayoutThatFits:resolvedRange];
|
||||
as_log_verbose(ASLayoutLog(), "Calculated layout %@", result);
|
||||
|
||||
if (isRootCall) {
|
||||
pthread_setspecific(key, NULL);
|
||||
if (--tls_callDepth == 0) {
|
||||
ASSignpostEnd(ASSignpostCalculateLayout);
|
||||
}
|
||||
return result;
|
||||
|
||||
@ -11,29 +11,18 @@
|
||||
//
|
||||
|
||||
#import <AsyncDisplayKit/ASAssert.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
static pthread_key_t ASMainThreadAssertionsDisabledKey()
|
||||
{
|
||||
return ASPthreadStaticKey(NULL);
|
||||
}
|
||||
static _Thread_local int tls_mainThreadAssertionsDisabledCount;
|
||||
|
||||
BOOL ASMainThreadAssertionsAreDisabled() {
|
||||
return (size_t)pthread_getspecific(ASMainThreadAssertionsDisabledKey()) > 0;
|
||||
return tls_mainThreadAssertionsDisabledCount > 0;
|
||||
}
|
||||
|
||||
void ASPushMainThreadAssertionsDisabled() {
|
||||
pthread_key_t key = ASMainThreadAssertionsDisabledKey();
|
||||
size_t oldValue = (size_t)pthread_getspecific(key);
|
||||
pthread_setspecific(key, (void *)(oldValue + 1));
|
||||
tls_mainThreadAssertionsDisabledCount += 1;
|
||||
}
|
||||
|
||||
void ASPopMainThreadAssertionsDisabled() {
|
||||
pthread_key_t key = ASMainThreadAssertionsDisabledKey();
|
||||
size_t oldValue = (size_t)pthread_getspecific(key);
|
||||
if (oldValue > 0) {
|
||||
pthread_setspecific(key, (void *)(oldValue - 1));
|
||||
} else {
|
||||
ASDisplayNodeCFailAssert(@"Attempt to pop thread assertion-disabling without corresponding push.");
|
||||
}
|
||||
tls_mainThreadAssertionsDisabledCount -= 1;
|
||||
ASDisplayNodeCAssert(tls_mainThreadAssertionsDisabledCount >= 0, @"Attempt to pop thread assertion-disabling without corresponding push.");
|
||||
}
|
||||
|
||||
@ -211,15 +211,6 @@
|
||||
#define AS_SUBCLASSING_RESTRICTED
|
||||
#endif
|
||||
|
||||
#define ASPthreadStaticKey(dtor) ({ \
|
||||
static dispatch_once_t onceToken; \
|
||||
static pthread_key_t key; \
|
||||
dispatch_once(&onceToken, ^{ \
|
||||
pthread_key_create(&key, dtor); \
|
||||
}); \
|
||||
key; \
|
||||
})
|
||||
|
||||
#define ASCreateOnce(expr) ({ \
|
||||
static dispatch_once_t onceToken; \
|
||||
static __typeof__(expr) staticVar; \
|
||||
|
||||
@ -50,38 +50,27 @@ CGSize const ASLayoutElementParentSizeUndefined = {ASLayoutElementParentDimensio
|
||||
int32_t const ASLayoutElementContextInvalidTransitionID = 0;
|
||||
int32_t const ASLayoutElementContextDefaultTransitionID = ASLayoutElementContextInvalidTransitionID + 1;
|
||||
|
||||
static void ASLayoutElementDestructor(void *p) {
|
||||
if (p != NULL) {
|
||||
ASDisplayNodeCFailAssert(@"Thread exited without clearing layout element context!");
|
||||
CFBridgingRelease(p);
|
||||
}
|
||||
};
|
||||
|
||||
pthread_key_t ASLayoutElementContextKey()
|
||||
{
|
||||
return ASPthreadStaticKey(ASLayoutElementDestructor);
|
||||
}
|
||||
static _Thread_local __unsafe_unretained ASLayoutElementContext *tls_context;
|
||||
|
||||
void ASLayoutElementPushContext(ASLayoutElementContext *context)
|
||||
{
|
||||
// NOTE: It would be easy to support nested contexts – just use an NSMutableArray here.
|
||||
ASDisplayNodeCAssertNil(ASLayoutElementGetCurrentContext(), @"Nested ASLayoutElementContexts aren't supported.");
|
||||
pthread_setspecific(ASLayoutElementContextKey(), CFBridgingRetain(context));
|
||||
ASDisplayNodeCAssertNil(tls_context, @"Nested ASLayoutElementContexts aren't supported.");
|
||||
|
||||
tls_context = (__bridge ASLayoutElementContext *)(__bridge_retained CFTypeRef)context;
|
||||
}
|
||||
|
||||
ASLayoutElementContext *ASLayoutElementGetCurrentContext()
|
||||
{
|
||||
// Don't retain here. Caller will retain if it wants to!
|
||||
return (__bridge __unsafe_unretained ASLayoutElementContext *)pthread_getspecific(ASLayoutElementContextKey());
|
||||
return tls_context;
|
||||
}
|
||||
|
||||
void ASLayoutElementPopContext()
|
||||
{
|
||||
ASLayoutElementContextKey();
|
||||
ASDisplayNodeCAssertNotNil(ASLayoutElementGetCurrentContext(), @"Attempt to pop context when there wasn't a context!");
|
||||
auto key = ASLayoutElementContextKey();
|
||||
CFBridgingRelease(pthread_getspecific(key));
|
||||
pthread_setspecific(key, NULL);
|
||||
ASDisplayNodeCAssertNotNil(tls_context, @"Attempt to pop context when there wasn't a context!");
|
||||
CFRelease((__bridge CFTypeRef)tls_context);
|
||||
tls_context = nil;
|
||||
}
|
||||
|
||||
#pragma mark - ASLayoutElementStyle
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user