mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-10 16:29:55 +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/)
|
- 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)
|
- 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/)
|
- 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
|
## 2.6
|
||||||
- [Xcode 9] Updated to require Xcode 9 (to fix warnings) [Garrett Moon](https://github.com/garrettmoon)
|
- [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
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
//
|
//
|
||||||
|
|
||||||
#import <pthread.h>
|
|
||||||
|
|
||||||
#import <AsyncDisplayKit/ASBlockTypes.h>
|
#import <AsyncDisplayKit/ASBlockTypes.h>
|
||||||
#import <AsyncDisplayKit/ASDisplayNode.h>
|
#import <AsyncDisplayKit/ASDisplayNode.h>
|
||||||
|
|
||||||
|
|||||||
@ -1046,15 +1046,11 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
|
|||||||
restrictedToSize:(ASLayoutElementSize)size
|
restrictedToSize:(ASLayoutElementSize)size
|
||||||
relativeToParentSize:(CGSize)parentSize
|
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.
|
// We only want one calculateLayout signpost interval per thread.
|
||||||
// This is fast enough to do it unconditionally.
|
static _Thread_local NSInteger tls_callDepth;
|
||||||
auto key = ASPthreadStaticKey(NULL);
|
|
||||||
BOOL isRootCall = (pthread_getspecific(key) == NULL);
|
|
||||||
as_activity_scope_verbose(as_activity_create("Calculate node layout", AS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT));
|
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));
|
as_log_verbose(ASLayoutLog(), "Calculating layout for %@ sizeRange %@", self, NSStringFromASSizeRange(constrainedSize));
|
||||||
if (isRootCall) {
|
if (tls_callDepth++ == 0) {
|
||||||
pthread_setspecific(key, kCFBooleanTrue);
|
|
||||||
ASSignpostStart(ASSignpostCalculateLayout);
|
ASSignpostStart(ASSignpostCalculateLayout);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1063,8 +1059,7 @@ static ASDisplayNodeMethodOverrides GetASDisplayNodeMethodOverrides(Class c)
|
|||||||
ASLayout *result = [self calculateLayoutThatFits:resolvedRange];
|
ASLayout *result = [self calculateLayoutThatFits:resolvedRange];
|
||||||
as_log_verbose(ASLayoutLog(), "Calculated layout %@", result);
|
as_log_verbose(ASLayoutLog(), "Calculated layout %@", result);
|
||||||
|
|
||||||
if (isRootCall) {
|
if (--tls_callDepth == 0) {
|
||||||
pthread_setspecific(key, NULL);
|
|
||||||
ASSignpostEnd(ASSignpostCalculateLayout);
|
ASSignpostEnd(ASSignpostCalculateLayout);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@ -11,29 +11,18 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#import <AsyncDisplayKit/ASAssert.h>
|
#import <AsyncDisplayKit/ASAssert.h>
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
|
|
||||||
static pthread_key_t ASMainThreadAssertionsDisabledKey()
|
static _Thread_local int tls_mainThreadAssertionsDisabledCount;
|
||||||
{
|
|
||||||
return ASPthreadStaticKey(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL ASMainThreadAssertionsAreDisabled() {
|
BOOL ASMainThreadAssertionsAreDisabled() {
|
||||||
return (size_t)pthread_getspecific(ASMainThreadAssertionsDisabledKey()) > 0;
|
return tls_mainThreadAssertionsDisabledCount > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ASPushMainThreadAssertionsDisabled() {
|
void ASPushMainThreadAssertionsDisabled() {
|
||||||
pthread_key_t key = ASMainThreadAssertionsDisabledKey();
|
tls_mainThreadAssertionsDisabledCount += 1;
|
||||||
size_t oldValue = (size_t)pthread_getspecific(key);
|
|
||||||
pthread_setspecific(key, (void *)(oldValue + 1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ASPopMainThreadAssertionsDisabled() {
|
void ASPopMainThreadAssertionsDisabled() {
|
||||||
pthread_key_t key = ASMainThreadAssertionsDisabledKey();
|
tls_mainThreadAssertionsDisabledCount -= 1;
|
||||||
size_t oldValue = (size_t)pthread_getspecific(key);
|
ASDisplayNodeCAssert(tls_mainThreadAssertionsDisabledCount >= 0, @"Attempt to pop thread assertion-disabling without corresponding push.");
|
||||||
if (oldValue > 0) {
|
|
||||||
pthread_setspecific(key, (void *)(oldValue - 1));
|
|
||||||
} else {
|
|
||||||
ASDisplayNodeCFailAssert(@"Attempt to pop thread assertion-disabling without corresponding push.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -211,15 +211,6 @@
|
|||||||
#define AS_SUBCLASSING_RESTRICTED
|
#define AS_SUBCLASSING_RESTRICTED
|
||||||
#endif
|
#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) ({ \
|
#define ASCreateOnce(expr) ({ \
|
||||||
static dispatch_once_t onceToken; \
|
static dispatch_once_t onceToken; \
|
||||||
static __typeof__(expr) staticVar; \
|
static __typeof__(expr) staticVar; \
|
||||||
|
|||||||
@ -50,38 +50,27 @@ CGSize const ASLayoutElementParentSizeUndefined = {ASLayoutElementParentDimensio
|
|||||||
int32_t const ASLayoutElementContextInvalidTransitionID = 0;
|
int32_t const ASLayoutElementContextInvalidTransitionID = 0;
|
||||||
int32_t const ASLayoutElementContextDefaultTransitionID = ASLayoutElementContextInvalidTransitionID + 1;
|
int32_t const ASLayoutElementContextDefaultTransitionID = ASLayoutElementContextInvalidTransitionID + 1;
|
||||||
|
|
||||||
static void ASLayoutElementDestructor(void *p) {
|
static _Thread_local __unsafe_unretained ASLayoutElementContext *tls_context;
|
||||||
if (p != NULL) {
|
|
||||||
ASDisplayNodeCFailAssert(@"Thread exited without clearing layout element context!");
|
|
||||||
CFBridgingRelease(p);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
pthread_key_t ASLayoutElementContextKey()
|
|
||||||
{
|
|
||||||
return ASPthreadStaticKey(ASLayoutElementDestructor);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ASLayoutElementPushContext(ASLayoutElementContext *context)
|
void ASLayoutElementPushContext(ASLayoutElementContext *context)
|
||||||
{
|
{
|
||||||
// NOTE: It would be easy to support nested contexts – just use an NSMutableArray here.
|
// NOTE: It would be easy to support nested contexts – just use an NSMutableArray here.
|
||||||
ASDisplayNodeCAssertNil(ASLayoutElementGetCurrentContext(), @"Nested ASLayoutElementContexts aren't supported.");
|
ASDisplayNodeCAssertNil(tls_context, @"Nested ASLayoutElementContexts aren't supported.");
|
||||||
pthread_setspecific(ASLayoutElementContextKey(), CFBridgingRetain(context));
|
|
||||||
|
tls_context = (__bridge ASLayoutElementContext *)(__bridge_retained CFTypeRef)context;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASLayoutElementContext *ASLayoutElementGetCurrentContext()
|
ASLayoutElementContext *ASLayoutElementGetCurrentContext()
|
||||||
{
|
{
|
||||||
// Don't retain here. Caller will retain if it wants to!
|
// Don't retain here. Caller will retain if it wants to!
|
||||||
return (__bridge __unsafe_unretained ASLayoutElementContext *)pthread_getspecific(ASLayoutElementContextKey());
|
return tls_context;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ASLayoutElementPopContext()
|
void ASLayoutElementPopContext()
|
||||||
{
|
{
|
||||||
ASLayoutElementContextKey();
|
ASDisplayNodeCAssertNotNil(tls_context, @"Attempt to pop context when there wasn't a context!");
|
||||||
ASDisplayNodeCAssertNotNil(ASLayoutElementGetCurrentContext(), @"Attempt to pop context when there wasn't a context!");
|
CFRelease((__bridge CFTypeRef)tls_context);
|
||||||
auto key = ASLayoutElementContextKey();
|
tls_context = nil;
|
||||||
CFBridgingRelease(pthread_getspecific(key));
|
|
||||||
pthread_setspecific(key, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - ASLayoutElementStyle
|
#pragma mark - ASLayoutElementStyle
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user