Commit 8337bde5 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 1afd27a6
...@@ -385,22 +385,29 @@ error _Conn::__pin1(PinReq *req) { ...@@ -385,22 +385,29 @@ error _Conn::__pin1(PinReq *req) {
wconn._atMu.RUnlock(); wconn._atMu.RUnlock();
}); });
// lock wconn.filehMu.R to lookup fileh in wconn.filehTab.
// keep wconn.filehMu.R during whole __pin1 to make sure that e.g.
// simultaneous close does not remove f from wconn.filehTab.
// TODO keeping filehMu.R during whole pin is not needed and locking can be made more granular.
//
// NOTE no deadlock wrt Conn.resync, Conn.open, FileH.close - they all send // NOTE no deadlock wrt Conn.resync, Conn.open, FileH.close - they all send
// "watch" outside of wconn.filehMu. // "watch" outside of wconn.filehMu.
wconn._filehMu.RLock(); wconn._filehMu.RLock();
// XXX +incref f, so that simultaneous close does not remove f from wconn.filehTab ? defer([&]() {
// XXX or just make FileH.close lock f too to synchronize with pinner? wconn._filehMu.RUnlock();
// XXX or just keep wconn._filehMu.R during whole __pin1() });
tie(f, ok) = wconn._filehTab.get_(req->foid); tie(f, ok) = wconn._filehTab.get_(req->foid);
if (!ok) { if (!ok) {
wconn._filehMu.RUnlock();
// why wcfs sent us this update? // why wcfs sent us this update?
return fmt::errorf("unexpected pin: f<%s> not watched", v(req->foid)); return fmt::errorf("unexpected pin: f<%s> not watched", v(req->foid));
} }
// XXX <- f._openReady ? // NOTE no need to check f._state as we need to go only through f.mmaps, and
// wcfs server can send us pins at any state, including "opening" - to pin
// our view to requested @at, and "closing" - due to other clients
// accessing wcfs/head/f simultaneously.
wconn._filehMu.RUnlock(); // XXX maybe `f.mu.lock() -> wconn.filehMu.unlock()` to avoid race with FileH close?
f->_mu.lock(); f->_mu.lock();
defer([&]() { defer([&]() {
f->_mu.unlock(); f->_mu.unlock();
...@@ -447,7 +454,7 @@ error _Conn::__pin1(PinReq *req) { ...@@ -447,7 +454,7 @@ error _Conn::__pin1(PinReq *req) {
if (err != nil) if (err != nil)
return err; return err;
//trace("\t-> remmaped"); XXX //trace("\t-> remmaped");
} }
// update f._pinned // update f._pinned
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment