Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e6b7328b authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Retry write operation when getting ENOBUFS." into oc-dev

parents dd618767 6f6210dd
Loading
Loading
Loading
Loading
+30 −21
Original line number Diff line number Diff line
@@ -34,6 +34,8 @@ namespace android {
namespace fuse {
namespace {

constexpr useconds_t kRetrySleepForWriting = 1000;  // 1 ms

template <typename T>
bool CheckHeaderLength(const FuseMessage<T>* self, const char* name, size_t max_size) {
    const auto& header = static_cast<const T*>(self)->header;
@@ -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 auto& header = static_cast<const T*>(self)->header;

    while (true) {
        int result;
        if (sockflag) {
            CHECK(data == nullptr);
@@ -102,19 +105,25 @@ ResultOrAgain WriteInternal(const FuseMessage<T>* self, int fd, int sockflag, co
        } else {
            result = TEMP_FAILURE_RETRY(write(fd, buf, header.len));
        }

        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;
        }
                default:
                    PLOG(ERROR) << "Failed to write a FUSE message";
                    return ResultOrAgain::kFailure;
            }

        }
        CHECK(static_cast<uint32_t>(result) == header.len);
        return ResultOrAgain::kSuccess;
    }
}
}

static_assert(std::is_standard_layout<FuseBuffer>::value,
              "FuseBuffer must be standard layout union.");
@@ -161,7 +170,7 @@ bool FuseMessage<T>::Write(int fd) const {
template <typename T>
bool FuseMessage<T>::WriteWithBody(int fd, size_t max_size, const void* data) const {
    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>