diff options
Diffstat (limited to 'netfs/fuse/fuseFiles.cpp')
-rw-r--r-- | netfs/fuse/fuseFiles.cpp | 48 |
1 files changed, 25 insertions, 23 deletions
diff --git a/netfs/fuse/fuseFiles.cpp b/netfs/fuse/fuseFiles.cpp index ed0e881..b587809 100644 --- a/netfs/fuse/fuseFiles.cpp +++ b/netfs/fuse/fuseFiles.cpp @@ -2,6 +2,7 @@ #include "fuseApp.impl.h" #include "lockHelpers.h" #include <entCache.h> +#include <mutex> namespace NetFS { FuseApp::OpenFile::OpenFile(FilePrx r, const std::string & p, int f) : @@ -130,31 +131,32 @@ FuseApp::write(const char *, const char * buf, size_t s, off_t o, struct fuse_fi if (fcr->Async) { const auto key = OpenFile::range(o, s); while (true) { - ScopeLock(of->_lock) { - // Acquire operations to wait for - std::vector<Ice::AsyncResultPtr> overlap; - auto R = of->bg.equal_range(key); - if (R.first == R.second) { - // Begin write and store operation - auto r = remote->begin_write(o, s, Buffer(buf, buf + s), [of,key](const Ice::AsyncResultPtr &) { - ScopeLock(of->_lock) { - of->bg.erase(key); - } - }); - of->bg.insert({key, r}); - return s; - } - else { - // Wait for them whilst unlocked - of->_lock.unlock(); - overlap.reserve(std::distance(R.first, R.second)); - for (auto i = R.first; i != R.second; i++) { - overlap.push_back(i->second); - } - for (const auto & r : overlap) { - r->waitForCompleted(); + std::unique_lock<decltype(of->_lock)> _l(of->_lock); + // Acquire operations to wait for + std::vector<Ice::AsyncResultPtr> overlap; + auto R = of->bg.equal_range(key); + if (R.first == R.second) { + // Begin write and store operation + auto r = remote->begin_write(o, s, Buffer(buf, buf + s), [of,key](const Ice::AsyncResultPtr &) { + ScopeLock(of->_lock) { + of->bg.erase(key); } + }); + of->bg.insert({key, r}); + break; + } + else { + // Wait for them whilst unlocked + _l.release()->unlock(); + overlap.reserve(std::distance(R.first, R.second)); + for (auto i = R.first; i != R.second; i++) { + overlap.push_back(i->second); + } + for (const auto & r : overlap) { + r->waitForCompleted(); } + // Cause this thread to yield so the callback can acquire _lock + usleep(0); } } } |