Closed ivstiv closed 1 year ago
Hi @ivstiv!
What you describe is expected behaviour. Cancelling the mutex will reject all promises that have been acquired by waiters, but will (and cannot) cancel locks that already have been acquired. So, what happens in your example:
execute
(first timeslice): runExclusive
calls acquire
, which locks the mutex and returns a resolved promiseexecute
(still in the same timeslice): all waiters are cancelled (but none are actually cancelled, as acquire
already locked the mutex and resolved the promise). The call to release()
will force the mutex to become available again, but it cannot cancel the already acquired lock either. runExclusive
calls acquire, which locks the mutex again and returns a resolved promiserunExclusive
continue execution and await the timeoutconsole.log
is executed twice.The important parts are:
acquire
returns a promise, the lock actually happens in the same timeslice if the mutex is available when acquire
is called.release
just forces the mutex to become available again, it cannot cancel resolved promises that were returned by acquire
. This is why release
should only be called as the consequence of a previously acquired lock.
It looks like when I cancel a mutex it doesn't throw the E_CANCELLED error and the runExclusive callback finishes. Here is the code to reproduce it:
Output:
Expected output:
Note 1: I am calling the release() because of this behaviour: