xref: /llvm-project/compiler-rt/test/tsan/Linux/epoll_norace.cpp (revision 16baf59c6d0b3bf7392995e3e55fc9e2ba9cb5e7)
1 // RUN: %clangxx_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
2 
3 // The test captures what some high-performance networking servers do.
4 // One thread writes to an fd, and another just receives an epoll
5 // notification about the write to synchronize with the first thread
6 // w/o actually reading from the fd.
7 
8 #include "../test.h"
9 #include <errno.h>
10 #include <sys/epoll.h>
11 #include <sys/eventfd.h>
12 
main()13 int main() {
14   int efd = epoll_create(1);
15   if (efd == -1)
16     exit(printf("epoll_create failed: %d\n", errno));
17   int fd = eventfd(0, 0);
18   if (fd == -1)
19     exit(printf("eventfd failed: %d\n", errno));
20   epoll_event event = {.events = EPOLLIN | EPOLLET};
21   if (epoll_ctl(efd, EPOLL_CTL_ADD, fd, &event))
22     exit(printf("epoll_ctl failed: %d\n", errno));
23   pthread_t th;
24   pthread_create(
25       &th, nullptr,
26       +[](void *arg) -> void * {
27         long long to_add = 1;
28         if (write((long)arg, &to_add, sizeof(to_add)) != sizeof(to_add))
29           exit(printf("write failed: %d\n", errno));
30         return nullptr;
31       },
32       (void *)(long)fd);
33   struct epoll_event events[1] = {};
34   if (epoll_wait(efd, events, 1, -1) != 1)
35     exit(printf("epoll_wait failed: %d\n", errno));
36   close(fd);
37   pthread_join(th, nullptr);
38   close(efd);
39   fprintf(stderr, "DONE\n");
40 }
41 
42 // CHECK: DONE
43