}
 
        ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_GET_FD, &sd );
+       slapd_sd_lock();
+       ber_sockbuf_free( c->c_sb );
        if ( sd != AC_SOCKET_INVALID ) {
-               slapd_remove( sd, 1, 0 );
+               slapd_remove( sd, 1, 0, 1 );
 
                Statslog( LDAP_DEBUG_STATS, (close_reason
                                                                         ? "conn=%lu fd=%ld closed (%s)\n"
                                                                         : "conn=%lu fd=%ld closed\n"),
                        connid, (long) sd, close_reason, 0, 0 );
+       } else {
+               slapd_sd_unlock();
        }
 
-       ber_sockbuf_free( c->c_sb );
-
        c->c_sb = ber_sockbuf_alloc( );
 
        {
        c->c_conn_state = SLAP_C_INVALID;
        c->c_struct_state = SLAP_C_UNUSED;
        c->c_close_reason = "?";                        /* should never be needed */
+       slapd_sd_lock();
        ber_sockbuf_free( c->c_sb );
        c->c_sb = ber_sockbuf_alloc( );
        {
                ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_SET_MAX_INCOMING, &max );
        }
 
-       slapd_remove( s, 0, 1 );
+       slapd_remove( s, 0, 1, 1 );
        connection_return( c );
 }
 
         * the first one is returned with new_op
         */
        if( ( rc = connection_read( s, &new_op ) ) < 0 ) {
-               Debug( LDAP_DEBUG_TRACE, "connection_read(%d) error\n", s, 0, 0 );
-               tcp_close( s );
+               Debug( LDAP_DEBUG_CONNS, "connection_read(%d) error\n", s, 0, 0 );
                return (void*)(long)rc;
        }
 
        /* execute the queued request in the same thread */
        if( new_op ) {
-               rc = (long)connection_operation(
-                       ldap_pvt_thread_pool_context(), new_op );
+               rc = (long)connection_operation( ctx, new_op );
        }
 
        return (void*)(long)rc;
         * thread reads data on it. Otherwise the listener thread will repeatedly
         * submit the same event on it to the pool.
         */
-       slapd_clr_read( s, 0 );
+       rc = slapd_clr_read( s, 0 );
+       if ( rc )
+               return rc;
 
        rc = ldap_pvt_thread_pool_submit( &connection_pool,
                connection_read_thread, (void *)(long)s );
                Debug( LDAP_DEBUG_ANY,
                        "connection_read(%ld): no connection!\n",
                        (long) s, 0, 0 );
-               slapd_remove(s, 1, 0);
 
                ldap_pvt_thread_mutex_unlock( MCA_GET_CONN_MUTEX(s) );
                return -1;
                Debug( LDAP_DEBUG_ANY,
                        "connection_write(%ld): no connection!\n",
                        (long)s, 0, 0 );
-               slapd_remove(s, 1, 0);
                ldap_pvt_thread_mutex_unlock( MCA_GET_CONN_MUTEX( s ) );
                return -1;
        }
 
 #endif
 }
 
+void slapd_sd_lock()
+{
+       ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
+}
+
+void slapd_sd_unlock()
+{
+       ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
+}
+
 /*
  * Remove the descriptor from daemon control
  */
 void slapd_remove(
        ber_socket_t s,
        int wasactive,
-       int wake )
+       int wake,
+       int locked )
 {
        int waswriter;
        int wasreader;
 
-       ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
+       if ( !locked )
+               ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
+
+       assert( SLAP_SOCK_IS_ACTIVE( s ));
 
        if ( wasactive ) slap_daemon.sd_nactives--;
 
        WAKE_LISTENER(wake);
 }
 
-void slapd_clr_read(ber_socket_t s, int wake) {
+int slapd_clr_read(ber_socket_t s, int wake) {
+       int rc = 1;
        ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
 
-       assert( SLAP_SOCK_IS_ACTIVE( s ));
-       SLAP_SOCK_CLR_READ( s );
-
+       if ( SLAP_SOCK_IS_ACTIVE( s )) {
+               SLAP_SOCK_CLR_READ( s );
+               rc = 0;
+       }
        ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
-       WAKE_LISTENER(wake);
+       if ( !rc )
+               WAKE_LISTENER(wake);
+       return rc;
 }
 
 void slapd_set_read(ber_socket_t s, int wake) {
                Listener *lr = slap_listeners[l];
 
                if ( lr->sl_sd != AC_SOCKET_INVALID ) {
-                       if ( remove ) slapd_remove( lr->sl_sd, 0, 0 );
+                       if ( remove ) slapd_remove( lr->sl_sd, 0, 0, 0 );
 
 #ifdef LDAP_PF_LOCAL
                        if ( lr->sl_sa.sa_addr.sa_family == AF_LOCAL ) {
 
 LDAP_SLAPD_F (int) slapd_daemon_destroy(void);
 LDAP_SLAPD_F (int) slapd_daemon(void);
 LDAP_SLAPD_F (Listener **)     slapd_get_listeners LDAP_P((void));
-LDAP_SLAPD_F (void) slapd_remove LDAP_P((ber_socket_t s, int wasactive, int wake));
+LDAP_SLAPD_F (void) slapd_remove LDAP_P((ber_socket_t s, int wasactive,
+       int wake, int locked ));
+LDAP_SLAPD_F (void) slapd_sd_lock();
+LDAP_SLAPD_F (void) slapd_sd_unlock();
 
 LDAP_SLAPD_F (RETSIGTYPE) slap_sig_shutdown LDAP_P((int sig));
 LDAP_SLAPD_F (RETSIGTYPE) slap_sig_wake LDAP_P((int sig));
 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_set_read LDAP_P((ber_socket_t s, int wake));
-LDAP_SLAPD_F (void) slapd_clr_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_V (volatile sig_atomic_t) slapd_abrupt_shutdown;
 LDAP_SLAPD_V (volatile sig_atomic_t) slapd_shutdown;