+#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)
+
+# ifdef SLAP_LIGHTWEIGHT_DISPATCHER
+# define SLAP_SOCK_SET_SUSPEND(s) \
+ ( slap_daemon.sd_suspend[SLAP_SOCK_IX(s)] = 1 )
+# define SLAP_SOCK_CLR_SUSPEND(s) \
+ ( slap_daemon.sd_suspend[SLAP_SOCK_IX(s)] = 0 )
+# define SLAP_SOCK_IS_SUSPEND(s) \
+ ( slap_daemon.sd_suspend[SLAP_SOCK_IX(s)] == 1 )
+# endif
+
+# 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,fd=%d) failed, errno=%d, shutting down\n", \
+ s, errno, 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)); \
+ if ( index < 0 ) break; \
+ 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) ((Listener *)(revents[(i)].data.ptr))
+
+# define SLAP_EVENT_FD(i) SLAP_EV_PTRFD(revents[(i)].data.ptr)
+
+# define SLAP_SOCK_SET_INIT do { \
+ slap_daemon.sd_epolls = ch_calloc(1, \
+ 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; \
+} while (0)
+
+# define SLAP_EVENT_DECL struct epoll_event *revents
+
+# define SLAP_EVENT_INIT do { \
+ revents = slap_daemon.sd_epolls + dtblsize; \
+} while (0)
+
+# 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 do { \
+ AC_MEMCPY( &readfds, &slap_daemon.sd_readers, sizeof(fd_set) ); \
+ if ( nwriters ) { \
+ AC_MEMCPY( &writefds, &slap_daemon.sd_writers, sizeof(fd_set) ); \
+ } else { \
+ FD_ZERO( &writefds ); \
+ } \
+} while (0)
+
+# ifdef FD_SETSIZE
+# define CHK_SETSIZE do { \
+ if (dtblsize > FD_SETSIZE) dtblsize = FD_SETSIZE; \
+} while (0)
+# else
+# define CHK_SETSIZE do { ; } while (0)
+# endif
+
+# define SLAP_SOCK_SET_INIT do { \
+ CHK_SETSIZE; \
+ FD_ZERO(&slap_daemon.sd_readers); \
+ FD_ZERO(&slap_daemon.sd_writers); \
+} while (0)
+
+# 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) do { \
+ if ((s) >= slap_daemon.sd_nfds) slap_daemon.sd_nfds = (s)+1; \
+} while (0)
+# 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) )
+#endif