Loading libappfuse/FuseBuffer.cc +30 −21 Original line number Original line Diff line number Diff line Loading @@ -34,6 +34,8 @@ namespace android { namespace fuse { namespace fuse { namespace { namespace { constexpr useconds_t kRetrySleepForWriting = 1000; // 1 ms template <typename T> template <typename T> bool CheckHeaderLength(const FuseMessage<T>* self, const char* name, size_t max_size) { bool CheckHeaderLength(const FuseMessage<T>* self, const char* name, size_t max_size) { const auto& header = static_cast<const T*>(self)->header; const auto& header = static_cast<const T*>(self)->header; Loading Loading @@ -91,6 +93,7 @@ ResultOrAgain WriteInternal(const FuseMessage<T>* self, int fd, int sockflag, co const char* const buf = reinterpret_cast<const char*>(self); const char* const buf = reinterpret_cast<const char*>(self); const auto& header = static_cast<const T*>(self)->header; const auto& header = static_cast<const T*>(self)->header; while (true) { int result; int result; if (sockflag) { if (sockflag) { CHECK(data == nullptr); CHECK(data == nullptr); Loading @@ -102,19 +105,25 @@ ResultOrAgain WriteInternal(const FuseMessage<T>* self, int fd, int sockflag, co } else { } else { result = TEMP_FAILURE_RETRY(write(fd, buf, header.len)); result = TEMP_FAILURE_RETRY(write(fd, buf, header.len)); } } if (result == -1) { if (result == -1) { if (errno == EAGAIN) { switch (errno) { case ENOBUFS: // When returning ENOBUFS, epoll still reports the FD is writable. Just usleep // and retry again. usleep(kRetrySleepForWriting); continue; case EAGAIN: return ResultOrAgain::kAgain; return ResultOrAgain::kAgain; } default: PLOG(ERROR) << "Failed to write a FUSE message"; PLOG(ERROR) << "Failed to write a FUSE message"; return ResultOrAgain::kFailure; return ResultOrAgain::kFailure; } } } CHECK(static_cast<uint32_t>(result) == header.len); CHECK(static_cast<uint32_t>(result) == header.len); return ResultOrAgain::kSuccess; return ResultOrAgain::kSuccess; } } } } } static_assert(std::is_standard_layout<FuseBuffer>::value, static_assert(std::is_standard_layout<FuseBuffer>::value, "FuseBuffer must be standard layout union."); "FuseBuffer must be standard layout union."); Loading Loading @@ -161,7 +170,7 @@ bool FuseMessage<T>::Write(int fd) const { template <typename T> template <typename T> bool FuseMessage<T>::WriteWithBody(int fd, size_t max_size, const void* data) const { bool FuseMessage<T>::WriteWithBody(int fd, size_t max_size, const void* data) const { CHECK(data != nullptr); CHECK(data != nullptr); return WriteInternal<T>(this, fd, 0, data, max_size) == ResultOrAgain::kSuccess; return WriteInternal(this, fd, 0, data, max_size) == ResultOrAgain::kSuccess; } } template <typename T> template <typename T> Loading Loading
libappfuse/FuseBuffer.cc +30 −21 Original line number Original line Diff line number Diff line Loading @@ -34,6 +34,8 @@ namespace android { namespace fuse { namespace fuse { namespace { namespace { constexpr useconds_t kRetrySleepForWriting = 1000; // 1 ms template <typename T> template <typename T> bool CheckHeaderLength(const FuseMessage<T>* self, const char* name, size_t max_size) { bool CheckHeaderLength(const FuseMessage<T>* self, const char* name, size_t max_size) { const auto& header = static_cast<const T*>(self)->header; const auto& header = static_cast<const T*>(self)->header; Loading Loading @@ -91,6 +93,7 @@ ResultOrAgain WriteInternal(const FuseMessage<T>* self, int fd, int sockflag, co const char* const buf = reinterpret_cast<const char*>(self); const char* const buf = reinterpret_cast<const char*>(self); const auto& header = static_cast<const T*>(self)->header; const auto& header = static_cast<const T*>(self)->header; while (true) { int result; int result; if (sockflag) { if (sockflag) { CHECK(data == nullptr); CHECK(data == nullptr); Loading @@ -102,19 +105,25 @@ ResultOrAgain WriteInternal(const FuseMessage<T>* self, int fd, int sockflag, co } else { } else { result = TEMP_FAILURE_RETRY(write(fd, buf, header.len)); result = TEMP_FAILURE_RETRY(write(fd, buf, header.len)); } } if (result == -1) { if (result == -1) { if (errno == EAGAIN) { switch (errno) { case ENOBUFS: // When returning ENOBUFS, epoll still reports the FD is writable. Just usleep // and retry again. usleep(kRetrySleepForWriting); continue; case EAGAIN: return ResultOrAgain::kAgain; return ResultOrAgain::kAgain; } default: PLOG(ERROR) << "Failed to write a FUSE message"; PLOG(ERROR) << "Failed to write a FUSE message"; return ResultOrAgain::kFailure; return ResultOrAgain::kFailure; } } } CHECK(static_cast<uint32_t>(result) == header.len); CHECK(static_cast<uint32_t>(result) == header.len); return ResultOrAgain::kSuccess; return ResultOrAgain::kSuccess; } } } } } static_assert(std::is_standard_layout<FuseBuffer>::value, static_assert(std::is_standard_layout<FuseBuffer>::value, "FuseBuffer must be standard layout union."); "FuseBuffer must be standard layout union."); Loading Loading @@ -161,7 +170,7 @@ bool FuseMessage<T>::Write(int fd) const { template <typename T> template <typename T> bool FuseMessage<T>::WriteWithBody(int fd, size_t max_size, const void* data) const { bool FuseMessage<T>::WriteWithBody(int fd, size_t max_size, const void* data) const { CHECK(data != nullptr); CHECK(data != nullptr); return WriteInternal<T>(this, fd, 0, data, max_size) == ResultOrAgain::kSuccess; return WriteInternal(this, fd, 0, data, max_size) == ResultOrAgain::kSuccess; } } template <typename T> template <typename T> Loading