watcher icon indicating copy to clipboard operation
watcher copied to clipboard

Deadlock between Watcher and Debounce threads (fix #187)

Open bpasero opened this issue 1 year ago • 2 comments

fix https://github.com/parcel-bundler/watcher/issues/187

There are two threads involved in Watcher.cc and Debounce.cc each calling into respective methods of the other and thus each potentially holding onto locks of the other. This can lead to a deadlock in the following scenario:

While the Debounce.cc thread is processing callbacks in the Debounce::notify() method, it holds its own lock. The method loops over callbacks to process in Watcher.cc which itself requires a lock in Watcher.cc. If an event gets reported while the debouncer is in Watcher.triggerCallbacks(), a deadlock is present, because:

  • assume the event thread is thread A
  • assume the debouncer thread is thread B
  • A holds its own lock in Watcher::notify() and calls into Debounce.trigger() which requires the debouncer lock
  • B at this time is inside Debounce::notify() holding its own lock processing callbacks and about to call into Watcher.triggerCallbacks()
  • A deadlocks waiting for B to release the debouncer lock
  • B deadlocks waiting for A to release the watcher lock

bpasero avatar Sep 07 '24 05:09 bpasero

Thanks for the deep investigation here! This looks good to me.

devongovett avatar Sep 15 '24 15:09 devongovett

Could this be merged and published soon, please? We're desperately waiting for a fix :)

jmeinke avatar Oct 10 '24 11:10 jmeinke

@devongovett 👋 yeah, would be great to see a new version with the fix included

bpasero avatar Oct 26 '24 06:10 bpasero