/***************************************
  * Use epoll infrastructure - epoll(4) *
  ***************************************/
+
+#undef SLAP_EVENT_ACK          /* events trigger once per descriptor */
+
 # define SLAP_EVENT_FNAME              "epoll"
 # define SLAP_EVENTS_ARE_INDEXED       0
 # define SLAP_EPOLL_SOCK_IX(s)         (slap_daemon.sd_index[(s)])
        int rc; \
        SLAP_EPOLL_SOCK_IX((s)) = slap_daemon.sd_nfds; \
        SLAP_EPOLL_SOCK_EP((s)).data.ptr = (l) ? (l) : (void *)(&SLAP_EPOLL_SOCK_IX(s)); \
-       SLAP_EPOLL_SOCK_EV((s)) = EPOLLIN; \
+       SLAP_EPOLL_SOCK_EV((s)) = EPOLLIN|EPOLLET; \
        rc = epoll_ctl(slap_daemon.sd_epfd, EPOLL_CTL_ADD, \
                (s), &SLAP_EPOLL_SOCK_EP((s))); \
        if ( rc == 0 ) { \
 } while (0)
 
 #elif defined(SLAP_X_DEVPOLL) && defined(HAVE_DEVPOLL)
-
 /*************************************************************
  * Use Solaris' (>= 2.7) /dev/poll infrastructure - poll(7d) *
  *************************************************************/
+
+#define SLAP_EVENT_ACK 1       /* events keep signalling unless we stop them */
+
 # define SLAP_EVENT_FNAME              "/dev/poll"
 # define SLAP_EVENTS_ARE_INDEXED       0
 /*
 } while (0)
 
 #else /* ! epoll && ! /dev/poll */
+
+#define SLAP_EVENT_ACK 1       /* events keep signalling unless we stop them */
+
 # ifdef HAVE_WINSOCK
 # define SLAP_EVENT_FNAME              "WSselect"
 /* Winsock provides a "select" function but its fd_sets are
        WAKE_LISTENER(wake || slapd_gentle_shutdown == 2);
 }
 
+void
+slapd_ack_write( ber_socket_t s, int wake )
+{
+#ifdef SLAP_EVENT_ACK
+       ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
+
+       if ( SLAP_SOCK_IS_WRITE( s )) {
+               assert( SLAP_SOCK_IS_ACTIVE( s ));
+
+               SLAP_SOCK_CLR_WRITE( s );
+               slap_daemon.sd_nwriters--;
+       }
+
+       ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
+#endif
+       WAKE_LISTENER(wake);
+}
+
 void
 slapd_clr_write( ber_socket_t s, int wake )
 {
        WAKE_LISTENER(wake);
 }
 
+int
+slapd_ack_read( ber_socket_t s, int wake )
+{
+#ifdef SLAP_EVENT_ACK
+       int rc = 1;
+       ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
+
+       if ( SLAP_SOCK_IS_ACTIVE( s )) {
+               SLAP_SOCK_CLR_READ( s );
+               rc = 0;
+       }
+       ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
+       if ( !rc )
+               WAKE_LISTENER(wake);
+       return rc;
+#else
+       return 0;
+#endif
+}
+
 int
 slapd_clr_read( ber_socket_t s, int wake )
 {
                                        char c[BUFSIZ];
                                        waking = 0;
                                        tcp_read( SLAP_FD2SOCK(wake_sds[0]), c, sizeof(c) );
-                                       break;
+                                       continue;
                                }
 
                                if ( SLAP_EVENT_IS_WRITE( i ) ) {
 
 
 LDAP_SLAPD_F (void) slapd_set_write LDAP_P((ber_socket_t s, int wake));
 LDAP_SLAPD_F (void) slapd_clr_write LDAP_P((ber_socket_t s, int wake));
+LDAP_SLAPD_F (void) slapd_ack_write LDAP_P((ber_socket_t s, int wake));
 LDAP_SLAPD_F (void) slapd_set_read LDAP_P((ber_socket_t s, int wake));
 LDAP_SLAPD_F (int) slapd_clr_read LDAP_P((ber_socket_t s, int wake));
+LDAP_SLAPD_F (int) slapd_ack_read LDAP_P((ber_socket_t s, int wake));
 
 LDAP_SLAPD_V (volatile sig_atomic_t) slapd_abrupt_shutdown;
 LDAP_SLAPD_V (volatile sig_atomic_t) slapd_shutdown;