gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/test/syscalls/linux/epoll.cc (about)

     1  // Copyright 2018 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  #include <errno.h>
    16  #include <limits.h>
    17  #include <pthread.h>
    18  #include <signal.h>
    19  #include <stdint.h>
    20  #include <stdio.h>
    21  #include <string.h>
    22  #include <sys/epoll.h>
    23  #include <sys/eventfd.h>
    24  #include <sys/signalfd.h>
    25  #include <time.h>
    26  #include <unistd.h>
    27  
    28  #include "gtest/gtest.h"
    29  #include "absl/synchronization/mutex.h"
    30  #include "test/util/epoll_util.h"
    31  #include "test/util/eventfd_util.h"
    32  #include "test/util/file_descriptor.h"
    33  #include "test/util/posix_error.h"
    34  #include "test/util/signal_util.h"
    35  #include "test/util/socket_util.h"
    36  #include "test/util/temp_path.h"
    37  #include "test/util/test_util.h"
    38  #include "test/util/thread_util.h"
    39  
    40  namespace gvisor {
    41  namespace testing {
    42  
    43  namespace {
    44  
    45  constexpr int kFDsPerEpoll = 3;
    46  constexpr uint64_t kMagicConstant = 0x0102030405060708;
    47  
    48  #ifndef SYS_epoll_pwait2
    49  #define SYS_epoll_pwait2 441
    50  #endif
    51  
    52  int test_epoll_pwait2(int fd, struct epoll_event* events, int maxevents,
    53                        const struct timespec* timeout, const sigset_t* sigset) {
    54    return syscall(SYS_epoll_pwait2, fd, events, maxevents, timeout, sigset);
    55  }
    56  
    57  TEST(EpollTest, AllWritable) {
    58    auto epollfd = ASSERT_NO_ERRNO_AND_VALUE(NewEpollFD());
    59    std::vector<FileDescriptor> eventfds;
    60    for (int i = 0; i < kFDsPerEpoll; i++) {
    61      eventfds.push_back(ASSERT_NO_ERRNO_AND_VALUE(NewEventFD()));
    62      ASSERT_NO_ERRNO(RegisterEpollFD(epollfd.get(), eventfds[i].get(),
    63                                      EPOLLIN | EPOLLOUT, kMagicConstant + i));
    64    }
    65  
    66    struct epoll_event result[kFDsPerEpoll];
    67    ASSERT_THAT(RetryEINTR(epoll_wait)(epollfd.get(), result, kFDsPerEpoll, -1),
    68                SyscallSucceedsWithValue(kFDsPerEpoll));
    69    for (int i = 0; i < kFDsPerEpoll; i++) {
    70      ASSERT_EQ(result[i].events, EPOLLOUT);
    71    }
    72  }
    73  
    74  TEST(EpollTest, LastReadable) {
    75    auto epollfd = ASSERT_NO_ERRNO_AND_VALUE(NewEpollFD());
    76    std::vector<FileDescriptor> eventfds;
    77    for (int i = 0; i < kFDsPerEpoll; i++) {
    78      eventfds.push_back(ASSERT_NO_ERRNO_AND_VALUE(NewEventFD()));
    79      ASSERT_NO_ERRNO(RegisterEpollFD(epollfd.get(), eventfds[i].get(),
    80                                      EPOLLIN | EPOLLOUT, kMagicConstant + i));
    81    }
    82  
    83    uint64_t tmp = 1;
    84    ASSERT_THAT(WriteFd(eventfds[kFDsPerEpoll - 1].get(), &tmp, sizeof(tmp)),
    85                SyscallSucceedsWithValue(sizeof(tmp)));
    86  
    87    struct epoll_event result[kFDsPerEpoll];
    88    ASSERT_THAT(RetryEINTR(epoll_wait)(epollfd.get(), result, kFDsPerEpoll, -1),
    89                SyscallSucceedsWithValue(kFDsPerEpoll));
    90  
    91    int i;
    92    for (i = 0; i < kFDsPerEpoll - 1; i++) {
    93      EXPECT_EQ(result[i].events, EPOLLOUT);
    94    }
    95    EXPECT_EQ(result[i].events, EPOLLOUT | EPOLLIN);
    96    EXPECT_EQ(result[i].data.u64, kMagicConstant + i);
    97  }
    98  
    99  TEST(EpollTest, LastNonWritable) {
   100    auto epollfd = ASSERT_NO_ERRNO_AND_VALUE(NewEpollFD());
   101    std::vector<FileDescriptor> eventfds;
   102    for (int i = 0; i < kFDsPerEpoll; i++) {
   103      eventfds.push_back(ASSERT_NO_ERRNO_AND_VALUE(NewEventFD()));
   104      ASSERT_NO_ERRNO(RegisterEpollFD(epollfd.get(), eventfds[i].get(),
   105                                      EPOLLIN | EPOLLOUT, kMagicConstant + i));
   106    }
   107  
   108    // Write the maximum value to the event fd so that writing to it again would
   109    // block.
   110    uint64_t tmp = ULLONG_MAX - 1;
   111    ASSERT_THAT(WriteFd(eventfds[kFDsPerEpoll - 1].get(), &tmp, sizeof(tmp)),
   112                SyscallSucceedsWithValue(sizeof(tmp)));
   113  
   114    struct epoll_event result[kFDsPerEpoll];
   115    ASSERT_THAT(RetryEINTR(epoll_wait)(epollfd.get(), result, kFDsPerEpoll, -1),
   116                SyscallSucceedsWithValue(kFDsPerEpoll));
   117  
   118    int i;
   119    for (i = 0; i < kFDsPerEpoll - 1; i++) {
   120      EXPECT_EQ(result[i].events, EPOLLOUT);
   121    }
   122    EXPECT_EQ(result[i].events, EPOLLIN);
   123    EXPECT_THAT(ReadFd(eventfds[kFDsPerEpoll - 1].get(), &tmp, sizeof(tmp)),
   124                sizeof(tmp));
   125    EXPECT_THAT(RetryEINTR(epoll_wait)(epollfd.get(), result, kFDsPerEpoll, -1),
   126                SyscallSucceedsWithValue(kFDsPerEpoll));
   127  
   128    for (i = 0; i < kFDsPerEpoll; i++) {
   129      EXPECT_EQ(result[i].events, EPOLLOUT);
   130    }
   131  }
   132  
   133  TEST(EpollTest, Timeout) {
   134    auto epollfd = ASSERT_NO_ERRNO_AND_VALUE(NewEpollFD());
   135    std::vector<FileDescriptor> eventfds;
   136    for (int i = 0; i < kFDsPerEpoll; i++) {
   137      eventfds.push_back(ASSERT_NO_ERRNO_AND_VALUE(NewEventFD()));
   138      ASSERT_NO_ERRNO(RegisterEpollFD(epollfd.get(), eventfds[i].get(), EPOLLIN,
   139                                      kMagicConstant + i));
   140    }
   141  
   142    constexpr int kTimeoutMs = 200;
   143    struct timespec begin;
   144    struct timespec end;
   145    struct epoll_event result[kFDsPerEpoll];
   146  
   147    {
   148      const DisableSave ds;  // Timing-related.
   149      EXPECT_THAT(clock_gettime(CLOCK_MONOTONIC, &begin), SyscallSucceeds());
   150  
   151      ASSERT_THAT(
   152          RetryEINTR(epoll_wait)(epollfd.get(), result, kFDsPerEpoll, kTimeoutMs),
   153          SyscallSucceedsWithValue(0));
   154      EXPECT_THAT(clock_gettime(CLOCK_MONOTONIC, &end), SyscallSucceeds());
   155    }
   156  
   157    // Check the lower bound on the timeout.  Checking for an upper bound is
   158    // fragile because Linux can overrun the timeout due to scheduling delays.
   159    EXPECT_GT(ms_elapsed(begin, end), kTimeoutMs - 1);
   160  }
   161  
   162  TEST(EpollTest, EpollPwait2Timeout) {
   163    auto epollfd = ASSERT_NO_ERRNO_AND_VALUE(NewEpollFD());
   164    // 200 milliseconds.
   165    constexpr int kTimeoutNs = 200000000;
   166    struct timespec timeout;
   167    timeout.tv_sec = 0;
   168    timeout.tv_nsec = 0;
   169    struct timespec begin;
   170    struct timespec end;
   171    struct epoll_event result[kFDsPerEpoll];
   172  
   173    std::vector<FileDescriptor> eventfds;
   174    for (int i = 0; i < kFDsPerEpoll; i++) {
   175      eventfds.push_back(ASSERT_NO_ERRNO_AND_VALUE(NewEventFD()));
   176      ASSERT_NO_ERRNO(RegisterEpollFD(epollfd.get(), eventfds[i].get(), EPOLLIN,
   177                                      kMagicConstant + i));
   178    }
   179  
   180    // Pass valid arguments so that the syscall won't be blocked indefinitely
   181    // nor return errno EINVAL.
   182    //
   183    // The syscall returns immediately when timeout is zero,
   184    // even if no events are available.
   185    SKIP_IF(!IsRunningOnGvisor() &&
   186            test_epoll_pwait2(epollfd.get(), result, kFDsPerEpoll, &timeout,
   187                              nullptr) < 0 &&
   188            errno == ENOSYS);
   189  
   190    {
   191      const DisableSave ds;  // Timing-related.
   192      EXPECT_THAT(clock_gettime(CLOCK_MONOTONIC, &begin), SyscallSucceeds());
   193  
   194      timeout.tv_nsec = kTimeoutNs;
   195      ASSERT_THAT(RetryEINTR(test_epoll_pwait2)(epollfd.get(), result,
   196                                                kFDsPerEpoll, &timeout, nullptr),
   197                  SyscallSucceedsWithValue(0));
   198      EXPECT_THAT(clock_gettime(CLOCK_MONOTONIC, &end), SyscallSucceeds());
   199    }
   200  
   201    // Check the lower bound on the timeout.  Checking for an upper bound is
   202    // fragile because Linux can overrun the timeout due to scheduling delays.
   203    EXPECT_GT(ns_elapsed(begin, end), kTimeoutNs - 1);
   204  }
   205  
   206  void* writer(void* arg) {
   207    int fd = *reinterpret_cast<int*>(arg);
   208    uint64_t tmp = 1;
   209  
   210    usleep(200000);
   211    if (WriteFd(fd, &tmp, sizeof(tmp)) != sizeof(tmp)) {
   212      fprintf(stderr, "writer failed: errno %s\n", strerror(errno));
   213    }
   214  
   215    return nullptr;
   216  }
   217  
   218  TEST(EpollTest, WaitThenUnblock) {
   219    auto epollfd = ASSERT_NO_ERRNO_AND_VALUE(NewEpollFD());
   220    std::vector<FileDescriptor> eventfds;
   221    for (int i = 0; i < kFDsPerEpoll; i++) {
   222      eventfds.push_back(ASSERT_NO_ERRNO_AND_VALUE(NewEventFD()));
   223      ASSERT_NO_ERRNO(RegisterEpollFD(epollfd.get(), eventfds[i].get(), EPOLLIN,
   224                                      kMagicConstant + i));
   225    }
   226  
   227    // Fire off a thread that will make at least one of the event fds readable.
   228    pthread_t thread;
   229    int make_readable = eventfds[0].get();
   230    ASSERT_THAT(pthread_create(&thread, nullptr, writer, &make_readable),
   231                SyscallSucceedsWithValue(0));
   232  
   233    struct epoll_event result[kFDsPerEpoll];
   234    EXPECT_THAT(RetryEINTR(epoll_wait)(epollfd.get(), result, kFDsPerEpoll, -1),
   235                SyscallSucceedsWithValue(1));
   236    EXPECT_THAT(pthread_detach(thread), SyscallSucceeds());
   237  }
   238  
   239  #ifndef ANDROID  // Android does not support pthread_cancel
   240  
   241  void sighandler(int s) {}
   242  
   243  void* signaler(void* arg) {
   244    pthread_t* t = reinterpret_cast<pthread_t*>(arg);
   245    // Repeatedly send the real-time signal until we are detached, because it's
   246    // difficult to know exactly when epoll_wait on another thread (which this
   247    // is intending to interrupt) has started blocking.
   248    while (1) {
   249      usleep(200000);
   250      pthread_kill(*t, SIGRTMIN);
   251    }
   252    return nullptr;
   253  }
   254  
   255  TEST(EpollTest, UnblockWithSignal) {
   256    auto epollfd = ASSERT_NO_ERRNO_AND_VALUE(NewEpollFD());
   257    std::vector<FileDescriptor> eventfds;
   258    for (int i = 0; i < kFDsPerEpoll; i++) {
   259      eventfds.push_back(ASSERT_NO_ERRNO_AND_VALUE(NewEventFD()));
   260      ASSERT_NO_ERRNO(RegisterEpollFD(epollfd.get(), eventfds[i].get(), EPOLLIN,
   261                                      kMagicConstant + i));
   262    }
   263  
   264    signal(SIGRTMIN, sighandler);
   265    // Unblock the real time signals that InitGoogle blocks :(
   266    sigset_t unblock;
   267    sigemptyset(&unblock);
   268    sigaddset(&unblock, SIGRTMIN);
   269    ASSERT_THAT(sigprocmask(SIG_UNBLOCK, &unblock, nullptr), SyscallSucceeds());
   270  
   271    pthread_t thread;
   272    pthread_t cur = pthread_self();
   273    ASSERT_THAT(pthread_create(&thread, nullptr, signaler, &cur),
   274                SyscallSucceedsWithValue(0));
   275  
   276    struct epoll_event result[kFDsPerEpoll];
   277    EXPECT_THAT(epoll_wait(epollfd.get(), result, kFDsPerEpoll, -1),
   278                SyscallFailsWithErrno(EINTR));
   279    EXPECT_THAT(pthread_cancel(thread), SyscallSucceeds());
   280    EXPECT_THAT(pthread_detach(thread), SyscallSucceeds());
   281  }
   282  
   283  #endif  // ANDROID
   284  
   285  TEST(EpollTest, TimeoutNoFds) {
   286    auto epollfd = ASSERT_NO_ERRNO_AND_VALUE(NewEpollFD());
   287    struct epoll_event result[kFDsPerEpoll];
   288    EXPECT_THAT(RetryEINTR(epoll_wait)(epollfd.get(), result, kFDsPerEpoll, 100),
   289                SyscallSucceedsWithValue(0));
   290  }
   291  
   292  struct addr_ctx {
   293    int epollfd;
   294    int eventfd;
   295  };
   296  
   297  void* fd_adder(void* arg) {
   298    struct addr_ctx* actx = reinterpret_cast<struct addr_ctx*>(arg);
   299    struct epoll_event event;
   300    event.events = EPOLLIN | EPOLLOUT;
   301    event.data.u64 = 0xdeadbeeffacefeed;
   302  
   303    usleep(200000);
   304    if (epoll_ctl(actx->epollfd, EPOLL_CTL_ADD, actx->eventfd, &event) == -1) {
   305      fprintf(stderr, "epoll_ctl failed: %s\n", strerror(errno));
   306    }
   307  
   308    return nullptr;
   309  }
   310  
   311  TEST(EpollTest, UnblockWithNewFD) {
   312    auto epollfd = ASSERT_NO_ERRNO_AND_VALUE(NewEpollFD());
   313    auto eventfd = ASSERT_NO_ERRNO_AND_VALUE(NewEventFD());
   314  
   315    pthread_t thread;
   316    struct addr_ctx actx = {epollfd.get(), eventfd.get()};
   317    ASSERT_THAT(pthread_create(&thread, nullptr, fd_adder, &actx),
   318                SyscallSucceedsWithValue(0));
   319  
   320    struct epoll_event result[kFDsPerEpoll];
   321    // Wait while no FDs are ready, but after 200ms fd_adder will add a ready FD
   322    // to epoll which will wake us up.
   323    EXPECT_THAT(RetryEINTR(epoll_wait)(epollfd.get(), result, kFDsPerEpoll, -1),
   324                SyscallSucceedsWithValue(1));
   325    EXPECT_THAT(pthread_detach(thread), SyscallSucceeds());
   326    EXPECT_EQ(result[0].data.u64, 0xdeadbeeffacefeed);
   327  }
   328  
   329  TEST(EpollTest, Oneshot) {
   330    auto epollfd = ASSERT_NO_ERRNO_AND_VALUE(NewEpollFD());
   331    std::vector<FileDescriptor> eventfds;
   332    for (int i = 0; i < kFDsPerEpoll; i++) {
   333      eventfds.push_back(ASSERT_NO_ERRNO_AND_VALUE(NewEventFD()));
   334      ASSERT_NO_ERRNO(RegisterEpollFD(epollfd.get(), eventfds[i].get(), EPOLLIN,
   335                                      kMagicConstant + i));
   336    }
   337  
   338    struct epoll_event event;
   339    event.events = EPOLLOUT | EPOLLONESHOT;
   340    event.data.u64 = kMagicConstant;
   341    ASSERT_THAT(
   342        epoll_ctl(epollfd.get(), EPOLL_CTL_MOD, eventfds[0].get(), &event),
   343        SyscallSucceeds());
   344  
   345    struct epoll_event result[kFDsPerEpoll];
   346    // One-shot entry means that the first epoll_wait should succeed.
   347    ASSERT_THAT(RetryEINTR(epoll_wait)(epollfd.get(), result, kFDsPerEpoll, -1),
   348                SyscallSucceedsWithValue(1));
   349    EXPECT_EQ(result[0].data.u64, kMagicConstant);
   350  
   351    // One-shot entry means that the second epoll_wait should timeout.
   352    EXPECT_THAT(RetryEINTR(epoll_wait)(epollfd.get(), result, kFDsPerEpoll, 100),
   353                SyscallSucceedsWithValue(0));
   354  }
   355  
   356  // NOTE(b/228468030): This test aims to test epoll functionality when 2 epoll
   357  // instances are used to track the same FD using EPOLLONESHOT.
   358  TEST(EpollTest, DoubleEpollOneShot) {
   359    int sockets[2];
   360    ASSERT_THAT(socketpair(AF_UNIX, SOCK_STREAM, 0, sockets), SyscallSucceeds());
   361    auto epollfd1 = ASSERT_NO_ERRNO_AND_VALUE(NewEpollFD());
   362    auto epollfd2 = ASSERT_NO_ERRNO_AND_VALUE(NewEpollFD());
   363  
   364    ASSERT_NO_ERRNO(RegisterEpollFD(epollfd1.get(), sockets[1],
   365                                    EPOLLIN | EPOLLONESHOT, kMagicConstant));
   366    ASSERT_NO_ERRNO(RegisterEpollFD(epollfd2.get(), sockets[1],
   367                                    EPOLLIN | EPOLLONESHOT, kMagicConstant));
   368  
   369    const DisableSave ds;  // May trigger spurious event.
   370  
   371    constexpr char msg1[] = "hello";
   372    constexpr char msg2[] = "world";
   373    // For the purpose of this test, msg1 and msg2 should be equal in size.
   374    ASSERT_EQ(sizeof(msg1), sizeof(msg2));
   375    const auto msg_size = sizeof(msg1);
   376  
   377    // Server and client here only communicate with `msg_size` sized messages.
   378    // When client sees msg2, it will shutdown. All other communication is msg1.
   379    const uint n = 1 << 14;  // Arbitrary to trigger race.
   380    ScopedThread server([&sockets, &msg1, &msg2]() {
   381      char tmp[msg_size];
   382      for (uint i = 0; i < n; ++i) {
   383        // Read request.
   384        ASSERT_THAT(ReadFd(sockets[0], &tmp, sizeof(tmp)),
   385                    SyscallSucceedsWithValue(sizeof(tmp)));
   386        EXPECT_EQ(strcmp(tmp, msg1), 0);
   387        // Respond to request.
   388        if (i < n - 2) {
   389          ASSERT_EQ(WriteFd(sockets[0], msg1, sizeof(msg1)), sizeof(msg1));
   390        } else {
   391          ASSERT_EQ(WriteFd(sockets[0], msg2, sizeof(msg2)), sizeof(msg2));
   392        }
   393      }
   394    });
   395  
   396    // m is used to synchronize reads on sockets[1].
   397    absl::Mutex m;
   398  
   399    auto clientFn = [&sockets, &msg1, &msg2, &m](FileDescriptor& epollfd) {
   400      char tmp[msg_size];
   401      bool rearm = false;
   402      while (true) {
   403        if (rearm) {
   404          // Rearm with EPOLLONESHOT.
   405          struct epoll_event event;
   406          event.events = EPOLLIN | EPOLLONESHOT;
   407          event.data.u64 = kMagicConstant;
   408          ASSERT_THAT(epoll_ctl(epollfd.get(), EPOLL_CTL_MOD, sockets[1], &event),
   409                      SyscallSucceeds());
   410        }
   411  
   412        // Make request.
   413        {
   414          absl::MutexLock lock(&m);
   415          ASSERT_EQ(WriteFd(sockets[1], msg1, sizeof(msg1)), sizeof(msg1));
   416        }
   417  
   418        // Wait for response.
   419        struct epoll_event result[kFDsPerEpoll];
   420        ASSERT_THAT(
   421            RetryEINTR(epoll_wait)(epollfd.get(), result, kFDsPerEpoll, -1),
   422            SyscallSucceedsWithValue(1));
   423        EXPECT_EQ(result[0].data.u64, kMagicConstant);
   424        rearm = true;
   425  
   426        // Read response.
   427        {
   428          absl::MutexLock lock(&m);
   429          ASSERT_THAT(ReadFd(sockets[1], &tmp, sizeof(tmp)),
   430                      SyscallSucceedsWithValue(sizeof(tmp)));
   431        }
   432        if (strcmp(tmp, msg2) == 0) {
   433          break;
   434        }
   435        EXPECT_EQ(strcmp(tmp, msg1), 0);
   436      }
   437    };
   438  
   439    ScopedThread client1([&epollfd1, &clientFn]() { clientFn(epollfd1); });
   440  
   441    ScopedThread client2([&epollfd2, &clientFn]() { clientFn(epollfd2); });
   442  
   443    server.Join();
   444    client1.Join();
   445    client2.Join();
   446  }
   447  
   448  TEST(EpollTest, EdgeTriggered) {
   449    // Test edge-triggered entry: make it edge-triggered, first wait should
   450    // return it, second one should time out, make it writable again, third wait
   451    // should return it, fourth wait should timeout.
   452    auto epollfd = ASSERT_NO_ERRNO_AND_VALUE(NewEpollFD());
   453    auto eventfd = ASSERT_NO_ERRNO_AND_VALUE(NewEventFD());
   454    ASSERT_NO_ERRNO(RegisterEpollFD(epollfd.get(), eventfd.get(),
   455                                    EPOLLOUT | EPOLLET, kMagicConstant));
   456  
   457    struct epoll_event result[kFDsPerEpoll];
   458  
   459    {
   460      const DisableSave ds;  // May trigger spurious event.
   461  
   462      // Edge-triggered entry means that the first epoll_wait should return the
   463      // event.
   464      ASSERT_THAT(epoll_wait(epollfd.get(), result, kFDsPerEpoll, -1),
   465                  SyscallSucceedsWithValue(1));
   466      EXPECT_EQ(result[0].data.u64, kMagicConstant);
   467  
   468      // Edge-triggered entry means that the second epoll_wait should time out.
   469      ASSERT_THAT(epoll_wait(epollfd.get(), result, kFDsPerEpoll, 100),
   470                  SyscallSucceedsWithValue(0));
   471    }
   472  
   473    uint64_t tmp = ULLONG_MAX - 1;
   474  
   475    // Make an fd non-writable.
   476    ASSERT_THAT(WriteFd(eventfd.get(), &tmp, sizeof(tmp)),
   477                SyscallSucceedsWithValue(sizeof(tmp)));
   478  
   479    // Make the same fd non-writable to trigger a change, which will trigger an
   480    // edge-triggered event.
   481    ASSERT_THAT(ReadFd(eventfd.get(), &tmp, sizeof(tmp)),
   482                SyscallSucceedsWithValue(sizeof(tmp)));
   483  
   484    {
   485      const DisableSave ds;  // May trigger spurious event.
   486  
   487      // An edge-triggered event should now be returned.
   488      ASSERT_THAT(epoll_wait(epollfd.get(), result, kFDsPerEpoll, -1),
   489                  SyscallSucceedsWithValue(1));
   490      EXPECT_EQ(result[0].data.u64, kMagicConstant);
   491  
   492      // The edge-triggered event had been consumed above, we don't expect to
   493      // get it again.
   494      ASSERT_THAT(epoll_wait(epollfd.get(), result, kFDsPerEpoll, 100),
   495                  SyscallSucceedsWithValue(0));
   496    }
   497  }
   498  
   499  TEST(EpollTest, OneshotAndEdgeTriggered) {
   500    auto epollfd = ASSERT_NO_ERRNO_AND_VALUE(NewEpollFD());
   501    auto eventfd = ASSERT_NO_ERRNO_AND_VALUE(NewEventFD());
   502    ASSERT_NO_ERRNO(RegisterEpollFD(epollfd.get(), eventfd.get(),
   503                                    EPOLLOUT | EPOLLET | EPOLLONESHOT,
   504                                    kMagicConstant));
   505  
   506    struct epoll_event result[kFDsPerEpoll];
   507    // First time one shot edge-triggered entry means that epoll_wait should
   508    // return the event.
   509    ASSERT_THAT(RetryEINTR(epoll_wait)(epollfd.get(), result, kFDsPerEpoll, -1),
   510                SyscallSucceedsWithValue(1));
   511    EXPECT_EQ(result[0].data.u64, kMagicConstant);
   512  
   513    // Edge-triggered entry means that the second epoll_wait should time out.
   514    ASSERT_THAT(RetryEINTR(epoll_wait)(epollfd.get(), result, kFDsPerEpoll, 100),
   515                SyscallSucceedsWithValue(0));
   516  
   517    uint64_t tmp = ULLONG_MAX - 1;
   518    // Make an fd non-writable.
   519    ASSERT_THAT(WriteFd(eventfd.get(), &tmp, sizeof(tmp)),
   520                SyscallSucceedsWithValue(sizeof(tmp)));
   521    // Make the same fd non-writable to trigger a change, which will not trigger
   522    // an edge-triggered event because we've also included EPOLLONESHOT.
   523    ASSERT_THAT(ReadFd(eventfd.get(), &tmp, sizeof(tmp)),
   524                SyscallSucceedsWithValue(sizeof(tmp)));
   525    ASSERT_THAT(RetryEINTR(epoll_wait)(epollfd.get(), result, kFDsPerEpoll, 100),
   526                SyscallSucceedsWithValue(0));
   527  }
   528  
   529  TEST(EpollTest, CycleOfOneDisallowed) {
   530    auto epollfd = ASSERT_NO_ERRNO_AND_VALUE(NewEpollFD());
   531  
   532    struct epoll_event event;
   533    event.events = EPOLLOUT;
   534    event.data.u64 = kMagicConstant;
   535  
   536    ASSERT_THAT(epoll_ctl(epollfd.get(), EPOLL_CTL_ADD, epollfd.get(), &event),
   537                SyscallFailsWithErrno(EINVAL));
   538  }
   539  
   540  TEST(EpollTest, CycleOfThreeDisallowed) {
   541    auto epollfd = ASSERT_NO_ERRNO_AND_VALUE(NewEpollFD());
   542    auto epollfd1 = ASSERT_NO_ERRNO_AND_VALUE(NewEpollFD());
   543    auto epollfd2 = ASSERT_NO_ERRNO_AND_VALUE(NewEpollFD());
   544  
   545    ASSERT_NO_ERRNO(
   546        RegisterEpollFD(epollfd.get(), epollfd1.get(), EPOLLIN, kMagicConstant));
   547    ASSERT_NO_ERRNO(
   548        RegisterEpollFD(epollfd1.get(), epollfd2.get(), EPOLLIN, kMagicConstant));
   549  
   550    struct epoll_event event;
   551    event.events = EPOLLIN;
   552    event.data.u64 = kMagicConstant;
   553    EXPECT_THAT(epoll_ctl(epollfd2.get(), EPOLL_CTL_ADD, epollfd.get(), &event),
   554                SyscallFailsWithErrno(ELOOP));
   555  }
   556  
   557  TEST(EpollTest, CloseFile) {
   558    auto epollfd = ASSERT_NO_ERRNO_AND_VALUE(NewEpollFD());
   559    auto eventfd = ASSERT_NO_ERRNO_AND_VALUE(NewEventFD());
   560    ASSERT_NO_ERRNO(
   561        RegisterEpollFD(epollfd.get(), eventfd.get(), EPOLLOUT, kMagicConstant));
   562  
   563    struct epoll_event result[kFDsPerEpoll];
   564    ASSERT_THAT(RetryEINTR(epoll_wait)(epollfd.get(), result, kFDsPerEpoll, -1),
   565                SyscallSucceedsWithValue(1));
   566    EXPECT_EQ(result[0].data.u64, kMagicConstant);
   567  
   568    // Close the event fd early.
   569    eventfd.reset();
   570  
   571    EXPECT_THAT(RetryEINTR(epoll_wait)(epollfd.get(), result, kFDsPerEpoll, 100),
   572                SyscallSucceedsWithValue(0));
   573  }
   574  
   575  TEST(EpollTest, PipeReaderHupAfterWriterClosed) {
   576    auto epollfd = ASSERT_NO_ERRNO_AND_VALUE(NewEpollFD());
   577    int pipefds[2];
   578    ASSERT_THAT(pipe(pipefds), SyscallSucceeds());
   579    FileDescriptor rfd(pipefds[0]);
   580    FileDescriptor wfd(pipefds[1]);
   581  
   582    ASSERT_NO_ERRNO(RegisterEpollFD(epollfd.get(), rfd.get(), 0, kMagicConstant));
   583    struct epoll_event result[kFDsPerEpoll];
   584    // Initially, rfd should not generate any events of interest.
   585    ASSERT_THAT(epoll_wait(epollfd.get(), result, kFDsPerEpoll, 0),
   586                SyscallSucceedsWithValue(0));
   587    // Close the write end of the pipe.
   588    wfd.reset();
   589    // rfd should now generate EPOLLHUP, which EPOLL_CTL_ADD unconditionally adds
   590    // to the set of events of interest.
   591    ASSERT_THAT(epoll_wait(epollfd.get(), result, kFDsPerEpoll, 0),
   592                SyscallSucceedsWithValue(1));
   593    EXPECT_EQ(result[0].events, EPOLLHUP);
   594    EXPECT_EQ(result[0].data.u64, kMagicConstant);
   595  }
   596  
   597  TEST(EpollTest, PipeWriterErrAfterReaderClosed) {
   598    auto epollfd = ASSERT_NO_ERRNO_AND_VALUE(NewEpollFD());
   599    int pipefds[2];
   600    ASSERT_THAT(pipe(pipefds), SyscallSucceeds());
   601    FileDescriptor rfd(pipefds[0]);
   602    FileDescriptor wfd(pipefds[1]);
   603  
   604    ASSERT_NO_ERRNO(
   605        RegisterEpollFD(epollfd.get(), wfd.get(), EPOLLERR, kMagicConstant));
   606    struct epoll_event result[kFDsPerEpoll];
   607    // Initially, wfd should not generate any events of interest.
   608    ASSERT_THAT(epoll_wait(epollfd.get(), result, kFDsPerEpoll, 0),
   609                SyscallSucceedsWithValue(0));
   610    // Close the read end of the pipe.
   611    rfd.reset();
   612    // wfd should now generate EPOLLERR, which EPOLL_CTL_ADD unconditionally adds
   613    // to the set of events of interest.
   614    ASSERT_THAT(epoll_wait(epollfd.get(), result, kFDsPerEpoll, 0),
   615                SyscallSucceedsWithValue(1));
   616    EXPECT_EQ(result[0].events, EPOLLERR);
   617    EXPECT_EQ(result[0].data.u64, kMagicConstant);
   618  }
   619  
   620  TEST(EpollTest, DoubleLayerEpoll) {
   621    int pipefds[2];
   622    ASSERT_THAT(pipe2(pipefds, O_NONBLOCK), SyscallSucceeds());
   623    FileDescriptor rfd(pipefds[0]);
   624    FileDescriptor wfd(pipefds[1]);
   625  
   626    auto epfd1 = ASSERT_NO_ERRNO_AND_VALUE(NewEpollFD());
   627    ASSERT_NO_ERRNO(
   628        RegisterEpollFD(epfd1.get(), rfd.get(), EPOLLIN | EPOLLHUP, rfd.get()));
   629  
   630    auto epfd2 = ASSERT_NO_ERRNO_AND_VALUE(NewEpollFD());
   631    ASSERT_NO_ERRNO(RegisterEpollFD(epfd2.get(), epfd1.get(), EPOLLIN | EPOLLHUP,
   632                                    epfd1.get()));
   633  
   634    // Write to wfd and then check if epoll events were generated correctly.
   635    // Run this loop a couple of times to check if event in epfd1 is cleaned.
   636    constexpr char data[] = "data";
   637    for (int i = 0; i < 2; ++i) {
   638      ScopedThread thread1([&wfd, &data]() {
   639        sleep(1);
   640        ASSERT_EQ(WriteFd(wfd.get(), data, sizeof(data)), sizeof(data));
   641      });
   642  
   643      struct epoll_event ret_events[2];
   644      ASSERT_THAT(RetryEINTR(epoll_wait)(epfd2.get(), ret_events, 2, 5000),
   645                  SyscallSucceedsWithValue(1));
   646      ASSERT_EQ(ret_events[0].data.fd, epfd1.get());
   647      ASSERT_THAT(RetryEINTR(epoll_wait)(epfd1.get(), ret_events, 2, 5000),
   648                  SyscallSucceedsWithValue(1));
   649      ASSERT_EQ(ret_events[0].data.fd, rfd.get());
   650      char readBuf[sizeof(data)];
   651      ASSERT_EQ(ReadFd(rfd.get(), readBuf, sizeof(data)), sizeof(data));
   652    }
   653  }
   654  
   655  TEST(EpollTest, RegularFiles) {
   656    auto epollfd = ASSERT_NO_ERRNO_AND_VALUE(NewEpollFD());
   657  
   658    struct epoll_event event;
   659    event.events = EPOLLIN | EPOLLOUT;
   660    event.data.u64 = kMagicConstant;
   661  
   662    auto path = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile());
   663    auto fd = ASSERT_NO_ERRNO_AND_VALUE(Open(path.path(), O_RDONLY));
   664    EXPECT_THAT(epoll_ctl(epollfd.get(), EPOLL_CTL_ADD, fd.get(), &event),
   665                SyscallFailsWithErrno(EPERM));
   666  }
   667  
   668  // Regression test for b/222369818.
   669  TEST(EpollTest, ReadyMutexCircularity) {
   670    constexpr int kSignal = SIGUSR1;
   671    sigset_t set;
   672    sigemptyset(&set);
   673    sigaddset(&set, kSignal);
   674    auto cleanup_sigmask =
   675        ASSERT_NO_ERRNO_AND_VALUE(ScopedSignalMask(SIG_BLOCK, set));
   676    int sigfd_raw;
   677    ASSERT_THAT(sigfd_raw = signalfd(-1 /* fd */, &set, SFD_NONBLOCK),
   678                SyscallSucceeds());
   679    FileDescriptor sigfd(sigfd_raw);
   680  
   681    auto epollfd = ASSERT_NO_ERRNO_AND_VALUE(NewEpollFD());
   682    ASSERT_NO_ERRNO(RegisterEpollFD(epollfd.get(), sigfd.get(), EPOLLIN, 0));
   683  
   684    // The test passes if this does not deadlock.
   685    constexpr int kIterations = 25000;
   686    auto pid = getpid();
   687    auto tid = gettid();
   688    DisableSave ds;
   689    ScopedThread sender_thread([&] {
   690      for (int i = 0; i < kIterations; i++) {
   691        ASSERT_THAT(tgkill(pid, tid, kSignal), SyscallSucceeds());
   692      }
   693    });
   694    int num_signals = 0;
   695    signalfd_siginfo info;
   696    while (true) {
   697      struct epoll_event ev;
   698      int ret = RetryEINTR(epoll_wait)(epollfd.get(), &ev, 1, 1000 /* timeout */);
   699      ASSERT_THAT(ret, SyscallSucceeds());
   700      if (ret == 0) {
   701        break;
   702      }
   703      ASSERT_THAT(read(sigfd.get(), &info, sizeof(info)),
   704                  SyscallSucceedsWithValue(sizeof(info)));
   705      num_signals++;
   706    }
   707    EXPECT_GT(num_signals, 0);
   708    sender_thread.Join();
   709    // epoll_wait() may have timed out before sender_thread finished executing
   710    // (possible on slower platforms like ptrace), so read from sigfd (which is
   711    // non-blocking) one more time to potentially dequeue the signal before
   712    // unmasking it in cleanup_sigmask's destructor.
   713    read(sigfd.get(), &info, sizeof(info));
   714  }
   715  
   716  }  // namespace
   717  
   718  }  // namespace testing
   719  }  // namespace gvisor