worker: avoid potential deadlock on NearHeapLimit
It can happen that the NearHeapLimit
callback is called while calling
the oninit()
function on MessagePort
construction causing a deadlock
when the Worker::Exit()
method is called, as the mutex_
was already
held on the CreateEnvMessagePort()
method. To fix it, just use the
mutex_
to protect the child_port_data_
variable and avoid holding it
when creating the MessagePort
.
Also, return early from Worker::Run()
if the worker message port
could not be created.
Fixes: https://github.com/nodejs/node/issues/38208.
A couple of things I'd like to point out:
- I've only been able to reproduce the issue from the original report in the
v12.x
branch, but I think that potentially it could happen on newer branches too. - I've implemented this solution on the assumption that the mutex is only needed to protect
child_port_data_
based on this comment, if that's not the case, it won't work. Another option I've tried that also works was using a recursive mutex, but I don't know if that solution would be acceptable.