+#ifdef HAVE_EPOLL
+#define SLAP_EVENTS_ARE_INDEXED 0
+#define SLAP_SOCK_IX(s) (slap_daemon.sd_index[s])
+#define SLAP_SOCK_EP(s) (slap_daemon.sd_epolls[SLAP_SOCK_IX(s)])
+#define SLAP_SOCK_EV(s) (SLAP_SOCK_EP(s).events)
+#define SLAP_SOCK_IS_ACTIVE(s) (SLAP_SOCK_IX(s) != -1)
+#define SLAP_SOCK_NOT_ACTIVE(s) (SLAP_SOCK_IX(s) == -1)
+#define SLAP_SOCK_IS_SET(s, mode) (SLAP_SOCK_EV(s) & mode)
+
+#define SLAP_SOCK_IS_READ(s) SLAP_SOCK_IS_SET(s, EPOLLIN)
+#define SLAP_SOCK_IS_WRITE(s) SLAP_SOCK_IS_SET(s, EPOLLOUT)
+
+#define SLAP_SET_SOCK(s, mode) do { \
+ if ((SLAP_SOCK_EV(s) & mode) != mode) { \
+ SLAP_SOCK_EV(s) |= mode; \
+ epoll_ctl(slap_daemon.sd_epfd, EPOLL_CTL_MOD, s, \
+ &SLAP_SOCK_EP(s)); \
+ } \
+} while(0)
+
+#define SLAP_CLR_SOCK(s, mode) do { \
+ if ((SLAP_SOCK_EV(s) & mode)) { \
+ SLAP_SOCK_EV(s) &= ~mode; \
+ epoll_ctl(slap_daemon.sd_epfd, EPOLL_CTL_MOD, s, \
+ &SLAP_SOCK_EP(s)); \
+ } \
+} while(0)
+
+#define SLAP_SOCK_SET_READ(s) SLAP_SET_SOCK(s, EPOLLIN)
+#define SLAP_SOCK_SET_WRITE(s) SLAP_SET_SOCK(s, EPOLLOUT)
+
+#define SLAP_SOCK_CLR_READ(s) SLAP_CLR_SOCK(s, EPOLLIN)
+#define SLAP_SOCK_CLR_WRITE(s) SLAP_CLR_SOCK(s, EPOLLOUT)
+
+#define SLAP_CLR_EVENT(i, mode) (revents[i].events &= ~mode)
+
+
+#define SLAP_EVENT_MAX slap_daemon.sd_nfds
+
+/* If a Listener address is provided, store that as the epoll data.
+ * Otherwise, store the address of this socket's slot in the
+ * index array. If we can't do this add, the system is out of
+ * resources and we need to shutdown.
+ */
+#define SLAP_ADD_SOCK(s, l) do { \
+ int rc; \
+ SLAP_SOCK_IX(s) = slap_daemon.sd_nfds; \
+ SLAP_SOCK_EP(s).data.ptr = (l) ? (l) : (void *)(&SLAP_SOCK_IX(s)); \
+ SLAP_SOCK_EV(s) = EPOLLIN; \
+ rc = epoll_ctl(slap_daemon.sd_epfd, EPOLL_CTL_ADD, s, \
+ &SLAP_SOCK_EP(s)); \
+ if ( rc == 0 ) slap_daemon.sd_nfds++; \
+ else { \
+ Debug( LDAP_DEBUG_ANY, "daemon: epoll_ctl ADD failed, errno %d, shutting down\n", \
+ errno, 0, 0 ); \
+ slapd_shutdown = 2; \
+ } \
+} while(0)
+
+#define SLAP_EV_LISTENER(ptr) (((int *)(ptr) >= slap_daemon.sd_index && \
+ (int *)(ptr) <= (slap_daemon.sd_index+dtblsize)) ? 0 : 1)
+
+#define SLAP_EV_PTRFD(ptr) (SLAP_EV_LISTENER(ptr) ? \
+ ((Listener *)ptr)->sl_sd : (int *)(ptr) - slap_daemon.sd_index)
+
+#define SLAP_DEL_SOCK(s) do { \
+ int fd, rc, index = SLAP_SOCK_IX(s); \
+ rc = epoll_ctl(slap_daemon.sd_epfd, EPOLL_CTL_DEL, s, \
+ &SLAP_SOCK_EP(s)); \
+ slap_daemon.sd_epolls[index] = slap_daemon.sd_epolls[slap_daemon.sd_nfds-1]; \
+ fd = SLAP_EV_PTRFD(slap_daemon.sd_epolls[index].data.ptr); \
+ slap_daemon.sd_index[fd] = index; \
+ slap_daemon.sd_index[s] = -1; \
+ slap_daemon.sd_nfds--; \
+} while(0)
+
+#define SLAP_EVENT_CLR_READ(i) SLAP_CLR_EVENT(i, EPOLLIN)
+#define SLAP_EVENT_CLR_WRITE(i) SLAP_CLR_EVENT(i, EPOLLOUT)
+
+#define SLAP_CHK_EVENT(i, mode) (revents[i].events & mode)
+
+#define SLAP_EVENT_IS_READ(i) SLAP_CHK_EVENT(i, EPOLLIN)
+#define SLAP_EVENT_IS_WRITE(i) SLAP_CHK_EVENT(i, EPOLLOUT)
+#define SLAP_EVENT_IS_LISTENER(i) SLAP_EV_LISTENER(revents[i].data.ptr)
+#define SLAP_EVENT_LISTENER(i) (revents[i].data.ptr)
+
+#define SLAP_EVENT_FD(i) SLAP_EV_PTRFD(revents[i].data.ptr)
+#define SLAP_SOCK_SET_MUTE(s) SLAP_SOCK_CLR_READ(s)
+#define SLAP_SOCK_CLR_MUTE(s) SLAP_SOCK_SET_READ(s)
+#define SLAP_SOCK_IS_MUTE(s) !SLAP_SOCK_IS_READ(s)
+
+#define SLAP_SOCK_SET_INIT \
+ slap_daemon.sd_epolls = ch_malloc(sizeof(struct epoll_event) * dtblsize * 2); \
+ slap_daemon.sd_index = ch_malloc(sizeof(int) * dtblsize); \
+ slap_daemon.sd_epfd = epoll_create( dtblsize ); \
+ for (i=0; i<dtblsize; i++) slap_daemon.sd_index[i] = -1
+
+
+#define SLAP_EVENT_DECL \
+ struct epoll_event *revents
+
+#define SLAP_EVENT_INIT \
+ revents = slap_daemon.sd_epolls + dtblsize; \
+
+#define SLAP_EVENT_WAIT(tvp) \
+ epoll_wait( slap_daemon.sd_epfd, revents, dtblsize, tvp ? tvp->tv_sec * 1000 : -1 )
+
+#else
+
+/* select */
+#define SLAP_EVENTS_ARE_INDEXED 1
+#define SLAP_EVENT_DECL \
+ fd_set readfds, writefds
+
+#define SLAP_EVENT_INIT \
+ AC_MEMCPY( &readfds, &slap_daemon.sd_readers, sizeof(fd_set) ); \
+ if ( nwriters ) \
+ AC_MEMCPY( &writefds, &slap_daemon.sd_writers, sizeof(fd_set) )
+
+#ifdef FD_SETSIZE
+#define CHK_SETSIZE \
+ if (dtblsize > FD_SETSIZE) dtblsize = FD_SETSIZE
+#else
+#define CHK_SETSIZE
+#endif
+
+#define SLAP_SOCK_SET_INIT \
+ CHK_SETSIZE; \
+ FD_ZERO(&slap_daemon.sd_readers); \
+ FD_ZERO(&slap_daemon.sd_writers)
+
+#define SLAP_SOCK_IS_ACTIVE(fd) FD_ISSET(fd, &slap_daemon.sd_actives)
+
+#define SLAP_SOCK_IS_READ(fd) FD_ISSET(fd, &slap_daemon.sd_readers)
+#define SLAP_SOCK_IS_WRITE(fd) FD_ISSET(fd, &slap_daemon.sd_writers)
+
+#define SLAP_SOCK_NOT_ACTIVE(fd) (!SLAP_SOCK_IS_ACTIVE(fd) && \
+ !SLAP_SOCK_IS_READ(fd) && !SLAP_SOCK_IS_WRITE(fd))
+
+#ifdef HAVE_WINSOCK
+#define SLAP_SOCK_SET_READ(fd) do { \
+ if (!SLAP_SOCK_IS_READ(fd)) {FD_SET(fd, &slap_daemon.sd_readers);} \
+} while(0)
+#define SLAP_SOCK_SET_WRITE(fd) do { \
+ if (!SLAP_SOCK_IS_WRITE(fd)) {FD_SET(fd, &slap_daemon.sd_writers);} \
+} while(0)
+
+#define SLAP_ADDTEST(s)
+#define SLAP_EVENT_MAX dtblsize
+#else
+#define SLAP_SOCK_SET_READ(fd) FD_SET(fd, &slap_daemon.sd_readers)
+#define SLAP_SOCK_SET_WRITE(fd) FD_SET(fd, &slap_daemon.sd_writers)
+
+#define SLAP_EVENT_MAX slap_daemon.sd_nfds
+#define SLAP_ADDTEST(s) if (s >= slap_daemon.sd_nfds) slap_daemon.sd_nfds = s+1
+#endif
+
+#define SLAP_SOCK_CLR_READ(fd) FD_CLR(fd, &slap_daemon.sd_readers)
+#define SLAP_SOCK_CLR_WRITE(fd) FD_CLR(fd, &slap_daemon.sd_writers)
+
+#define SLAP_ADD_SOCK(s, l) do { \
+ SLAP_ADDTEST(s); \
+ FD_SET(s, &slap_daemon.sd_actives); \
+ FD_SET(s, &slap_daemon.sd_readers); \
+} while(0)
+
+#define SLAP_DEL_SOCK(s) do { \
+ FD_CLR(s, &slap_daemon.sd_actives); \
+ FD_CLR(s, &slap_daemon.sd_readers); \
+ FD_CLR(s, &slap_daemon.sd_writers); \
+} while(0)
+
+#define SLAP_EVENT_IS_READ(fd) FD_ISSET(fd, &readfds)
+#define SLAP_EVENT_IS_WRITE(fd) FD_ISSET(fd, &writefds)
+
+#define SLAP_EVENT_CLR_READ(fd) FD_CLR(fd, &readfds)
+#define SLAP_EVENT_CLR_WRITE(fd) FD_CLR(fd, &writefds)
+
+#define SLAP_EVENT_WAIT(tvp) \
+ select( SLAP_EVENT_MAX, &readfds, \
+ nwriters > 0 ? &writefds : NULL, NULL, tvp )
+
+#define SLAP_SOCK_SET_MUTE(s) FD_CLR(s, &readfds)
+#define SLAP_SOCK_CLR_MUTE(s) FD_SET(s, &readfds)
+#define SLAP_SOCK_IS_MUTE(s) FD_ISSET(s, &readfds)
+
+#endif