NativeScript / ios-jsc

NativeScript for iOS using JavaScriptCore

Home Page:http://docs.nativescript.org/runtimes/ios

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

calling setTimeout in worker will crash the app on worker.close

patricklx opened this issue · comments

Environment
Provide version numbers for the following components (information can be retrieved by running tns info in your project folder or by inspecting the package.json of the project):

  • CLI: 5.3.1
  • Cross-platform modules: 5.3.1
  • iOS Runtime: 5.3.1
  • Android Runtime (if applicable):
  • Plugin(s):

Describe the bug
the app will crash when trying to close the worker when a setTimeout was called.
note that it works if clearTimeout was called before close();

require('globals');
const id = setTimeout(()=> console.log('timer'); 5000);
close();

will crash the app on worker close();

To Reproduce
create a worker thread with the above snippet and close it later.

Expected behavior

  1. should close without crash
  2. should clear up all timers on close? or add functionality to timers to clear all manually

Sample project

Additional context
i propose to use NSTimer like this:

timers = {};
timersMap = new Map();
 function wrapper(timer) {
   const fn = timers.timers.get(timer);
   timersMap.delete(timer);
   fn();
 }
 timers.setTimeout = function(fn, ms) {
   const t = NSTimer.scheduledTimerWithTimeIntervalRepeatsBlock(ms / 1000.0, false, wrapper);
   timersMap.set(t, fn);
   return t;
 };

 timers.clearTimeout = function(timer) {
   timer.invalidate();
   timersMap.delete(timer);
 };

 timers.setInterval = function(fn, ms) {
   const t = NSTimer.scheduledTimerWithTimeIntervalRepeatsBlock(ms / 1000.0, true, wrapper);
   timersMap.set(t, fn);
   return t;
 };

 timers.clearInterval = function(timer) {
   timer.invalidate();
   timersMap.delete(timer);
 };

 timers.clearAll = function() {
   timersMap.forEach((fn, t => t.invalidate());
   timersMap.clear();
 };

 timers.setImmediate = fn => global.setTimeout(fn, 0);
 timers.clearImmediate = fn => global.clearTimeout(fn, 0); 

also, i get a better stack trace:

Crashed: NativeScript: Worker
0  NativeScript                   0x10142b6d0 JSC::JSLock::lock(long) + 32
1  NativeScript                   0x10142b4fc JSC::JSLockHolder::JSLockHolder(JSC::VM*) + 52
2  NativeScript                   0x10142b4fc JSC::JSLockHolder::JSLockHolder(JSC::VM*) + 52
3  NativeScript                   0x101326c08 NativeScript::JSBlock::disposeBlock(NativeScript::JSBlock*) + 64
4  libsystem_blocks.dylib         0x183ceca5c _Block_release + 152
5  Foundation                     0x184da6c0c -[_NSTimerBlockTarget dealloc] + 36
6  Foundation                     0x184ce3de4 _timerRelease + 88
7  CoreFoundation                 0x1842250b8 CFRunLoopTimerInvalidate + 680
8  CoreFoundation                 0x184304040 __CFRunLoopTimerDeallocate + 32
9  CoreFoundation                 0x184304c3c _CFRelease + 216
10 CoreFoundation                 0x1842b7660 __CFArrayReleaseValues + 540
11 CoreFoundation                 0x1842212bc CFArrayRemoveAllValues + 212
12 CoreFoundation                 0x184220144 __CFSetApplyFunction_block_invoke + 24
13 CoreFoundation                 0x18421ff98 CFBasicHashApply + 132
14 CoreFoundation                 0x18421ff00 CFSetApplyFunction + 288
15 CoreFoundation                 0x184301eec __CFRunLoopDeallocate + 260
16 CoreFoundation                 0x184304c3c _CFRelease + 216
17 CoreFoundation                 0x1842f3828 __CFTSDFinalize + 120
18 libsystem_pthread.dylib        0x183f8057c _pthread_tsd_cleanup + 572
19 libsystem_pthread.dylib        0x183f802cc _pthread_exit + 88
20 libsystem_pthread.dylib        0x183f8122c _pthread_body + 284
21 libsystem_pthread.dylib        0x183f81110 _pthread_body + 290
22 libsystem_pthread.dylib        0x183f7fb10 thread_start + 4

Fixed with #1213