diff --git a/lib/init.lua b/lib/init.lua index 4287997..03675b1 100644 --- a/lib/init.lua +++ b/lib/init.lua @@ -233,6 +233,9 @@ function Promise._new(traceback, callback, parent) end local self = { + -- The executor thread. + _thread = nil, + -- Used to locate where a promise was created _source = traceback, @@ -292,13 +295,15 @@ function Promise._new(traceback, callback, parent) return self._status == Promise.Status.Cancelled end - coroutine.wrap(function() + self._thread = coroutine.create(function() local ok, _, result = runExecutor(self._source, callback, resolve, reject, onCancel) if not ok then reject(result[1]) end - end)() + end) + + task.spawn(self._thread) return self end @@ -1385,6 +1390,8 @@ function Promise.prototype:cancel() self._cancellationHook() end + coroutine.close(self._thread) + if self._parent then self._parent:_consumerCancelled(self) end @@ -1847,6 +1854,8 @@ function Promise.prototype:_finalize() self._parent = nil self._consumers = nil end + + task.defer(coroutine.close, self._thread) end --[=[ diff --git a/lib/init.spec.lua b/lib/init.spec.lua index 047f281..a6599a0 100644 --- a/lib/init.spec.lua +++ b/lib/init.spec.lua @@ -218,6 +218,20 @@ return function() expect(called).to.equal(true) end) + + itSKIP("should close the thread after resolve", function() + local count = 0 + Promise.new(function(resolve) + count += 1 + resolve() + Promise.delay(1):await() + count += 1 + end) + + task.wait(1) + + expect(count).to.equal(1) + end) end) describe("Promise.defer", function() @@ -627,6 +641,20 @@ return function() expect(p1._status).to.equal(Promise.Status.Cancelled) expect(p2._status).to.equal(Promise.Status.Cancelled) end) + + it("should close the promise thread", function() + local count = 0 + local promise = Promise.new(function() + count += 1 + Promise.delay(1):await() + count += 1 + end) + + promise:cancel() + advanceTime(2) + + expect(count).to.equal(1) + end) end) describe("Promise:finally", function()