-
Committer:
Tarmac
-
Author(s):
Christopher James Halse Rogers
-
Date:
2017-07-27 08:46:31 UTC
-
mfrom:
(4213.1.3 trunk)
-
Revision ID:
tarmac-20170727084631-gj232utp7xw3igxw
mcl::BufferVault: Fix lock inversion.
~BufferVault takes BufferVault::mutex and then calls AtomicCallback::set_callback() on each buffer,
which takes AtomicCallback::mutex.
The RPC subsystem calls buffer->callback(), which takes AtomicCallback::mutex and then calls
BufferVault::wire_transfer_inbound... which immediately takes BufferVault::mutex.
This is clearly a disaster waiting to happen.
Instead, move to a two-phase destruction approach:
1) Lock BufferVault::mutex, set a flag telling callbacks to bail, and collect all the existing
buffers.
2) Drop the lock, and use buffer->set_callback() to wait on any thread already in a callback.
3) Don't bother telling the server to release any buffers; they're associated with the
BufferStream that we're in the process of destroying, and will get cleaned up there.
Approved by mir-ci-bot, Alan Griffiths.