Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix 32-bit simulator build on Xcode >= 9.3 #1025

Merged
merged 1 commit into from
Jul 13, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
- Properly consider node for responder methods [Michael Schneider](https://github.com/maicki)
- [IGListKit] Adds missing UIScrollViewDelegate method to DataSource proxy [Sergey Pronin](https://github.com/wannabehero)
- Fix misleading/scary stack trace shown when an assertion occurs during node measurement [Huy Nguyen](https://github.com/nguyenhuy) [#1022](https://github.com/TextureGroup/Texture/pull/1022)
- Fix build on 32-bit simulator in Xcode 9.3 and later, caused by `Thread-local storage is not supported on this architecture.` [Adlai Holler](https://github.com/Adlai-Holler)

## 2.7
- Fix pager node for interface coalescing. [Max Wang](https://github.com/wsdwsd0829) [#877](https://github.com/TextureGroup/Texture/pull/877)
Expand Down
11 changes: 9 additions & 2 deletions Source/ASDisplayNode.mm
Original file line number Diff line number Diff line change
Expand Up @@ -1076,22 +1076,29 @@ - (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize
restrictedToSize:(ASLayoutElementSize)size
relativeToParentSize:(CGSize)parentSize
{
// We only want one calculateLayout signpost interval per thread.
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 AS_KDEBUG_ENABLE
// We only want one calculateLayout signpost interval per thread.
// Currently there is no fallback for profiling i386, since it's not useful.
static _Thread_local NSInteger tls_callDepth;
if (tls_callDepth++ == 0) {
ASSignpostStart(ASSignpostCalculateLayout);
}
#endif

ASSizeRange styleAndParentSize = ASLayoutElementSizeResolve(self.style.size, parentSize);
const ASSizeRange resolvedRange = ASSizeRangeIntersect(constrainedSize, styleAndParentSize);
ASLayout *result = [self calculateLayoutThatFits:resolvedRange];
as_log_verbose(ASLayoutLog(), "Calculated layout %@", result);

#if AS_KDEBUG_ENABLE
if (--tls_callDepth == 0) {
ASSignpostEnd(ASSignpostCalculateLayout);
}
#endif

return result;
}

Expand Down
36 changes: 35 additions & 1 deletion Source/Base/ASAssert.m
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@
//

#import <AsyncDisplayKit/ASAssert.h>
#import <AsyncDisplayKit/ASAvailability.h>

static _Thread_local int tls_mainThreadAssertionsDisabledCount;
#if AS_TLS_AVAILABLE

static _Thread_local int tls_mainThreadAssertionsDisabledCount;
BOOL ASMainThreadAssertionsAreDisabled() {
return tls_mainThreadAssertionsDisabledCount > 0;
}
Expand All @@ -26,3 +28,35 @@ void ASPopMainThreadAssertionsDisabled() {
tls_mainThreadAssertionsDisabledCount -= 1;
ASDisplayNodeCAssert(tls_mainThreadAssertionsDisabledCount >= 0, @"Attempt to pop thread assertion-disabling without corresponding push.");
}

#else

#import <dispatch/once.h>

static pthread_key_t ASMainThreadAssertionsDisabledKey() {
static pthread_key_t k;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
pthread_key_create(&k, NULL);
});
return k;
}

BOOL ASMainThreadAssertionsAreDisabled() {
return (pthread_getspecific(ASMainThreadAssertionsDisabledKey()) > 0);
}

void ASPushMainThreadAssertionsDisabled() {
let key = ASMainThreadAssertionsDisabledKey();
let oldVal = pthread_getspecific(key);
pthread_setspecific(key, oldVal + 1);
}

void ASPopMainThreadAssertionsDisabled() {
let key = ASMainThreadAssertionsDisabledKey();
let oldVal = pthread_getspecific(key);
pthread_setspecific(key, oldVal - 1);
ASDisplayNodeCAssert(oldVal > 0, @"Attempt to pop thread assertion-disabling without corresponding push.");
}

#endif // AS_TLS_AVAILABLE
6 changes: 6 additions & 0 deletions Source/Base/ASAvailability.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@

#pragma once

#ifdef __i386__
#define AS_TLS_AVAILABLE 0
#else
#define AS_TLS_AVAILABLE 1
#endif

#ifndef kCFCoreFoundationVersionNumber_iOS_10_0
#define kCFCoreFoundationVersionNumber_iOS_10_0 1348.00
#endif
Expand Down
38 changes: 38 additions & 0 deletions Source/Layout/ASLayoutElement.mm
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ - (instancetype)init
int32_t const ASLayoutElementContextInvalidTransitionID = 0;
int32_t const ASLayoutElementContextDefaultTransitionID = ASLayoutElementContextInvalidTransitionID + 1;

#if AS_TLS_AVAILABLE

static _Thread_local __unsafe_unretained ASLayoutElementContext *tls_context;

void ASLayoutElementPushContext(ASLayoutElementContext *context)
Expand All @@ -73,6 +75,42 @@ void ASLayoutElementPopContext()
tls_context = nil;
}

#else

static pthread_key_t ASLayoutElementContextKey() {
static pthread_key_t k;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
pthread_key_create(&k, NULL);
});
return k;
}
void ASLayoutElementPushContext(ASLayoutElementContext *context)
{
// NOTE: It would be easy to support nested contexts – just use an NSMutableArray here.
ASDisplayNodeCAssertNil(pthread_getspecific(ASLayoutElementContextKey()), @"Nested ASLayoutElementContexts aren't supported.");

let cfCtx = (__bridge_retained CFTypeRef)context;
pthread_setspecific(ASLayoutElementContextKey(), cfCtx);
}

ASLayoutElementContext *ASLayoutElementGetCurrentContext()
{
// Don't retain here. Caller will retain if it wants to!
let ctxPtr = pthread_getspecific(ASLayoutElementContextKey());
return (__bridge ASLayoutElementContext *)ctxPtr;
}

void ASLayoutElementPopContext()
{
let ctx = (CFTypeRef)pthread_getspecific(ASLayoutElementContextKey());
ASDisplayNodeCAssertNotNil(ctx, @"Attempt to pop context when there wasn't a context!");
CFRelease(ctx);
pthread_setspecific(ASLayoutElementContextKey(), NULL);
}

#endif // AS_TLS_AVAILABLE

#pragma mark - ASLayoutElementStyle

NSString * const ASLayoutElementStyleWidthProperty = @"ASLayoutElementStyleWidthProperty";
Expand Down