From 01e5b70e5c35522a839269ba4ebd88955c809bd1 Mon Sep 17 00:00:00 2001 From: Yavor Georgiev Date: Fri, 18 Sep 2015 14:50:27 +0300 Subject: [PATCH] Schedule the runtime on the runloop of its owner thread --- build/project-template/__PROJECT_NAME__/main.m | 2 ++ cmake/main.m | 2 ++ examples/BlankApp/main.m | 2 ++ src/NativeScript/GlobalObject.h | 8 ++++++++ src/NativeScript/GlobalObject.mm | 7 ++++++- src/NativeScript/TNSRuntime.h | 4 ++++ src/NativeScript/TNSRuntime.mm | 8 ++++++++ tests/TestRunner/app/Promises.js | 5 +++++ tests/TestRunner/app/bootstrap.js | 2 ++ 9 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 tests/TestRunner/app/Promises.js diff --git a/build/project-template/__PROJECT_NAME__/main.m b/build/project-template/__PROJECT_NAME__/main.m index fed39c5ba..41281c68c 100644 --- a/build/project-template/__PROJECT_NAME__/main.m +++ b/build/project-template/__PROJECT_NAME__/main.m @@ -38,6 +38,8 @@ int main(int argc, char *argv[]) { #endif [TNSRuntime initializeMetadata:&startOfMetadataSection]; runtime = [[TNSRuntime alloc] initWithApplicationPath:applicationPath]; + [runtime scheduleInRunLoop:[NSRunLoop currentRunLoop] + forMode:NSRunLoopCommonModes]; #ifndef NDEBUG [TNSRuntimeInspector setLogsToSystemConsole:YES]; diff --git a/cmake/main.m b/cmake/main.m index 71f002d05..71b01d687 100644 --- a/cmake/main.m +++ b/cmake/main.m @@ -12,6 +12,8 @@ int main(int argc, char *argv[]) { [TNSRuntime initializeMetadata:&startOfMetadataSection]; runtime = [[TNSRuntime alloc] initWithApplicationPath:[NSBundle mainBundle].bundlePath]; + [runtime scheduleInRunLoop:[NSRunLoop currentRunLoop] + forMode:NSRunLoopCommonModes]; TNSRuntimeInspector.logsToSystemConsole = YES; #ifndef NDEBUG diff --git a/examples/BlankApp/main.m b/examples/BlankApp/main.m index a4162bca6..3eb15b7f1 100644 --- a/examples/BlankApp/main.m +++ b/examples/BlankApp/main.m @@ -18,6 +18,8 @@ int main(int argc, char *argv[]) { [TNSRuntime initializeMetadata:&startOfMetadataSection]; TNSRuntime *runtime = [[TNSRuntime alloc] initWithApplicationPath:[NSBundle mainBundle].bundlePath]; + [runtime scheduleInRunLoop:[NSRunLoop currentRunLoop] + forMode:NSRunLoopCommonModes]; TNSRuntimeInspector.logsToSystemConsole = YES; NSError *error = nil; diff --git a/src/NativeScript/GlobalObject.h b/src/NativeScript/GlobalObject.h index a2c9e9934..0fbc5cef8 100644 --- a/src/NativeScript/GlobalObject.h +++ b/src/NativeScript/GlobalObject.h @@ -124,6 +124,11 @@ class GlobalObject : public JSC::JSGlobalObject { return this->_fastEnumerationIteratorStructure.get(); } + void setMicrotaskRunLoopAndMode(CFRunLoopRef runLoop, CFTypeRef mode) { + this->_microtaskRunLoop = runLoop; + this->_microtaskRunLoopMode = mode; + } + #if defined(__LP64__) && __LP64__ JSC::WeakGCMap& taggedPointers() { return this->_taggedPointers; @@ -145,6 +150,9 @@ class GlobalObject : public JSC::JSGlobalObject { WTF::String _applicationPath; + WTF::RetainPtr _microtaskRunLoop; + WTF::RetainPtr _microtaskRunLoopMode; + JSC::WriteBarrier _objCMethodCallStructure; JSC::WriteBarrier _objCConstructorCallStructure; JSC::WriteBarrier _objCBlockCallStructure; diff --git a/src/NativeScript/GlobalObject.mm b/src/NativeScript/GlobalObject.mm index aa8b0e14c..4d623cf54 100644 --- a/src/NativeScript/GlobalObject.mm +++ b/src/NativeScript/GlobalObject.mm @@ -374,9 +374,14 @@ static EncodedJSValue JSC_HOST_CALL collectGarbage(ExecState* execState) { } void GlobalObject::queueTaskToEventLoop(const JSGlobalObject* globalObject, WTF::PassRefPtr task) { - CFRunLoopPerformBlock(CFRunLoopGetCurrent(), kCFRunLoopCommonModes, ^{ + auto global = jsCast(globalObject); + CFRunLoopRef runLoop = global->_microtaskRunLoop.get() ?: CFRunLoopGetCurrent(); + CFTypeRef mode = global->_microtaskRunLoopMode.get() ?: kCFRunLoopCommonModes; + + CFRunLoopPerformBlock(runLoop, mode, ^{ JSLockHolder lock(globalObject->vm()); task->run(const_cast(globalObject)->globalExec()); }); + CFRunLoopWakeUp(runLoop); } } diff --git a/src/NativeScript/TNSRuntime.h b/src/NativeScript/TNSRuntime.h index 38db8176a..f1aacc1b5 100644 --- a/src/NativeScript/TNSRuntime.h +++ b/src/NativeScript/TNSRuntime.h @@ -21,6 +21,10 @@ FOUNDATION_EXTERN void TNSSetUncaughtErrorHandler(TNSUncaughtErrorHandler handle - (instancetype)initWithApplicationPath:(NSString*)applicationPath; +- (void)scheduleInRunLoop:(NSRunLoop*)runLoop forMode:(NSString*)mode; + +- (void)removeFromRunLoop:(NSRunLoop*)runLoop forMode:(NSString*)mode; + - (JSGlobalContextRef)globalContext; - (void)executeModule:(NSString*)entryPointModuleIdentifier; diff --git a/src/NativeScript/TNSRuntime.mm b/src/NativeScript/TNSRuntime.mm index b42f188e1..90e49b235 100644 --- a/src/NativeScript/TNSRuntime.mm +++ b/src/NativeScript/TNSRuntime.mm @@ -63,6 +63,14 @@ - (instancetype)initWithApplicationPath:(NSString*)applicationPath { return self; } +- (void)scheduleInRunLoop:(NSRunLoop*)runLoop forMode:(NSString*)mode { + self->_globalObject->setMicrotaskRunLoopAndMode([runLoop getCFRunLoop], mode); +} + +- (void)removeFromRunLoop:(NSRunLoop*)runLoop forMode:(NSString*)mode { + self->_globalObject->setMicrotaskRunLoopAndMode(nullptr, nullptr); +} + - (JSGlobalContextRef)globalContext { return toGlobalRef(self->_globalObject->globalExec()); } diff --git a/tests/TestRunner/app/Promises.js b/tests/TestRunner/app/Promises.js new file mode 100644 index 000000000..9f090a1fd --- /dev/null +++ b/tests/TestRunner/app/Promises.js @@ -0,0 +1,5 @@ +describe("Promise scheduling", function () { + it("should be executed", function(done) { + Promise.resolve().then(done); + }); +}); \ No newline at end of file diff --git a/tests/TestRunner/app/bootstrap.js b/tests/TestRunner/app/bootstrap.js index 246183c4e..17f20a21c 100644 --- a/tests/TestRunner/app/bootstrap.js +++ b/tests/TestRunner/app/bootstrap.js @@ -57,6 +57,8 @@ require('./shared'); require('./ApiTests'); require('./DeclarationConflicts'); +require('./Promises'); + execute(); UIApplicationMain(0, null, null, null);