diff --git a/src/lime/app/Future.hx b/src/lime/app/Future.hx index cc8520a9b..991b0d119 100644 --- a/src/lime/app/Future.hx +++ b/src/lime/app/Future.hx @@ -353,6 +353,8 @@ import lime.utils.Log; private static var singleThreadPool:ThreadPool; #if lime_threads private static var multiThreadPool:ThreadPool; + // It isn't safe to pass a promise object to a web worker. + private static var promises:Map<{}, Promise> = new Map(); #end public static var minThreads(default, set):Int = 0; public static var maxThreads(default, set):Int = 1; @@ -381,7 +383,21 @@ import lime.utils.Log; @:allow(lime.app.Future) private static function queue(work:WorkFunctionNull>, state:State, promise:Promise, mode:ThreadMode = MULTI_THREADED):Void { - getPool(mode).queue({work: work, state: state, promise: promise}); + var bundle = {work: work, state: state, promise: promise}; + + #if lime_threads + if (mode == MULTI_THREADED) + { + #if html5 + work.makePortable(); + #end + + promises[bundle] = promise; + bundle.promise = null; + } + #end + + getPool(mode).queue(bundle); } // Event Handlers @@ -414,12 +430,16 @@ import lime.utils.Log; #if lime_threads private static function multiThreadPool_onComplete(result:Dynamic):Void { - multiThreadPool.eventData.state.promise.complete(result); + var promise:Promise = promises[multiThreadPool.eventData.state]; + promises.remove(multiThreadPool.eventData.state); + promise.complete(result); } private static function multiThreadPool_onError(error:Dynamic):Void { - multiThreadPool.eventData.state.promise.error(error); + var promise:Promise = promises[multiThreadPool.eventData.state]; + promises.remove(multiThreadPool.eventData.state); + promise.error(error); } #end diff --git a/src/lime/system/ThreadPool.hx b/src/lime/system/ThreadPool.hx index 0dae21b51..326be7af4 100644 --- a/src/lime/system/ThreadPool.hx +++ b/src/lime/system/ThreadPool.hx @@ -499,12 +499,9 @@ class ThreadPool extends WorkOutput onProgress.dispatch(threadEvent.state); case COMPLETE, ERROR: - // Remember that the listener could queue a new job. if (threadEvent.event == COMPLETE) { onComplete.dispatch(threadEvent.state); - - completed = activeJobs == 0 && __jobQueue.isEmpty(); } else { @@ -529,6 +526,8 @@ class ThreadPool extends WorkOutput } #end + completed = threadEvent.event == COMPLETE && activeJobs == 0 && __jobQueue.isEmpty(); + default: }