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