Fix tsan failures
diff --git a/src/core/lib/iomgr/ev_epoll_linux.c b/src/core/lib/iomgr/ev_epoll_linux.c
index a8a874c..35a15e0 100644
--- a/src/core/lib/iomgr/ev_epoll_linux.c
+++ b/src/core/lib/iomgr/ev_epoll_linux.c
@@ -236,6 +236,17 @@
 static gpr_mu g_pi_freelist_mu;
 static polling_island *g_pi_freelist = NULL;
 
+#ifdef _GRPC_TSAN
+/* Currently TSAN may incorrectly flag data races between epoll_ctl and
+   epoll_wait for any grpc_fd structs that are added to the epoll set via
+   epoll_ctl and are returned (within a very short window) via epoll_wait().
+
+   To work-around this race, we establish a happens-before relation between
+   the code just-before epoll_ctl() and the code after epoll_wait() by using
+   this atomic */
+gpr_atm g_epoll_sync;
+#endif
+
 /* The caller is expected to hold pi->mu lock before calling this function */
 static void polling_island_add_fds_locked(polling_island *pi, grpc_fd **fds,
                                           size_t fd_count, bool add_fd_refs) {
@@ -243,6 +254,11 @@
   size_t i;
   struct epoll_event ev;
 
+#ifdef _GRPC_TSAN
+  /* See the definition of g_epoll_sync for more context */
+  gpr_atm_rel_store(&g_epoll_sync, 0);
+#endif
+
   for (i = 0; i < fd_count; i++) {
     ev.events = (uint32_t)(EPOLLIN | EPOLLOUT | EPOLLET);
     ev.data.ptr = fds[i];
@@ -361,6 +377,7 @@
   }
 
   pi->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
+
   if (pi->epoll_fd < 0) {
     gpr_log(GPR_ERROR, "epoll_create1() failed with error: %s",
             strerror(errno));
@@ -1144,6 +1161,11 @@
       }
     }
 
+#ifdef _GRPC_TSAN
+    /* See the definition of g_poll_sync for more details */
+    gpr_atm_acq_load(&g_epoll_sync);
+#endif
+
     for (int i = 0; i < ep_rv; ++i) {
       void *data_ptr = ep_ev[i].data.ptr;
       if (data_ptr == &grpc_global_wakeup_fd) {
@@ -1514,10 +1536,13 @@
   return &vtable;
 }
 
-#else  /* defined(GPR_LINUX_EPOLL) */
+#else /* defined(GPR_LINUX_EPOLL) */
+#if defined(GPR_POSIX_SOCKET)
+#include "src/core/lib/iomgr/ev_posix.h"
 /* If GPR_LINUX_EPOLL is not defined, it means epoll is not available. Return
  * NULL */
 const grpc_event_engine_vtable *grpc_init_epoll_linux(void) { return NULL; }
+#endif /* defined(GPR_POSIX_SOCKET) */
 
 void grpc_use_signal(int signum) {}
 #endif /* !defined(GPR_LINUX_EPOLL) */