mirror of
https://github.com/trapexit/mergerfs.git
synced 2026-10-26 19:01:56 -04:00
Use atomic open file reference counts
- Use relaxed increment under the map bucket lock when duplicating file handles. - Use acq_rel decrement when releasing and checking for final references. - Load moved ref_count with relaxed ordering during map insertion.
This commit is contained in:
parent
b13727abde
commit
608cd00764
3 changed files with 27 additions and 4 deletions
|
|
@ -81,11 +81,21 @@ FUSE::release(cu64 nodeid_,
|
|||
FileInfo *canonical_fi = nullptr;
|
||||
FileInfo *fh_fi_to_free = nullptr;
|
||||
|
||||
// memory_order_acq_rel on the decrement gives us the canonical
|
||||
// refcount-publication pattern:
|
||||
// - release: prior writes to the OpenFile by this thread are
|
||||
// visible to whichever thread observes the final 0.
|
||||
// - acquire: the thread that drops the last ref acquires every
|
||||
// prior ref holder's writes before tearing down the entry.
|
||||
// The concurrent_flat_map bucket lock already serializes concurrent
|
||||
// visitors of this key so the acq_rel is good for any observer that
|
||||
// might examine ref_count outside a visit().
|
||||
of.erase_if(nodeid_,
|
||||
[&](auto &v_)
|
||||
{
|
||||
v_.second.ref_count--;
|
||||
if(v_.second.ref_count > 0)
|
||||
const int prev =
|
||||
v_.second.ref_count.fetch_sub(1,std::memory_order_acq_rel);
|
||||
if(prev > 1)
|
||||
{
|
||||
if(fi_ != v_.second.fi)
|
||||
fh_fi_to_free = fi_;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue