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
13int main() {
14 int efd = epoll_create(size: 1);
15 if (efd == -1)
16 exit(status: printf(format: "epoll_create failed: %d\n", errno));
17 int fd = eventfd(count: 0, flags: 0);
18 if (fd == -1)
19 exit(status: printf(format: "eventfd failed: %d\n", errno));
20 epoll_event event = {.events = EPOLLIN | EPOLLET};
21 if (epoll_ctl(epfd: efd, EPOLL_CTL_ADD, fd: fd, event: &event))
22 exit(status: printf(format: "epoll_ctl failed: %d\n", errno));
23 pthread_t th;
24 pthread_create(
25 newthread: &th, attr: nullptr,
26 start_routine: +[](void *arg) -> void * {
27 long long to_add = 1;
28 if (write(fd: (long)arg, buf: &to_add, n: sizeof(to_add)) != sizeof(to_add))
29 exit(status: printf(format: "write failed: %d\n", errno));
30 return nullptr;
31 },
32 arg: (void *)(long)fd);
33 struct epoll_event events[1] = {};
34 if (epoll_wait(epfd: efd, events: events, maxevents: 1, timeout: -1) != 1)
35 exit(status: printf(format: "epoll_wait failed: %d\n", errno));
36 close(fd: fd);
37 pthread_join(th: th, thread_return: nullptr);
38 close(fd: efd);
39 fprintf(stderr, format: "DONE\n");
40}
41
42// CHECK: DONE
43

source code of compiler-rt/test/tsan/Linux/epoll_norace.cpp