Commit bf9fb0da authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 7e1f6104
...@@ -627,13 +627,29 @@ pair<FileH, error> _Conn::open(zodb::Oid foid) { ...@@ -627,13 +627,29 @@ pair<FileH, error> _Conn::open(zodb::Oid foid) {
return make_pair(nil, E(err)); return make_pair(nil, E(err));
} }
retry:
FileH f; bool ok; FileH f; bool ok;
tie(f, ok) = wconn._filehTab.get_(foid); tie(f, ok) = wconn._filehTab.get_(foid);
if (ok) { if (ok) {
bool closing;
if (f->_state <= _FileHOpened) {
f->_nopen++; // XXX lock by f.mu ? f->_nopen++; // XXX lock by f.mu ?
closing = false;
} else {
closing = true;
}
wconn._mu.Unlock(); wconn._mu.Unlock();
// wait for: "opening" -> opened // if the file was closing|closed, we should wait for the close to
// complete and retry the open.
if (closing) {
f->_closedq.recv();
goto retry;
}
// the file was opening|opened. wait for it to be opened and return the result.
// we can be sure there won't be last Close simultaneous to us as we did ._nopen++
f->_openReady.recv(); f->_openReady.recv();
if (f->_openErr != nil) { if (f->_openErr != nil) {
// don't care about f->_nopen-- since f is not returned anywhere // don't care about f->_nopen-- since f is not returned anywhere
...@@ -649,10 +665,12 @@ pair<FileH, error> _Conn::open(zodb::Oid foid) { ...@@ -649,10 +665,12 @@ pair<FileH, error> _Conn::open(zodb::Oid foid) {
f->wconn = newref(&wconn); f->wconn = newref(&wconn);
f->foid = foid; f->foid = foid;
f->_openReady = makechan<structZ>(); f->_openReady = makechan<structZ>();
f->_closedq = makechan<structZ>();
f->_openErr = nil; f->_openErr = nil;
f->_headf = nil; f->_headf = nil;
f->blksize = 0; f->blksize = 0;
f->_headfsize = 0; f->_headfsize = 0;
f->_state = _FileHOpening;
f->_nopen = 1; f->_nopen = 1;
f->_closed = false; f->_closed = false;
......
...@@ -233,6 +233,7 @@ struct _FileH : object { ...@@ -233,6 +233,7 @@ struct _FileH : object {
chan<structZ> _openReady; // in-flight open completed chan<structZ> _openReady; // in-flight open completed
error _openErr; // error result from open error _openErr; // error result from open
chan<structZ> _closedq; // in-flight close completed
os::File _headf; // file object of head/file os::File _headf; // file object of head/file
size_t blksize; // block size of this file (does not change after fileh open) size_t blksize; // block size of this file (does not change after fileh open)
......
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