diff --git a/libappfuse/FuseBridgeLoop.cc b/libappfuse/FuseBridgeLoop.cc index acb963cfc..beee4a6f5 100644 --- a/libappfuse/FuseBridgeLoop.cc +++ b/libappfuse/FuseBridgeLoop.cc @@ -26,6 +26,7 @@ bool FuseBridgeLoop::Start( 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 @@ bool FuseBridgeLoop::Start( 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 bd503ebfb..e74d9e700 100644 --- a/libappfuse/tests/FuseBridgeLoopTest.cc +++ b/libappfuse/tests/FuseBridgeLoopTest.cc @@ -200,11 +200,16 @@ TEST_F(FuseBridgeLoopTest, FuseNotImpl) { 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