From b45c5aaf56f4c0046b7ac97edd379539b4bd1706 Mon Sep 17 00:00:00 2001 From: Kirill Smelkov <kirr@nexedi.com> Date: Fri, 21 Feb 2020 19:50:54 +0300 Subject: [PATCH] . --- wcfs/client/wcfs.cpp | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/wcfs/client/wcfs.cpp b/wcfs/client/wcfs.cpp index 06f9e4d8..17c4786c 100644 --- a/wcfs/client/wcfs.cpp +++ b/wcfs/client/wcfs.cpp @@ -514,7 +514,7 @@ error _Conn::resync(zodb::Tid at) { // TODO if file has no mappings and was not used during whole prev // cycle - forget and stop watching it - // XXX not yet ready f ? + // XXX not yet ready f // update f._headfsize and remmap to head/f zero regions that are now covered by head/f struct stat st; @@ -618,7 +618,7 @@ pair<FileH, error> _Conn::open(zodb::Oid foid) { } // create in-flight-opening FileH entry and perform open with wconn._mu released - // NOTE wconn._atMu is still held because open relies on wconn.at being stable. + // NOTE wconn._atMu.R is still held because FileH._open relies on wconn.at being stable. f = adoptref(new _FileH()); f->wconn = newref(&wconn); f->foid = foid; @@ -688,9 +688,8 @@ error _FileH::_open() { tie(ack, err) = wconn->_wlink->sendReq(context::background(), fmt::sprintf("watch %s @%s", v(foid), v(wconn->at))); if (err != nil) return err; - if (ack != "ok") { + if (ack != "ok") return fmt::errorf("watch: %s", v(ack)); - } retok = true; return nil; @@ -702,10 +701,25 @@ error _FileH::_open() { error _FileH::close() { _FileH& fileh = *this; Conn wconn = fileh.wconn; + + // XXX locking ok? + wconn->_atMu.RLock(); + defer([&]() { + wconn->_atMu.RUnlock(); + }); + xerr::Contextf E("%s: close f<%s>", v(wconn), v(fileh.foid)); // XXX change all fileh.mmaps to cause EFAULT on any access after fileh.close - // XXX "watch foid -" -> wconn.wlink (stop watching the file) + + // stop watching f + string ack; + error err; + tie(ack, err) = wconn->_wlink->sendReq(context::background(), fmt::sprintf("watch %s -", v(foid))); + if (err != nil) + return E(err); + if (ack != "ok") + return E(fmt::errorf("unwatch: %s", v(ack))); // remove fileh from wconn._filehTab // fileh.close can be called several times and after first call another -- 2.30.9