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

Improve dispatch queue idling resource handling #806

Merged
merged 3 commits into from
Jul 2, 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
62 changes: 0 additions & 62 deletions detox/ios/Detox.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,6 @@
objectVersion = 46;
objects = {

/* Begin PBXAggregateTarget section */
3941F4F21DC6200700F23DAC /* DetoxFramework */ = {
isa = PBXAggregateTarget;
buildConfigurationList = 3941F4F31DC6200700F23DAC /* Build configuration list for PBXAggregateTarget "DetoxFramework" */;
buildPhases = (
3941F4F61DC6203000F23DAC /* ShellScript */,
);
dependencies = (
);
name = DetoxFramework;
productName = DetoxFramework;
};
/* End PBXAggregateTarget section */

/* Begin PBXBuildFile section */
390D1C691E3A14EF007F5F46 /* UNNotificationResponse+PrivateHeaders.h in Headers */ = {isa = PBXBuildFile; fileRef = 390D1C671E3A14EF007F5F46 /* UNNotificationResponse+PrivateHeaders.h */; settings = {ATTRIBUTES = (Private, ); }; };
390D1C9C1E3A45F1007F5F46 /* UNNotification+PrivateHeaders.h in Headers */ = {isa = PBXBuildFile; fileRef = 390D1C9A1E3A45F1007F5F46 /* UNNotification+PrivateHeaders.h */; };
Expand Down Expand Up @@ -242,7 +228,6 @@
39A34C701E30F10D00BEBB59 /* DetoxAppDelegateProxy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DetoxAppDelegateProxy.m; sourceTree = "<group>"; };
39AB2D30205ABBD90029CD1F /* DetoxUserActivityDispatcher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DetoxUserActivityDispatcher.swift; sourceTree = "<group>"; };
39CEFCDA1E34E91B00A09124 /* DetoxUserNotificationDispatcher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DetoxUserNotificationDispatcher.swift; sourceTree = "<group>"; };
39D91D2E202B4128008DD636 /* test */ = {isa = PBXFileReference; lastKnownFileType = folder; name = test; path = ../test; sourceTree = "<group>"; };
39F642201FDD5EB000468FED /* DTXLogging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DTXLogging.h; path = DTXLoggingInfra/DTXLogging.h; sourceTree = SOURCE_ROOT; };
39F642271FDD5EB000468FED /* DTXLogging.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DTXLogging.m; path = DTXLoggingInfra/DTXLogging.m; sourceTree = SOURCE_ROOT; };
39F6422A1FDD5EEC00468FED /* Detox.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Detox.pch; sourceTree = "<group>"; };
Expand Down Expand Up @@ -326,7 +311,6 @@
39408DEE1FE6368100C20BD5 /* JS */ = {
isa = PBXGroup;
children = (
39D91D2E202B4128008DD636 /* test */,
3975C78220272ED500C59ED8 /* src */,
);
name = JS;
Expand Down Expand Up @@ -545,10 +529,6 @@
LastSwiftMigration = 0900;
ProvisioningStyle = Automatic;
};
3941F4F21DC6200700F23DAC = {
CreatedOnToolsVersion = 8.1;
ProvisioningStyle = Automatic;
};
394767961DBF985400D72256 = {
CreatedOnToolsVersion = 8.1;
LastSwiftMigration = 0900;
Expand Down Expand Up @@ -583,7 +563,6 @@
projectRoot = "";
targets = (
394767961DBF985400D72256 /* Detox */,
3941F4F21DC6200700F23DAC /* DetoxFramework */,
3928EFA41E47404900C19B6E /* DetoxUserNotificationTests */,
);
};
Expand Down Expand Up @@ -669,22 +648,6 @@
};
/* End PBXResourcesBuildPhase section */

/* Begin PBXShellScriptBuildPhase section */
3941F4F61DC6203000F23DAC /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/bash;
shellScript = "set -e\n\nfunction remove_arch() {\n lipo -create \"${1}\" \"${2}\" -output \"${3}\"\n}\n\nUNIVERSAL_OUTPUTFOLDER=${BUILD_DIR}/${CONFIGURATION}-universal\n\n# Make sure the output directory exists\n\nmkdir -p \"${UNIVERSAL_OUTPUTFOLDER}\"\n\n# Step 1. Build Device and Simulator versions\n\nxcodebuild -target \"${PROJECT_NAME}\" ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -arch arm64 -sdk iphoneos BUILD_DIR=\"${BUILD_DIR}\" BUILD_ROOT=\"${BUILD_ROOT}\" clean build VALID_ARCHS=arm64\nxcodebuild -target \"${PROJECT_NAME}\" -configuration ${CONFIGURATION} -arch x86_64 -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO BUILD_DIR=\"${BUILD_DIR}\" BUILD_ROOT=\"${BUILD_ROOT}\" clean build VALID_ARCHS=x86_64\n\n# Step 2. Copy the framework structure (from iphoneos build) to the universal folder\n\ncp -R \"${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework\" \"${UNIVERSAL_OUTPUTFOLDER}/\"\n\n# Step 3. Copy Swift modules from iphonesimulator build (if it exists) to the copied framework directory\nSIMULATOR_SWIFT_MODULES_DIR=\"${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule/.\"\nif [ -d \"${SIMULATOR_SWIFT_MODULES_DIR}\" ]; then\ncp -R \"${SIMULATOR_SWIFT_MODULES_DIR}\" \"${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule\"\nfi\n\n# Step 4. Create universal binary file using lipo and place the combined executable in the copied framework directory\n\nremove_arch \"${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/${PROJECT_NAME}\" \"${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework/${PROJECT_NAME}\" \"${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/${PROJECT_NAME}\"\n\n# Step 5. Create universal binaries for embedded frameworks\n\nfor SUB_FRAMEWORK in $( ls \"${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/Frameworks\" ); do\nif [ -d \"${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/Frameworks/$SUB_FRAMEWORK\" ]; then\necho \"Processing ${SUB_FRAMEWORK} as a dir\"\nBINARY_NAME=\"${SUB_FRAMEWORK%.*}\"\n\nremove_arch \"${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Frameworks/${SUB_FRAMEWORK}/${BINARY_NAME}\" \"${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework/Frameworks/${SUB_FRAMEWORK}/${BINARY_NAME}\" \"${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/Frameworks/${SUB_FRAMEWORK}/${BINARY_NAME}\"\n\nelse\necho \"Processing ${SUB_FRAMEWORK} as a file\"\n\nremove_arch \"${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Frameworks/${SUB_FRAMEWORK}\" \"${BUILD_DIR}/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework/Frameworks/${SUB_FRAMEWORK}\" \"${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/Frameworks/${SUB_FRAMEWORK}\"\n\nfi\ndone";
};
/* End PBXShellScriptBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
3928EFA11E47404900C19B6E /* Sources */ = {
isa = PBXSourcesBuildPhase;
Expand Down Expand Up @@ -780,22 +743,6 @@
};
name = Release;
};
3941F4F41DC6200700F23DAC /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 390D1C981E3A2893007F5F46 /* Detox.xcconfig */;
buildSettings = {
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
3941F4F51DC6200700F23DAC /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 390D1C981E3A2893007F5F46 /* Detox.xcconfig */;
buildSettings = {
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
3947679D1DBF985400D72256 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 390D1C981E3A2893007F5F46 /* Detox.xcconfig */;
Expand Down Expand Up @@ -986,15 +933,6 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
3941F4F31DC6200700F23DAC /* Build configuration list for PBXAggregateTarget "DetoxFramework" */ = {
isa = XCConfigurationList;
buildConfigurations = (
3941F4F41DC6200700F23DAC /* Debug */,
3941F4F51DC6200700F23DAC /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
394767911DBF985400D72256 /* Build configuration list for PBXProject "Detox" */ = {
isa = XCConfigurationList;
buildConfigurations = (
Expand Down

This file was deleted.

36 changes: 25 additions & 11 deletions detox/ios/Detox/ReactNativeSupport.m
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ void swz_addToRunLoop(id self, SEL _cmd, NSRunLoop* runloop)
}

static NSMutableArray* __observedQueues;
static NSMutableArray* __currentDispatchQueueIdlingResources;

static dispatch_queue_t (*wx_original_dispatch_queue_create)(const char *_Nullable label, dispatch_queue_attr_t _Nullable attr);

Expand Down Expand Up @@ -126,6 +127,7 @@ void setupForTests()
}

__observedQueues = [NSMutableArray new];
__currentDispatchQueueIdlingResources = [NSMutableArray new];

//Add an idling resource for each module queue.
Method m = class_getInstanceMethod(cls, NSSelectorFromString(@"setUpMethodQueue"));
Expand All @@ -135,17 +137,20 @@ void setupForTests()

dispatch_queue_t queue = object_getIvar(_self, class_getInstanceVariable(cls, "_methodQueue"));

if(queue != nil && [queue isKindOfClass:[NSNull class]] == NO && queue != dispatch_get_main_queue() && [__observedQueues containsObject:queue] == NO)
{
NSString* queueName = [[NSString alloc] initWithUTF8String:dispatch_queue_get_label(queue) ?: ""];

[__observedQueues addObject:queue];

dtx_log_info(@"Adding idling resource for queue: %@", queue);


[[GREYUIThreadExecutor sharedInstance] registerIdlingResource:[GREYDispatchQueueIdlingResource resourceWithDispatchQueue:queue name:queueName ?: @"SomeReactQueue"]];
}
dispatch_sync(__currentIdlingResourceSerialQueue, ^{
if(queue != nil && [queue isKindOfClass:[NSNull class]] == NO && queue != dispatch_get_main_queue() && [__observedQueues containsObject:queue] == NO)
{
NSString* queueName = [[NSString alloc] initWithUTF8String:dispatch_queue_get_label(queue) ?: ""];

[__observedQueues addObject:queue];

dtx_log_info(@"Adding idling resource for queue: %@", queue);

GREYDispatchQueueIdlingResource* ir = [GREYDispatchQueueIdlingResource resourceWithDispatchQueue:queue name:queueName ?: @"SomeReactQueue"];
[__currentDispatchQueueIdlingResources addObject:ir];
[[GREYUIThreadExecutor sharedInstance] registerIdlingResource:ir];
}
});
}));

//Cannot just extern this function - we are not linked with RN, so linker will fail. Instead, look for symbol in runtime.
Expand Down Expand Up @@ -183,6 +188,15 @@ + (void)reloadApp
return;
}

dispatch_sync(__currentIdlingResourceSerialQueue, ^{
[__currentDispatchQueueIdlingResources enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
[[GREYUIThreadExecutor sharedInstance] deregisterIdlingResource:obj];
}];

[__currentDispatchQueueIdlingResources removeAllObjects];
[__observedQueues removeAllObjects];
});

id<RN_RCTBridge> bridge = [NSClassFromString(@"RCTBridge") valueForKey:@"currentBridge"];

SEL reqRelSel = NSSelectorFromString(@"requestReload");
Expand Down
4 changes: 2 additions & 2 deletions detox/scripts/build_framework.ios.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/bash -e
#!/bin/bash -e -x

detoxRootPath="$(dirname $(dirname ${0}))"
detoxVersion=`node -p "require('${detoxRootPath}/package.json').version"`
Expand Down Expand Up @@ -32,7 +32,7 @@ function buildFramework () {
detoxSourcePath="${1}"
echo "Building Detox.framework from ${detoxSourcePath}..."
mkdir -p "${detoxFrameworkDirPath}"
xcodebuild build -project "${detoxSourcePath}"/Detox.xcodeproj -scheme DetoxFramework -configuration Release -derivedDataPath "${detoxFrameworkDirPath}"/DetoxBuild BUILD_DIR="${detoxFrameworkDirPath}"/DetoxBuild/Build/Products &> "${detoxFrameworkDirPath}"/detox_ios.log
"${detoxRootPath}"/scripts/build_universal_framework.sh "${detoxSourcePath}"/Detox.xcodeproj "${detoxFrameworkDirPath}"/DetoxBuild &> "${detoxFrameworkDirPath}"/detox_ios.log
mv "${detoxFrameworkDirPath}"/DetoxBuild/Build/Products/Release-universal/Detox.framework "${detoxFrameworkDirPath}"
rm -fr "${detoxFrameworkDirPath}"/DetoxBuild
}
Expand Down
52 changes: 52 additions & 0 deletions detox/scripts/build_universal_framework.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
PROJECT=$1
DERIVED_DATA=$2
CONFIGURATION=Release
PROJECT_NAME=Detox

set -e

function remove_arch() {
lipo -create "${1}" "${2}" -output "${3}"
}

UNIVERSAL_OUTPUTFOLDER=${DERIVED_DATA}/Build/Products/${CONFIGURATION}-universal

# Make sure the output directory exists

mkdir -p "${UNIVERSAL_OUTPUTFOLDER}"

# Step 1. Build Device and Simulator versions

xcodebuild -project "${PROJECT}" -scheme Detox ONLY_ACTIVE_ARCH=NO -configuration ${CONFIGURATION} -arch arm64 -sdk iphoneos clean build VALID_ARCHS=arm64 -derivedDataPath "${DERIVED_DATA}"
xcodebuild -project "${PROJECT}" -scheme Detox -configuration ${CONFIGURATION} -arch x86_64 -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO clean build VALID_ARCHS=x86_64 -derivedDataPath "${DERIVED_DATA}"

# Step 2. Copy the framework structure (from iphoneos build) to the universal folder

cp -R "${DERIVED_DATA}/Build/Products/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework" "${UNIVERSAL_OUTPUTFOLDER}/"

# Step 3. Copy Swift modules from iphonesimulator build (if it exists) to the copied framework directory
SIMULATOR_SWIFT_MODULES_DIR="${DERIVED_DATA}/Build/Products/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule/."
if [ -d "${SIMULATOR_SWIFT_MODULES_DIR}" ]; then
cp -R "${SIMULATOR_SWIFT_MODULES_DIR}" "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/Modules/${PROJECT_NAME}.swiftmodule"
fi

# Step 4. Create universal binary file using lipo and place the combined executable in the copied framework directory

remove_arch "${DERIVED_DATA}/Build/Products/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${DERIVED_DATA}/Build/Products/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework/${PROJECT_NAME}" "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/${PROJECT_NAME}"

# Step 5. Create universal binaries for embedded frameworks

for SUB_FRAMEWORK in $( ls "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/Frameworks" ); do
if [ -d "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/Frameworks/$SUB_FRAMEWORK" ]; then
echo "Processing ${SUB_FRAMEWORK} as a dir"
BINARY_NAME="${SUB_FRAMEWORK%.*}"

remove_arch "${DERIVED_DATA}/Build/Products/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Frameworks/${SUB_FRAMEWORK}/${BINARY_NAME}" "${DERIVED_DATA}/Build/Products/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework/Frameworks/${SUB_FRAMEWORK}/${BINARY_NAME}" "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/Frameworks/${SUB_FRAMEWORK}/${BINARY_NAME}"

else
echo "Processing ${SUB_FRAMEWORK} as a file"

remove_arch "${DERIVED_DATA}/Build/Products/${CONFIGURATION}-iphonesimulator/${PROJECT_NAME}.framework/Frameworks/${SUB_FRAMEWORK}" "${DERIVED_DATA}/Build/Products/${CONFIGURATION}-iphoneos/${PROJECT_NAME}.framework/Frameworks/${SUB_FRAMEWORK}" "${UNIVERSAL_OUTPUTFOLDER}/${PROJECT_NAME}.framework/Frameworks/${SUB_FRAMEWORK}"

fi
done