Commit c3e1d21f authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent be061f93
......@@ -301,20 +301,32 @@ error _Conn::close() {
// mappings to give EFAULT on access.
while (1) {
FileH f = nil;
bool opening, closing;
// pick up any fileh
wconn._filehMu.Lock();
if (!wconn._filehTab.empty())
if (!wconn._filehTab.empty()) {
f = wconn._filehTab.begin()->second;
opening = (f->_state < _FileHOpened);
closing = (f->_state >= _FileHClosing);
if (!closing)
f->_nopen++; // the file is not closing - we'll close it ourselves.
}
wconn._filehMu.Unlock();
if (f == nil)
break; // all closed
// XXX vvv only for !opening state
// if fileh was "opening" - wait for the open to complete before calling close.
if (opening) {
f->_openReady.recv();
if (f->_openErr != nil)
continue; // failed open; f should be removed from wconn._filehTab by Conn.open itself
}
// close f under
// - XXX virt_lock
// if fileh was not "closing" - close it ourselves (we pretended we opened it too).
// call close f under
// - virt_lock
// - wconn.atMu.R
// - wconn.filehMu unlocked
err = f->_closeLocked();
......@@ -322,7 +334,8 @@ error _Conn::close() {
reterr1(err);
// wait for f close to complete, as it might be that f.close was called
// simultaneously to wconn.close
// simultaneously to us or just before. f is removed from
// wconn.filehTab only after close completes.
f->_closedq.recv();
}
......@@ -760,6 +773,7 @@ retry:
bool retok = false;
wconn._filehTab[foid] = f;
wconn._filehMu.Unlock();
defer([&]() {
wconn._filehMu.Lock();
if (wconn._filehTab.get(foid) != f) {
......@@ -775,7 +789,6 @@ retry:
wconn._filehMu.Unlock();
f->_openReady.close();
});
wconn._filehMu.Unlock();
// do the actuall open.
// we hold only wconn.atMu.R, but niether wconn.filehMu, nor f.mu .
......
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