Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FD is blocked in fifo #1343

Open
mhomidi opened this issue Aug 15, 2024 · 0 comments
Open

FD is blocked in fifo #1343

mhomidi opened this issue Aug 15, 2024 · 0 comments

Comments

@mhomidi
Copy link
Collaborator

mhomidi commented Aug 15, 2024

I was running gvisor testcase on quark and I faced an issue with fifo. The testcase is this:

TEST(FifoTest, Fifo) {
  const std::string fifo = NewTempAbsPath();
  ASSERT_THAT(mknod(fifo.c_str(), S_IFIFO | S_IRUSR | S_IWUSR, 0),
              SyscallSucceeds());

  struct stat st;
  ASSERT_THAT(stat(fifo.c_str(), &st), SyscallSucceeds());
  EXPECT_TRUE(S_ISFIFO(st.st_mode));

  std::string msg = "some std::string";
  std::vector<char> buf(512);

  // Read-end of the pipe.
  ScopedThread t([&fifo, &buf, &msg]() {
    FileDescriptor fd =
        ASSERT_NO_ERRNO_AND_VALUE(OpenRetryEINTR(fifo.c_str(), O_RDONLY));
    EXPECT_THAT(ReadFd(fd.get(), buf.data(), buf.size()),
                SyscallSucceedsWithValue(msg.length()));
    EXPECT_EQ(msg, std::string(buf.data()));
  });
}

The problem is tnat when the write does its job, it closes the file. Then reader comes and open it with same fd but it is blocked when it is reading.
Actually it reads first 16 byte, but in the second iteration in ApplyFileIoSyscall, instead of getting zero, it is blocked when it call read syscall.

code of ReadFd and writeFd link to code:

inline ssize_t ReadFd(int fd, void* buf, size_t count) {
  return internal::ApplyFileIoSyscall(
      [&](size_t completed) {
        return read(fd, static_cast<char*>(buf) + completed, count - completed);
      },
      count);
}

inline ssize_t WriteFd(int fd, void const* buf, size_t count) {
  return internal::ApplyFileIoSyscall(
      [&](size_t completed) {
        return write(fd, static_cast<char const*>(buf) + completed,
                     count - completed);
      },
      count);
}

code of ApplyFileIoSyscall link :

ssize_t ApplyFileIoSyscall(F const& f, size_t const count) {
  size_t completed = 0;
  // `do ... while` because some callers actually want to make a syscall with a
  // count of 0.
  do {
    auto const cur = RetryEINTR(f)(completed);
    if (cur < 0) {
      return cur;
    } else if (cur == 0) {
      break;
    }
    completed += cur;
  } while (completed < count);
  return completed;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant