Merge "Stops the loop when all files are closed." am: d8d7fc6717 am: 920b02906f am: ac982d2644
am: 6d0e37cf1b

Change-Id: I699e905344bec05c3375afb03c47021a4b1b139d
diff --git a/libappfuse/FuseBridgeLoop.cc b/libappfuse/FuseBridgeLoop.cc
index acb963c..beee4a6 100644
--- a/libappfuse/FuseBridgeLoop.cc
+++ b/libappfuse/FuseBridgeLoop.cc
@@ -26,6 +26,7 @@
   base::unique_fd dev_fd(raw_dev_fd);
   base::unique_fd proxy_fd(raw_proxy_fd);
   fuse::FuseBuffer buffer;
+  size_t open_count = 0;
 
   LOG(DEBUG) << "Start fuse loop.";
   while (true) {
@@ -71,8 +72,26 @@
       return false;
     }
 
-    if (opcode == FUSE_INIT) {
-      callback->OnMount();
+    switch (opcode) {
+      case FUSE_INIT:
+        callback->OnMount();
+        break;
+      case FUSE_OPEN:
+        if (buffer.response.header.error == fuse::kFuseSuccess) {
+          open_count++;
+        }
+        break;
+      case FUSE_RELEASE:
+        if (open_count != 0) {
+            open_count--;
+        } else {
+            LOG(WARNING) << "Unexpected FUSE_RELEASE before opening a file.";
+            break;
+        }
+        if (open_count == 0) {
+          return true;
+        }
+        break;
     }
   }
 }
diff --git a/libappfuse/tests/FuseBridgeLoopTest.cc b/libappfuse/tests/FuseBridgeLoopTest.cc
index bd503eb..e74d9e7 100644
--- a/libappfuse/tests/FuseBridgeLoopTest.cc
+++ b/libappfuse/tests/FuseBridgeLoopTest.cc
@@ -200,11 +200,16 @@
 TEST_F(FuseBridgeLoopTest, Proxy) {
   CheckProxy(FUSE_LOOKUP);
   CheckProxy(FUSE_GETATTR);
-  CheckProxy(FUSE_OPEN);
   CheckProxy(FUSE_READ);
   CheckProxy(FUSE_WRITE);
-  CheckProxy(FUSE_RELEASE);
   CheckProxy(FUSE_FSYNC);
+
+  // Invoke FUSE_OPEN and FUSE_RELEASE at last as the loop will exit when all files are closed.
+  CheckProxy(FUSE_OPEN);
+  CheckProxy(FUSE_RELEASE);
+
+  // Ensure the loop exits.
+  Close();
 }
 
 }  // namespace fuse