summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2017-10-25 19:20:18 +0100
committerDan Goodliffe <dan@randomdan.homeip.net>2017-12-16 20:51:55 +0000
commit8a7e04ffd3e582854f92989540a8aad6d052b7ff (patch)
treeb851222114147e9613cd8b7816b4aa2c74e657bb
parentImplement background (file) writes (diff)
downloadnetfs-8a7e04ffd3e582854f92989540a8aad6d052b7ff.tar.bz2
netfs-8a7e04ffd3e582854f92989540a8aad6d052b7ff.tar.xz
netfs-8a7e04ffd3e582854f92989540a8aad6d052b7ff.zip
Add optimistic checking and pruning of background write results if it can be done without waiting for the lock
-rw-r--r--netfs/fuse/fuseApp.h2
-rw-r--r--netfs/fuse/fuseFiles.cpp25
2 files changed, 26 insertions, 1 deletions
diff --git a/netfs/fuse/fuseApp.h b/netfs/fuse/fuseApp.h
index c37ba6d..2169e85 100644
--- a/netfs/fuse/fuseApp.h
+++ b/netfs/fuse/fuseApp.h
@@ -33,12 +33,14 @@ namespace NetFS {
OpenFile(FilePrx remote, const std::string & path, int flags);
void flush();
+ void nonBlockingFlush();
void wait() const;
FilePrx remote;
const std::string path;
const int flags;
std::list<Ice::AsyncResultPtr> bg;
+ mutable boost::shared_mutex _lock;
};
typedef IceUtil::Handle<OpenFile> OpenFilePtr;
typedef std::map<int, OpenFilePtr> OpenFiles;
diff --git a/netfs/fuse/fuseFiles.cpp b/netfs/fuse/fuseFiles.cpp
index e31b4db..e81dd45 100644
--- a/netfs/fuse/fuseFiles.cpp
+++ b/netfs/fuse/fuseFiles.cpp
@@ -39,6 +39,7 @@ NetFS::FuseApp::clearFileProxy(uint64_t localID)
void
NetFS::FuseApp::OpenFile::wait() const
{
+ SharedLock(_lock);
for (const auto & w : bg) {
w->waitForCompleted();
}
@@ -47,6 +48,7 @@ NetFS::FuseApp::OpenFile::wait() const
void
NetFS::FuseApp::OpenFile::flush()
{
+ Lock(_lock);
while (!bg.empty()) {
auto w = bg.front();
bg.pop_front();
@@ -55,6 +57,24 @@ NetFS::FuseApp::OpenFile::flush()
}
}
+void
+NetFS::FuseApp::OpenFile::nonBlockingFlush()
+{
+ boost::unique_lock<boost::shared_mutex> lock(_lock, boost::try_to_lock);
+ if (lock.owns_lock()) {
+ for (auto wi = bg.begin(); wi != bg.end(); ) {
+ auto w = *wi;
+ if (w->isCompleted()) {
+ wi = bg.erase(wi);
+ w->throwLocalException();
+ }
+ else {
+ wi++;
+ }
+ }
+ }
+}
+
int
NetFS::FuseApp::open(const char * p, struct fuse_file_info * fi)
{
@@ -138,7 +158,10 @@ NetFS::FuseApp::write(const char *, const char * buf, size_t s, off_t o, struct
auto remote = of->remote;
auto r = remote->begin_write(o, s, NetFS::Buffer(buf, buf + s));
if (fcr->Async) {
- of->bg.push_back(r);
+ ScopeLock(of->_lock) {
+ of->bg.push_back(r);
+ }
+ of->nonBlockingFlush();
}
else {
r->throwLocalException();