Commit e32e463b authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 167b42ee
...@@ -126,37 +126,42 @@ error _Conn::close() { ...@@ -126,37 +126,42 @@ error _Conn::close() {
xerr::Contextf E("%s: close", v(wconn)); xerr::Contextf E("%s: close", v(wconn));
// xerr::Contextf E("wcfs %s: close %s", v(wconn._wc->mountpoint), v(wconn.at));
// XXX + conn # e.g. from wconn._wlink.id? or wlink.close should include its id itself?
// (or ._wlink._f.fd() ?)
error err, eret; error err, eret;
auto reterr1 = [&eret](error err) { auto reterr1 = [&eret](error err) {
if (eret == nil && err != nil) if (eret == nil && err != nil)
eret = err; eret = err;
}; };
bool alreadyClosed = false;
wconn._mu.lock(); wconn._mu.lock();
defer([&]() { alreadyClosed = (wconn._downErr == errConnClosed);
wconn._mu.unlock(); wconn._downErr = errConnClosed;
}); wconn._mu.unlock();
if (alreadyClosed)
wconn._downErr = errConnClosed; // XXX ok to change even if it was !nil before? return nil;
err = wconn._wlink->close(); // XXX ok under mu? // close wlink and signal to pinner to stop outside of wconn.mu
err = wconn._wlink->close(); // XXX ok under atMu?
if (err != nil) if (err != nil)
reterr1(err); reterr1(err);
wconn._pinCancel(); wconn._pinCancel();
err = wconn._pinWG->wait(); // XXX ok under mu? err = wconn._pinWG->wait(); // XXX ok under atMu?
if (!errors::Is(err, context::canceled)) // canceled - ok if (!errors::Is(err, context::canceled)) // canceled - ok
reterr1(err); reterr1(err);
// close all files - both that have no mappings and that still have opened mappings.
// pinner is stopped - now close all files - both that have no mappings and
// that still have opened mappings.
// //
// NOTE after file is closed mappings could continue to survive, but we can no // NOTE after file is closed mappings could continue to survive, but we can no
// longer maintain consistent view. For this reason we change mappings to // longer maintain consistent view. For this reason we change mappings to
// something that gives EFAULT on access. XXX implement // something that gives EFAULT on access. XXX implement
wconn._mu.lock();
defer([&]() {
wconn._mu.unlock();
});
// XXX f locking
for (auto _ : wconn._filehTab) { for (auto _ : wconn._filehTab) {
auto f = _.second; auto f = _.second;
err = f->_headf->close(); // XXX mark fileh as down so that fileh.close does not say "bad fd" err = f->_headf->close(); // XXX mark fileh as down so that fileh.close does not say "bad fd"
...@@ -211,7 +216,7 @@ error _Conn::__pinner(context::Context ctx) { ...@@ -211,7 +216,7 @@ error _Conn::__pinner(context::Context ctx) {
if (err != nil) { if (err != nil) {
// it is ok if we receive EOF due to us closing the connection // it is ok if we receive EOF due to us closing the connection
if (err == io::EOF_) { if (err == io::EOF_) {
wconn._mu.lock(); wconn._mu.lock(); // <- XXX
err = (wconn._downErr == errConnClosed) ? nil : io::ErrUnexpectedEOF; err = (wconn._downErr == errConnClosed) ? nil : io::ErrUnexpectedEOF;
wconn._mu.unlock(); wconn._mu.unlock();
} }
......
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