]> git.sur5r.net Git - openldap/commitdiff
Use per-thread slap_counters to eliminate lock contention
authorQuanah Gibson-Mount <quanah@openldap.org>
Wed, 7 Nov 2007 21:58:37 +0000 (21:58 +0000)
committerQuanah Gibson-Mount <quanah@openldap.org>
Wed, 7 Nov 2007 21:58:37 +0000 (21:58 +0000)
Unifdef SLAP_LIGHTWEIGHT_DISPATCHER
Use thread-specific data in pool_context()
Added native thread-specific data support
Concurrency tweaks:
  store conn->c_sd, don't use ber_sockbuf_ctrl to retrieve it.
  use per-thread free lists for operations, no mutexes needed.

20 files changed:
include/ldap_int_thread.h
include/ldap_pvt_thread.h
libraries/libldap_r/thr_cthreads.c
libraries/libldap_r/thr_nt.c
libraries/libldap_r/thr_posix.c
libraries/libldap_r/thr_pth.c
libraries/libldap_r/thr_stub.c
libraries/libldap_r/thr_thr.c
libraries/libldap_r/tpool.c
servers/slapd/abandon.c
servers/slapd/back-monitor/operation.c
servers/slapd/back-monitor/sent.c
servers/slapd/cancel.c
servers/slapd/connection.c
servers/slapd/daemon.c
servers/slapd/init.c
servers/slapd/operation.c
servers/slapd/proto-slap.h
servers/slapd/result.c
servers/slapd/slap.h

index d6a6d779575564762c1c324635562ea9acfcb270..db345df06dedd639b25526d04991cc92ae120d59 100644 (file)
@@ -44,6 +44,7 @@ LDAP_BEGIN_DECL
 typedef pthread_t              ldap_int_thread_t;
 typedef pthread_mutex_t                ldap_int_thread_mutex_t;
 typedef pthread_cond_t         ldap_int_thread_cond_t;
+typedef pthread_key_t          ldap_int_thread_key_t;
 
 #define ldap_int_thread_equal(a, b)    pthread_equal((a), (b))
 
@@ -88,6 +89,7 @@ LDAP_BEGIN_DECL
 typedef cthread_t              ldap_int_thread_t;
 typedef struct mutex           ldap_int_thread_mutex_t;
 typedef struct condition       ldap_int_thread_cond_t;
+typedef cthread_key_t          ldap_int_thread_key_t;
 
 LDAP_END_DECL
 
@@ -106,6 +108,7 @@ LDAP_BEGIN_DECL
 typedef pth_t          ldap_int_thread_t;
 typedef pth_mutex_t    ldap_int_thread_mutex_t;
 typedef pth_cond_t     ldap_int_thread_cond_t;
+typedef pth_key_t      ldap_int_thread_key_t;
 
 #if 0
 #define LDAP_THREAD_HAVE_RDWR 1
@@ -129,6 +132,7 @@ LDAP_BEGIN_DECL
 typedef thread_t               ldap_int_thread_t;
 typedef mutex_t                        ldap_int_thread_mutex_t;
 typedef cond_t                 ldap_int_thread_cond_t;
+typedef thread_key_t   ldap_int_thread_key_t;
 
 #define HAVE_REENTRANT_FUNCTIONS 1
 
@@ -181,6 +185,7 @@ LDAP_BEGIN_DECL
 typedef unsigned long  ldap_int_thread_t;
 typedef HANDLE ldap_int_thread_mutex_t;
 typedef HANDLE ldap_int_thread_cond_t;
+typedef DWORD  ldap_int_thread_key_t;
 
 LDAP_END_DECL
 
@@ -201,6 +206,7 @@ LDAP_BEGIN_DECL
 typedef int                    ldap_int_thread_t;
 typedef int                    ldap_int_thread_mutex_t;
 typedef int                    ldap_int_thread_cond_t;
+typedef int                    ldap_int_thread_key_t;
 
 #define LDAP_THREAD_HAVE_TPOOL 1
 typedef int                    ldap_int_thread_pool_t;
index 151756d692a03690537699f3e3f3ec709e6f1af6..21b2dc69cdf3affcca2b2db47d5ed4404b06c3bc 100644 (file)
@@ -34,6 +34,7 @@ typedef ldap_int_thread_cond_t                ldap_pvt_thread_cond_t;
 typedef ldap_int_thread_rdwr_t         ldap_pvt_thread_rdwr_t;
 #endif
 typedef ldap_int_thread_rmutex_t       ldap_pvt_thread_rmutex_t;
+typedef ldap_int_thread_key_t  ldap_pvt_thread_key_t;
 #endif /* !LDAP_PVT_THREAD_H_DONE */
 
 #define ldap_pvt_thread_equal          ldap_int_thread_equal
@@ -169,6 +170,18 @@ ldap_pvt_thread_rdwr_wtrylock LDAP_P((ldap_pvt_thread_rdwr_t *rdwrp));
 LDAP_F( int )
 ldap_pvt_thread_rdwr_wunlock LDAP_P((ldap_pvt_thread_rdwr_t *rdwrp));
 
+LDAP_F( int )
+ldap_pvt_thread_key_create LDAP_P((ldap_pvt_thread_key_t *keyp));
+
+LDAP_F( int )
+ldap_pvt_thread_key_destroy LDAP_P((ldap_pvt_thread_key_t key));
+
+LDAP_F( int )
+ldap_pvt_thread_key_setdata LDAP_P((ldap_pvt_thread_key_t key, void *data));
+
+LDAP_F( int )
+ldap_pvt_thread_key_getdata LDAP_P((ldap_pvt_thread_key_t key, void **data));
+
 #ifdef LDAP_DEBUG
 LDAP_F( int )
 ldap_pvt_thread_rdwr_readers LDAP_P((ldap_pvt_thread_rdwr_t *rdwrp));
index b98a47afa2caa28f736207e6a19a7faa6c73e84f..ab19880bb77d3f18c90b5df31336bf01f6519be4 100644 (file)
@@ -153,4 +153,28 @@ ldap_pvt_thread_self( void )
        return cthread_self();
 }
 
+int
+ldap_pvt_thread_key_create( ldap_pvt_thread_key_t *key )
+{
+       return cthread_keycreate( key );
+}
+
+int
+ldap_pvt_thread_key_destroy( ldap_pvt_thread_key_t key )
+{
+       return( 0 );
+}
+
+int
+ldap_pvt_thread_key_setdata( ldap_pvt_thread_key_t key, void *data )
+{
+       return cthread_setspecific( key, data );
+}
+
+int
+ldap_pvt_thread_key_getdata( ldap_pvt_thread_key_t key, void **data )
+{
+       return cthread_getspecific( key, data );
+}
+
 #endif /* HAVE_MACH_CTHREADS */
index f3d0755de99941f3a78f237b3c40a6d4349c9330..29416fa85e0071b2f6915987bd27d0608d1dcc97 100644 (file)
@@ -198,4 +198,37 @@ ldap_pvt_thread_self( void )
        return GetCurrentThreadId();
 }
 
+int
+ldap_pvt_thread_key_create( ldap_pvt_thread_key_t *keyp )
+{
+       DWORD key = TlsAlloc();
+       if ( key != TLS_OUT_OF_INDEXES ) {
+               *keyp = key;
+               return 0;
+       } else {
+               return -1;
+       }
+}
+
+int
+ldap_pvt_thread_key_destroy( ldap_pvt_thread_key_t key )
+{
+       /* TlsFree returns 0 on failure */
+       return( TlsFree( key ) == 0 );
+}
+
+int
+ldap_pvt_thread_key_setdata( ldap_pvt_thread_key_t key, void *data )
+{
+       return ( TlsSetValue( key, data ) == 0 );
+}
+
+int
+ldap_pvt_thread_key_getdata( ldap_pvt_thread_key_t key, void **data )
+{
+       void *ptr = TlsGetValue( key );
+       *data = ptr;
+       return( ptr ? GetLastError() : 0 );
+}
+
 #endif
index 4e0a45b4321b44872a5b8f20915ce6fd1341288f..34914b626f959e7454821ecd111e991b8f4f7383 100644 (file)
@@ -312,6 +312,31 @@ ldap_pvt_thread_t ldap_pvt_thread_self( void )
        return pthread_self();
 }
 
+int
+ldap_pvt_thread_key_create( ldap_pvt_thread_key_t *key )
+{
+       return pthread_key_create( key, NULL );
+}
+
+int
+ldap_pvt_thread_key_destroy( ldap_pvt_thread_key_t key )
+{
+       return pthread_key_delete( key );
+}
+
+int
+ldap_pvt_thread_key_setdata( ldap_pvt_thread_key_t key, void *data )
+{
+       return pthread_setspecific( key, data );
+}
+
+int
+ldap_pvt_thread_key_getdata( ldap_pvt_thread_key_t key, void **data )
+{
+       *data = pthread_getspecific( key );
+       return 0;
+}
+
 #ifdef LDAP_THREAD_HAVE_RDWR
 #ifdef HAVE_PTHREAD_RWLOCK_DESTROY
 int 
index c5844533c12da13974e8ecb9ed13b651c0240ab2..f06efe0d130730637c29e3a188e3b6209abecca6 100644 (file)
@@ -159,6 +159,31 @@ ldap_pvt_thread_self( void )
        return pth_self();
 }
 
+int
+ldap_pvt_thread_key_create( ldap_pvt_thread_key_t *key )
+{
+       return pth_key_create( key, NULL );
+}
+
+int
+ldap_pvt_thread_key_destroy( ldap_pvt_thread_key_t key )
+{
+       return pth_key_delete( key );
+}
+
+int
+ldap_pvt_thread_key_setdata( ldap_pvt_thread_key_t key, void *data )
+{
+       return pth_key_setdata( key, data );
+}
+
+int
+ldap_pvt_thread_key_getdata( ldap_pvt_thread_key_t key, void **data )
+{
+       *data = pth_key_getdata( key );
+       return 0;
+}
+
 #ifdef LDAP_THREAD_HAVE_RDWR
 int 
 ldap_pvt_thread_rdwr_init( ldap_pvt_thread_rdwr_t *rw )
index 1dce9d160be0f08a4796bd01e2537fd73b2c8bb5..65a18bd0ac1bb919b21b01a78ec3db1fbbd3f4c4 100644 (file)
@@ -237,6 +237,30 @@ ldap_pvt_thread_self( void )
        return(0);
 }
 
+int
+ldap_pvt_thread_key_create( ldap_pvt_thread_key_t *key )
+{
+       return(0);
+}
+
+int
+ldap_pvt_thread_key_destroy( ldap_pvt_thread_key_t key )
+{
+       return(0);
+}
+
+int
+ldap_pvt_thread_key_setdata( ldap_pvt_thread_key_t key, void *data )
+{
+       return(0);
+}
+
+int
+ldap_pvt_thread_key_getdata( ldap_pvt_thread_key_t key, void **data )
+{
+       return(0);
+}
+
 ldap_pvt_thread_t
 ldap_pvt_thread_pool_tid( void *vctx )
 {
index 2acbe083a64978566581134e46a507defc2dbe5e..2a9abae5454f160180ad822b0a03698df0dadb44 100644 (file)
@@ -159,4 +159,28 @@ ldap_pvt_thread_self( void )
        return thr_self();
 }
 
+int
+ldap_pvt_thread_key_create( ldap_pvt_thread_key_t *key )
+{
+       return thr_keycreate( key, NULL );
+}
+
+int
+ldap_pvt_thread_key_destroy( ldap_pvt_thread_key_t key )
+{
+       return( 0 );
+}
+
+int
+ldap_pvt_thread_key_setdata( ldap_pvt_thread_key_t key, void *data )
+{
+       return thr_setspecific( key, data );
+}
+
+int
+ldap_pvt_thread_key_getdata( ldap_pvt_thread_key_t key, void **data )
+{
+       return thr_getspecific( key, data );
+}
+
 #endif /* HAVE_THR */
index 6e3d81b3b2d18b99d0f5ae903277870e0827f747..81ebd92ed63b5d59a0a393a429298d1ce980cd7f 100644 (file)
@@ -38,11 +38,11 @@ typedef enum ldap_int_thread_pool_state_e {
 } ldap_int_thread_pool_state_t;
 
 /* Thread-specific key with data and optional free function */
-typedef struct ldap_int_thread_key_s {
+typedef struct ldap_int_tpool_key_s {
        void *ltk_key;
        void *ltk_data;
        ldap_pvt_thread_pool_keyfree_t *ltk_free;
-} ldap_int_thread_key_t;
+} ldap_int_tpool_key_t;
 
 /* Max number of thread-specific keys we store per thread.
  * We don't expect to use many...
@@ -55,7 +55,7 @@ typedef struct ldap_int_thread_key_s {
 /* Context: thread ID and thread-specific key/data pairs */
 typedef struct ldap_int_thread_userctx_s {
        ldap_pvt_thread_t ltu_id;
-       ldap_int_thread_key_t ltu_key[MAXKEYS];
+       ldap_int_tpool_key_t ltu_key[MAXKEYS];
 } ldap_int_thread_userctx_t;
 
 
@@ -126,6 +126,8 @@ static ldap_pvt_thread_mutex_t ldap_pvt_thread_pool_mutex;
 
 static void *ldap_int_thread_pool_wrapper( void *pool );
 
+static ldap_pvt_thread_key_t   ldap_tpool_key;
+
 /* Context of the main thread */
 static ldap_int_thread_userctx_t ldap_int_main_thrctx;
 
@@ -133,6 +135,7 @@ int
 ldap_int_thread_pool_startup ( void )
 {
        ldap_int_main_thrctx.ltu_id = ldap_pvt_thread_self();
+       ldap_pvt_thread_key_create( &ldap_tpool_key );
        return ldap_pvt_thread_mutex_init(&ldap_pvt_thread_pool_mutex);
 }
 
@@ -145,6 +148,7 @@ ldap_int_thread_pool_shutdown ( void )
                (ldap_pvt_thread_pool_destroy)(&pool, 0); /* ignore thr_debug macro */
        }
        ldap_pvt_thread_mutex_destroy(&ldap_pvt_thread_pool_mutex);
+       ldap_pvt_thread_key_destroy( ldap_tpool_key );
        return(0);
 }
 
@@ -552,6 +556,8 @@ ldap_int_thread_pool_wrapper (
        ctx.ltu_id = ldap_pvt_thread_self();
        TID_HASH(ctx.ltu_id, hash);
 
+       ldap_pvt_thread_key_setdata( ldap_tpool_key, &ctx );
+
        ldap_pvt_thread_mutex_lock(&pool->ltp_mutex);
 
        /* thread_keys[] is read-only when paused */
@@ -819,29 +825,10 @@ void ldap_pvt_thread_pool_purgekey( void *key )
  */
 void *ldap_pvt_thread_pool_context( )
 {
-       ldap_pvt_thread_t tid;
-       unsigned i, hash;
-       ldap_int_thread_userctx_t *ctx;
-
-       tid = ldap_pvt_thread_self();
-       if ( ldap_pvt_thread_equal( tid, ldap_int_main_thrctx.ltu_id ))
-               return &ldap_int_main_thrctx;
-
-       TID_HASH( tid, hash );
-       i = hash &= (LDAP_MAXTHR-1);
-       ldap_pvt_thread_mutex_lock(&ldap_pvt_thread_pool_mutex);
-       do {
-               ctx = thread_keys[i].ctx;
-               if ( ctx == DELETED_THREAD_CTX )
-                       continue;
-               if ( !ctx || ldap_pvt_thread_equal(thread_keys[i].ctx->ltu_id, tid) )
-                       goto done;
-       } while ( (i = (i+1) & (LDAP_MAXTHR-1)) != hash );
-       ctx = NULL;
- done:
-       ldap_pvt_thread_mutex_unlock(&ldap_pvt_thread_pool_mutex);
+       void *ctx = NULL;
 
-       return ctx;
+       ldap_pvt_thread_key_getdata( ldap_tpool_key, &ctx );
+       return ctx ? ctx : &ldap_int_main_thrctx;
 }
 
 /*
index c77dc1e25e34756e0783c7c0305fe8170146a648..3f8b608c45741ae54e8e8af4be161be56ccc0910 100644 (file)
@@ -98,7 +98,7 @@ do_abandon( Operation *op, SlapReply *rs )
                                        o, Operation, o_next );
                                LDAP_STAILQ_NEXT(o, o_next) = NULL;
                                op->o_conn->c_n_ops_pending--;
-                               slap_op_free( o );
+                               slap_op_free( o, NULL );
                                break;
                        }
                }
index 74bd27402c2805d361cacb098eec6c8bb4ff937c..10086079187bbbf407b1bff772b495ec2bad9464 100644 (file)
@@ -177,6 +177,7 @@ monitor_subsys_ops_update(
        struct berval           rdn;
        int                     i;
        Attribute               *a;
+       slap_counters_t *sc;
        static struct berval    bv_ops = BER_BVC( "cn=operations" );
 
        assert( mi != NULL );
@@ -188,21 +189,35 @@ monitor_subsys_ops_update(
                ldap_pvt_mp_init( nInitiated );
                ldap_pvt_mp_init( nCompleted );
 
-               ldap_pvt_thread_mutex_lock( &slap_counters.sc_ops_mutex );
+               ldap_pvt_thread_mutex_lock( &slap_counters.sc_mutex );
                for ( i = 0; i < SLAP_OP_LAST; i++ ) {
                        ldap_pvt_mp_add( nInitiated, slap_counters.sc_ops_initiated_[ i ] );
                        ldap_pvt_mp_add( nCompleted, slap_counters.sc_ops_completed_[ i ] );
                }
-               ldap_pvt_thread_mutex_unlock( &slap_counters.sc_ops_mutex );
+               for ( sc = slap_counters.sc_next; sc; sc = sc->sc_next ) {
+                       ldap_pvt_thread_mutex_lock( &sc->sc_mutex );
+                       for ( i = 0; i < SLAP_OP_LAST; i++ ) {
+                               ldap_pvt_mp_add( nInitiated, sc->sc_ops_initiated_[ i ] );
+                               ldap_pvt_mp_add( nCompleted, sc->sc_ops_completed_[ i ] );
+                       }
+                       ldap_pvt_thread_mutex_unlock( &sc->sc_mutex );
+               }
+               ldap_pvt_thread_mutex_unlock( &slap_counters.sc_mutex );
                
        } else {
                for ( i = 0; i < SLAP_OP_LAST; i++ ) {
                        if ( dn_match( &rdn, &monitor_op[ i ].nrdn ) )
                        {
-                               ldap_pvt_thread_mutex_lock( &slap_counters.sc_ops_mutex );
+                               ldap_pvt_thread_mutex_lock( &slap_counters.sc_mutex );
                                ldap_pvt_mp_init_set( nInitiated, slap_counters.sc_ops_initiated_[ i ] );
                                ldap_pvt_mp_init_set( nCompleted, slap_counters.sc_ops_completed_[ i ] );
-                               ldap_pvt_thread_mutex_unlock( &slap_counters.sc_ops_mutex );
+                               for ( sc = slap_counters.sc_next; sc; sc = sc->sc_next ) {
+                                       ldap_pvt_thread_mutex_lock( &sc->sc_mutex );
+                                       ldap_pvt_mp_add( nInitiated, sc->sc_ops_initiated_[ i ] );
+                                       ldap_pvt_mp_add( nCompleted, sc->sc_ops_completed_[ i ] );
+                                       ldap_pvt_thread_mutex_unlock( &sc->sc_mutex );
+                               }
+                               ldap_pvt_thread_mutex_unlock( &slap_counters.sc_mutex );
                                break;
                        }
                }
index 1be74711d9a0c38f68c9b0fc7b30f7bc94f9962c..d4d11fd30cd868749826dc5b4c0cc6ee8a13b161 100644 (file)
@@ -166,6 +166,7 @@ monitor_subsys_sent_update(
        struct berval           nrdn;
        ldap_pvt_mp_t           n;
        Attribute               *a;
+       slap_counters_t *sc;
        int                     i;
 
        assert( mi != NULL );
@@ -183,28 +184,48 @@ monitor_subsys_sent_update(
                return SLAP_CB_CONTINUE;
        }
 
-       ldap_pvt_thread_mutex_lock(&slap_counters.sc_sent_mutex);
+       ldap_pvt_thread_mutex_lock(&slap_counters.sc_mutex);
        switch ( i ) {
        case MONITOR_SENT_ENTRIES:
                ldap_pvt_mp_init_set( n, slap_counters.sc_entries );
+               for ( sc = slap_counters.sc_next; sc; sc = sc->sc_next ) {
+                       ldap_pvt_thread_mutex_lock( &sc->sc_mutex );
+                       ldap_pvt_mp_add( n, sc->sc_entries );
+                       ldap_pvt_thread_mutex_unlock( &sc->sc_mutex );
+               }
                break;
 
        case MONITOR_SENT_REFERRALS:
                ldap_pvt_mp_init_set( n, slap_counters.sc_refs );
+               for ( sc = slap_counters.sc_next; sc; sc = sc->sc_next ) {
+                       ldap_pvt_thread_mutex_lock( &sc->sc_mutex );
+                       ldap_pvt_mp_add( n, sc->sc_refs );
+                       ldap_pvt_thread_mutex_unlock( &sc->sc_mutex );
+               }
                break;
 
        case MONITOR_SENT_PDU:
                ldap_pvt_mp_init_set( n, slap_counters.sc_pdu );
+               for ( sc = slap_counters.sc_next; sc; sc = sc->sc_next ) {
+                       ldap_pvt_thread_mutex_lock( &sc->sc_mutex );
+                       ldap_pvt_mp_add( n, sc->sc_pdu );
+                       ldap_pvt_thread_mutex_unlock( &sc->sc_mutex );
+               }
                break;
 
        case MONITOR_SENT_BYTES:
                ldap_pvt_mp_init_set( n, slap_counters.sc_bytes );
+               for ( sc = slap_counters.sc_next; sc; sc = sc->sc_next ) {
+                       ldap_pvt_thread_mutex_lock( &sc->sc_mutex );
+                       ldap_pvt_mp_add( n, sc->sc_bytes );
+                       ldap_pvt_thread_mutex_unlock( &sc->sc_mutex );
+               }
                break;
 
        default:
                assert(0);
        }
-       ldap_pvt_thread_mutex_unlock(&slap_counters.sc_sent_mutex);
+       ldap_pvt_thread_mutex_unlock(&slap_counters.sc_mutex);
        
        a = attr_find( e->e_attrs, mi->mi_ad_monitorCounter );
        assert( a != NULL );
index dd4c79730cd86f505eb0cbaf9694686dff4c5cef..d11ad6a001d7e859282b0372ea67646652c8d175 100644 (file)
@@ -70,7 +70,7 @@ int cancel_extop( Operation *op, SlapReply *rs )
                        LDAP_STAILQ_REMOVE( &op->o_conn->c_pending_ops, o, Operation, o_next );
                        LDAP_STAILQ_NEXT(o, o_next) = NULL;
                        op->o_conn->c_n_ops_pending--;
-                       slap_op_free( o );
+                       slap_op_free( o, NULL );
                        ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
                        return LDAP_SUCCESS;
                }
index 9ec67f503a6d049ee48eec22e6e75089100234c6..c2e5a74318186f7f14de9048f4415d7129e69b6f 100644 (file)
@@ -83,25 +83,19 @@ connection_state2str( int state )
 
 static Connection* connection_get( ber_socket_t s );
 
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
-
 typedef struct conn_readinfo {
        Operation *op;
        ldap_pvt_thread_start_t *func;
        void *arg;
+       void *ctx;
        int nullop;
 } conn_readinfo;
 
 static int connection_input( Connection *c, conn_readinfo *cri );
-#else
-static int connection_input( Connection *c );
-#endif
 static void connection_close( Connection *c );
 
 static int connection_op_activate( Operation *op );
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
 static void connection_op_queue( Operation *op );
-#endif
 static int connection_resched( Connection *conn );
 static void connection_abandon( Connection *conn );
 static void connection_destroy( Connection *c );
@@ -267,8 +261,6 @@ static Connection* connection_get( ber_socket_t s )
 #else
        c = NULL;
        {
-               ber_socket_t i, sd;
-
                ldap_pvt_thread_mutex_lock( &connections_mutex );
                for(i=0; i<dtblsize; i++) {
                        if( connections[i].c_struct_state == SLAP_C_PENDING )
@@ -280,12 +272,9 @@ static Connection* connection_get( ber_socket_t s )
                                break;
                        }
 
-                       ber_sockbuf_ctrl( connections[i].c_sb,
-                               LBER_SB_OPT_GET_FD, &sd );
-
                        if( connections[i].c_struct_state == SLAP_C_UNUSED ) {
                                assert( connections[i].c_conn_state == SLAP_C_INVALID );
-                               assert( sd == AC_SOCKET_INVALID );
+                               assert( connections[i].c_sd == AC_SOCKET_INVALID );
                                continue;
                        }
 
@@ -293,7 +282,7 @@ static Connection* connection_get( ber_socket_t s )
                         * so don't assert details here.
                         */
 
-                       if( sd == s ) {
+                       if( connections[i].c_sd == s ) {
                                c = &connections[i];
                                break;
                        }
@@ -303,18 +292,15 @@ static Connection* connection_get( ber_socket_t s )
 #endif
 
        if( c != NULL ) {
-               ber_socket_t    sd;
-
                ldap_pvt_thread_mutex_lock( &c->c_mutex );
 
                assert( c->c_struct_state != SLAP_C_UNINITIALIZED );
 
-               ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_GET_FD, &sd );
 #ifdef HAVE_WINSOCK
                /* Avoid race condition after releasing
                 * connections_mutex
                 */
-               if ( sd != s ) {
+               if ( c->c_sd != s ) {
                        ldap_pvt_thread_mutex_unlock( &c->c_mutex );
                        return NULL;
                }
@@ -323,7 +309,7 @@ static Connection* connection_get( ber_socket_t s )
                        /* connection must have been closed due to resched */
 
                        assert( c->c_conn_state == SLAP_C_INVALID );
-                       assert( sd == AC_SOCKET_INVALID );
+                       assert( c->c_sd == AC_SOCKET_INVALID );
 
                        Debug( LDAP_DEBUG_TRACE,
                                "connection_get(%d): connection not used\n",
@@ -341,7 +327,7 @@ static Connection* connection_get( ber_socket_t s )
 
                assert( c->c_struct_state == SLAP_C_USED );
                assert( c->c_conn_state != SLAP_C_INVALID );
-               assert( sd != AC_SOCKET_INVALID );
+               assert( c->c_sd != AC_SOCKET_INVALID );
 
 #ifndef SLAPD_MONITOR
                if ( global_idletimeout > 0 )
@@ -405,8 +391,6 @@ Connection * connection_init(
 
                ldap_pvt_thread_mutex_lock( &connections_mutex );
                for( i=0; i < dtblsize; i++) {
-                       ber_socket_t    sd;
-
                        if ( connections[i].c_struct_state == SLAP_C_PENDING )
                                continue;
 
@@ -418,14 +402,7 @@ Connection * connection_init(
                                break;
                        }
 
-                       sd = AC_SOCKET_INVALID;
-                       if (connections[i].c_sb != NULL) {
-                               ber_sockbuf_ctrl( connections[i].c_sb,
-                                       LBER_SB_OPT_GET_FD, &sd );
-                       }
-
                        if( connections[i].c_struct_state == SLAP_C_UNUSED ) {
-                               assert( sd == AC_SOCKET_INVALID );
                                c = &connections[i];
                                c->c_struct_state = SLAP_C_PENDING;
                                break;
@@ -435,7 +412,6 @@ Connection * connection_init(
 
                        assert( connections[i].c_struct_state == SLAP_C_USED );
                        assert( connections[i].c_conn_state != SLAP_C_INVALID );
-                       assert( sd != AC_SOCKET_INVALID );
                }
                ldap_pvt_thread_mutex_unlock( &connections_mutex );
 
@@ -525,6 +501,7 @@ Connection * connection_init(
        assert( c->c_writewaiter == 0);
 
        c->c_listener = listener;
+       c->c_sd = s;
 
        if ( flags & CONN_IS_CLIENT ) {
                c->c_connid = 0;
@@ -677,7 +654,6 @@ void connection2anonymous( Connection *c )
 static void
 connection_destroy( Connection *c )
 {
-       ber_socket_t    sd;
        unsigned long   connid;
        const char              *close_reason;
        Sockbuf                 *sb;
@@ -754,21 +730,20 @@ connection_destroy( Connection *c )
                ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_SET_MAX_INCOMING, &max );
        }
 
-       ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_FD, &sd );
-
        /* c must be fully reset by this point; when we call slapd_remove
         * it may get immediately reused by a new connection.
         */
-       if ( sd != AC_SOCKET_INVALID ) {
-               slapd_remove( sd, sb, 1, 0, 0 );
+       if ( c->c_sd != AC_SOCKET_INVALID ) {
+               slapd_remove( c->c_sd, sb, 1, 0, 0 );
 
                if ( close_reason == NULL ) {
                        Statslog( LDAP_DEBUG_STATS, "conn=%lu fd=%ld closed\n",
-                               connid, (long) sd, 0, 0, 0 );
+                               connid, (long) c->c_sd, 0, 0, 0 );
                } else {
                        Statslog( LDAP_DEBUG_STATS, "conn=%lu fd=%ld closed (%s)\n",
-                               connid, (long) sd, close_reason, 0, 0 );
+                               connid, (long) c->c_sd, close_reason, 0, 0 );
                }
+               c->c_sd = AC_SOCKET_INVALID;
        }
 }
 
@@ -813,7 +788,7 @@ static void connection_abandon( Connection *c )
        while ( (o = LDAP_STAILQ_FIRST( &c->c_txn_ops )) != NULL) {
                LDAP_STAILQ_REMOVE_HEAD( &c->c_txn_ops, o_next );
                LDAP_STAILQ_NEXT(o, o_next) = NULL;
-               slap_op_free( o );
+               slap_op_free( o, NULL );
        }
 
        /* clear transaction */
@@ -825,7 +800,7 @@ static void connection_abandon( Connection *c )
        while ( (o = LDAP_STAILQ_FIRST( &c->c_pending_ops )) != NULL) {
                LDAP_STAILQ_REMOVE_HEAD( &c->c_pending_ops, o_next );
                LDAP_STAILQ_NEXT(o, o_next) = NULL;
-               slap_op_free( o );
+               slap_op_free( o, NULL );
        }
 }
 
@@ -839,18 +814,15 @@ void connection_closing( Connection *c, const char *why )
        /* c_mutex must be locked by caller */
 
        if( c->c_conn_state != SLAP_C_CLOSING ) {
-               ber_socket_t    sd;
-
-               ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_GET_FD, &sd );
                Debug( LDAP_DEBUG_TRACE,
                        "connection_closing: readying conn=%lu sd=%d for close\n",
-                       c->c_connid, sd, 0 );
+                       c->c_connid, c->c_sd, 0 );
                /* update state to closing */
                c->c_conn_state = SLAP_C_CLOSING;
                c->c_close_reason = why;
 
                /* don't listen on this port anymore */
-               slapd_clr_read( sd, 0 );
+               slapd_clr_read( c->c_sd, 0 );
 
                /* abandon active operations */
                connection_abandon( c );
@@ -862,13 +834,13 @@ void connection_closing( Connection *c, const char *why )
                         * connection_resched / connection_close before we
                         * finish, but that's OK.
                         */
-                       slapd_clr_write( sd, 1 );
+                       slapd_clr_write( c->c_sd, 1 );
                        ldap_pvt_thread_mutex_unlock( &c->c_mutex );
                        ldap_pvt_thread_mutex_lock( &c->c_write_mutex );
                        ldap_pvt_thread_mutex_lock( &c->c_mutex );
                        ldap_pvt_thread_mutex_unlock( &c->c_write_mutex );
                } else {
-                       slapd_clr_write( sd, 1 );
+                       slapd_clr_write( c->c_sd, 1 );
                }
 
        } else if( why == NULL && c->c_close_reason == conn_lost_str ) {
@@ -880,8 +852,6 @@ void connection_closing( Connection *c, const char *why )
 static void
 connection_close( Connection *c )
 {
-       ber_socket_t    sd = AC_SOCKET_INVALID;
-
        assert( connections != NULL );
        assert( c != NULL );
 
@@ -894,22 +864,17 @@ connection_close( Connection *c )
 
        /* NOTE: c_mutex should be locked by caller */
 
-       /* NOTE: don't get the file descriptor if not needed */
-       if ( LogTest( LDAP_DEBUG_TRACE ) ) {
-               ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_GET_FD, &sd );
-       }
-
        if ( !LDAP_STAILQ_EMPTY(&c->c_ops) ||
                !LDAP_STAILQ_EMPTY(&c->c_pending_ops) )
        {
                Debug( LDAP_DEBUG_TRACE,
                        "connection_close: deferring conn=%lu sd=%d\n",
-                       c->c_connid, sd, 0 );
+                       c->c_connid, c->c_sd, 0 );
                return;
        }
 
        Debug( LDAP_DEBUG_TRACE, "connection_close: conn=%lu sd=%d\n",
-               c->c_connid, sd, 0 );
+               c->c_connid, c->c_sd, 0 );
 
        connection_destroy( c );
 }
@@ -1011,24 +976,24 @@ void connection_done( Connection *c )
 /* FIXME: returns 0 in case of failure */
 #define INCR_OP_INITIATED(index) \
        do { \
-               ldap_pvt_thread_mutex_lock( &slap_counters.sc_ops_mutex ); \
-               ldap_pvt_mp_add_ulong(slap_counters.sc_ops_initiated_[(index)], 1); \
-               ldap_pvt_thread_mutex_unlock( &slap_counters.sc_ops_mutex ); \
+               ldap_pvt_thread_mutex_lock( &op->o_counters->sc_mutex ); \
+               ldap_pvt_mp_add_ulong(op->o_counters->sc_ops_initiated_[(index)], 1); \
+               ldap_pvt_thread_mutex_unlock( &op->o_counters->sc_mutex ); \
        } while (0)
 #define INCR_OP_COMPLETED(index) \
        do { \
-               ldap_pvt_thread_mutex_lock( &slap_counters.sc_ops_mutex ); \
-               ldap_pvt_mp_add_ulong(slap_counters.sc_ops_completed, 1); \
-               ldap_pvt_mp_add_ulong(slap_counters.sc_ops_completed_[(index)], 1); \
-               ldap_pvt_thread_mutex_unlock( &slap_counters.sc_ops_mutex ); \
+               ldap_pvt_thread_mutex_lock( &op->o_counters->sc_mutex ); \
+               ldap_pvt_mp_add_ulong(op->o_counters->sc_ops_completed, 1); \
+               ldap_pvt_mp_add_ulong(op->o_counters->sc_ops_completed_[(index)], 1); \
+               ldap_pvt_thread_mutex_unlock( &op->o_counters->sc_mutex ); \
        } while (0)
 #else /* !SLAPD_MONITOR */
 #define INCR_OP_INITIATED(index) do { } while (0)
 #define INCR_OP_COMPLETED(index) \
        do { \
-               ldap_pvt_thread_mutex_lock( &slap_counters.sc_ops_mutex ); \
-               ldap_pvt_mp_add_ulong(slap_counters.sc_ops_completed, 1); \
-               ldap_pvt_thread_mutex_unlock( &slap_counters.sc_ops_mutex ); \
+               ldap_pvt_thread_mutex_lock( &op->o_counters->sc_mutex ); \
+               ldap_pvt_mp_add_ulong(op->o_counters->sc_ops_completed, 1); \
+               ldap_pvt_thread_mutex_unlock( &op->o_counters->sc_mutex ); \
        } while (0)
 #endif /* !SLAPD_MONITOR */
 
@@ -1049,6 +1014,62 @@ static BI_op_func *opfun[] = {
        NULL
 };
 
+/* Counters are per-thread, not per-connection.
+ */
+static void
+conn_counter_destroy( void *key, void *data )
+{
+       slap_counters_t **prev, *sc;
+
+       ldap_pvt_thread_mutex_lock( &slap_counters.sc_mutex );
+       for ( prev = &slap_counters.sc_next, sc = slap_counters.sc_next; sc;
+               prev = &sc->sc_next, sc = sc->sc_next ) {
+               if ( sc == data ) {
+                       int i;
+
+                       *prev = sc->sc_next;
+                       /* Copy data to main counter */
+                       ldap_pvt_mp_add( slap_counters.sc_bytes, sc->sc_bytes );
+                       ldap_pvt_mp_add( slap_counters.sc_pdu, sc->sc_pdu );
+                       ldap_pvt_mp_add( slap_counters.sc_entries, sc->sc_entries );
+                       ldap_pvt_mp_add( slap_counters.sc_refs, sc->sc_refs );
+                       ldap_pvt_mp_add( slap_counters.sc_ops_initiated, sc->sc_ops_initiated );
+                       ldap_pvt_mp_add( slap_counters.sc_ops_completed, sc->sc_ops_completed );
+#ifdef SLAPD_MONITOR
+                       for ( i = 0; i < SLAP_OP_LAST; i++ ) {
+                               ldap_pvt_mp_add( slap_counters.sc_ops_initiated_[ i ], sc->sc_ops_initiated_[ i ] );
+                               ldap_pvt_mp_add( slap_counters.sc_ops_initiated_[ i ], sc->sc_ops_completed_[ i ] );
+                       }
+#endif /* SLAPD_MONITOR */
+                       slap_counters_destroy( sc );
+                       ber_memfree_x( data, NULL );
+                       break;
+               }
+       }
+       ldap_pvt_thread_mutex_unlock( &slap_counters.sc_mutex );
+}
+
+static void
+conn_counter_init( Operation *op, void *ctx )
+{
+       slap_counters_t *sc;
+       void *vsc = NULL;
+
+       if ( ldap_pvt_thread_pool_getkey( ctx, conn_counter_init, &vsc, NULL ) || !vsc ) {
+               vsc = ch_malloc( sizeof( slap_counters_t ));
+               sc = vsc;
+               slap_counters_init( sc );
+               ldap_pvt_thread_pool_setkey( ctx, conn_counter_init, vsc,
+                       conn_counter_destroy );
+
+               ldap_pvt_thread_mutex_lock( &slap_counters.sc_mutex );
+               sc->sc_next = slap_counters.sc_next;
+               slap_counters.sc_next = sc;
+               ldap_pvt_thread_mutex_unlock( &slap_counters.sc_mutex );
+       }
+       op->o_counters = vsc;
+}
+
 static void *
 connection_operation( void *ctx, void *arg_v )
 {
@@ -1062,10 +1083,11 @@ connection_operation( void *ctx, void *arg_v )
        void *memctx_null = NULL;
        ber_len_t memsiz;
 
-       ldap_pvt_thread_mutex_lock( &slap_counters.sc_ops_mutex );
+       conn_counter_init( op, ctx );
+       ldap_pvt_thread_mutex_lock( &op->o_counters->sc_mutex );
        /* FIXME: returns 0 in case of failure */
-       ldap_pvt_mp_add_ulong(slap_counters.sc_ops_initiated, 1);
-       ldap_pvt_thread_mutex_unlock( &slap_counters.sc_ops_mutex );
+       ldap_pvt_mp_add_ulong(op->o_counters->sc_ops_initiated, 1);
+       ldap_pvt_thread_mutex_unlock( &op->o_counters->sc_mutex );
 
        op->o_threadctx = ctx;
        op->o_tid = ldap_pvt_thread_pool_tid( ctx );
@@ -1175,7 +1197,6 @@ operations_error:
 
        LDAP_STAILQ_REMOVE( &conn->c_ops, op, Operation, o_next);
        LDAP_STAILQ_NEXT(op, o_next) = NULL;
-       slap_op_free( op );
        conn->c_n_ops_executing--;
        conn->c_n_ops_completed++;
 
@@ -1190,6 +1211,7 @@ operations_error:
 
        connection_resched( conn );
        ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
+       slap_op_free( op, ctx );
        return NULL;
 }
 
@@ -1247,8 +1269,6 @@ void connection_client_stop(
        connection_return( c );
 }
 
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
-
 static int connection_read( ber_socket_t s, conn_readinfo *cri );
 
 static void* connection_read_thread( void* ctx, void* argv )
@@ -1261,6 +1281,7 @@ static void* connection_read_thread( void* ctx, void* argv )
         * read incoming LDAP requests. If there is more than one,
         * the first one is returned with new_op
         */
+       cri.ctx = ctx;
        if( ( rc = connection_read( s, &cri ) ) < 0 ) {
                Debug( LDAP_DEBUG_CONNS, "connection_read(%d) error\n", s, 0, 0 );
                return (void*)(long)rc;
@@ -1300,14 +1321,9 @@ int connection_read_activate( ber_socket_t s )
 
        return rc;
 }
-#endif
 
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
 static int
 connection_read( ber_socket_t s, conn_readinfo *cri )
-#else
-int connection_read(ber_socket_t s)
-#endif
 {
        int rc = 0;
        Connection *c;
@@ -1336,15 +1352,9 @@ int connection_read(ber_socket_t s)
        }
 
        if ( c->c_conn_state == SLAP_C_CLIENT ) {
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
                cri->func = c->c_clientfunc;
                cri->arg = c->c_clientarg;
                /* read should already be cleared */
-#else
-               slapd_clr_read( s, 0 );
-               ldap_pvt_thread_pool_submit( &connection_pool,
-                       c->c_clientfunc, c->c_clientarg );
-#endif
                connection_return( c );
                return 0;
        }
@@ -1399,10 +1409,7 @@ int connection_read(ber_socket_t s)
                /* if success and data is ready, fall thru to data input loop */
                if( !ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_DATA_READY, NULL ) )
                {
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
                        slapd_set_read( s, 1 );
-#endif
-
                        connection_return( c );
                        return 0;
                }
@@ -1413,10 +1420,7 @@ int connection_read(ber_socket_t s)
        if ( c->c_sasl_layers ) {
                /* If previous layer is not removed yet, give up for now */
                if ( !c->c_sasl_sockctx ) {
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
                        slapd_set_read( s, 1 );
-#endif
-
                        connection_return( c );
                        return 0;
                }
@@ -1444,11 +1448,7 @@ int connection_read(ber_socket_t s)
 
        do {
                /* How do we do this without getting into a busy loop ? */
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
                rc = connection_input( c, cri );
-#else
-               rc = connection_input( c );
-#endif
        }
 #ifdef DATA_READY_LOOP
        while( !rc && ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_DATA_READY, NULL ));
@@ -1470,33 +1470,18 @@ int connection_read(ber_socket_t s)
                return 0;
        }
 
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
        if ( ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_NEEDS_WRITE, NULL ) ) {
                slapd_set_write( s, 0 );
        }
 
        slapd_set_read( s, 1 );
-#else
-       if ( ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_NEEDS_READ, NULL ) ) {
-               slapd_set_read( s, 1 );
-       }
-
-       if ( ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_NEEDS_WRITE, NULL ) ) {
-               slapd_set_write( s, 1 );
-       }
-#endif
-
        connection_return( c );
 
        return 0;
 }
 
 static int
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
 connection_input( Connection *conn , conn_readinfo *cri )
-#else
-connection_input( Connection *conn )
-#endif
 {
        Operation *op;
        ber_tag_t       tag;
@@ -1509,6 +1494,7 @@ connection_input( Connection *conn )
        char            *cdn = NULL;
 #endif
        char *defer = NULL;
+       void *ctx;
 
        if ( conn->c_currentber == NULL &&
                ( conn->c_currentber = ber_alloc()) == NULL )
@@ -1538,15 +1524,12 @@ connection_input( Connection *conn )
        tag = ber_get_next( conn->c_sb, &len, conn->c_currentber );
        if ( tag != LDAP_TAG_MESSAGE ) {
                int err = sock_errno();
-               ber_socket_t    sd;
-
-               ber_sockbuf_ctrl( conn->c_sb, LBER_SB_OPT_GET_FD, &sd );
 
                if ( err != EWOULDBLOCK && err != EAGAIN ) {
                        /* log, close and send error */
                        Debug( LDAP_DEBUG_TRACE,
                                "ber_get_next on fd %d failed errno=%d (%s)\n",
-                       sd, err, sock_errstr(err) );
+                       conn->c_sd, err, sock_errstr(err) );
                        ber_free( conn->c_currentber, 1 );
                        conn->c_currentber = NULL;
 
@@ -1592,7 +1575,8 @@ connection_input( Connection *conn )
                connection_abandon( conn );
        }
 
-       op = slap_op_alloc( ber, msgid, tag, conn->c_n_ops_received++ );
+       ctx = cri->ctx;
+       op = slap_op_alloc( ber, msgid, tag, conn->c_n_ops_received++, ctx );
 
        op->o_conn = conn;
        /* clear state if the connection is being reused from inactive */
@@ -1682,7 +1666,6 @@ connection_input( Connection *conn )
        } else {
                conn->c_n_ops_executing++;
 
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
                /*
                 * The first op will be processed in the same thread context,
                 * as long as there is only one op total.
@@ -1701,9 +1684,6 @@ connection_input( Connection *conn )
                        }
                        connection_op_activate( op );
                }
-#else
-               connection_op_activate( op );
-#endif
        }
 
 #ifdef NO_THREADS
@@ -1723,12 +1703,9 @@ connection_resched( Connection *conn )
        Operation *op;
 
        if( conn->c_conn_state == SLAP_C_CLOSING ) {
-               ber_socket_t    sd;
-               ber_sockbuf_ctrl( conn->c_sb, LBER_SB_OPT_GET_FD, &sd );
-
                Debug( LDAP_DEBUG_TRACE, "connection_resched: "
                        "attempting closing conn=%lu sd=%d\n",
-                       conn->c_connid, sd, 0 );
+                       conn->c_connid, conn->c_sd, 0 );
                connection_close( conn );
                return 0;
        }
@@ -2010,6 +1987,7 @@ connection_fake_init2(
        Operation *op = (Operation *) opbuf;
 
        conn->c_connid = -1;
+       conn->c_conn_idx = -1;
        conn->c_send_ldap_result = slap_send_ldap_result;
        conn->c_send_search_entry = slap_send_search_entry;
        conn->c_send_search_reference = slap_send_search_reference;
@@ -2028,6 +2006,7 @@ connection_fake_init2(
        op->o_threadctx = ctx;
        op->o_tid = ldap_pvt_thread_pool_tid( ctx );
 
+       op->o_counters = &slap_counters;
        op->o_conn = conn;
        op->o_connid = op->o_conn->c_connid;
        connection_init_log_prefix( op );
index 5949e543d732d4b177689720dcaf5778d0fdcae5..641e4380424fefb7711fe0965df42458b8d4c547 100644 (file)
@@ -182,14 +182,12 @@ static struct slap_daemon {
 # define SLAP_SOCK_CLR_READ(s)         SLAP_EPOLL_SOCK_CLR((s), EPOLLIN)
 # define SLAP_SOCK_CLR_WRITE(s)                SLAP_EPOLL_SOCK_CLR((s), EPOLLOUT)
 
-# ifdef SLAP_LIGHTWEIGHT_DISPATCHER
 #  define SLAP_SOCK_SET_SUSPEND(s) \
        ( slap_daemon.sd_suspend[SLAP_EPOLL_SOCK_IX(s)] = 1 )
 #  define SLAP_SOCK_CLR_SUSPEND(s) \
        ( slap_daemon.sd_suspend[SLAP_EPOLL_SOCK_IX(s)] = 0 )
 #  define SLAP_SOCK_IS_SUSPEND(s) \
        ( slap_daemon.sd_suspend[SLAP_EPOLL_SOCK_IX(s)] == 1 )
-# endif /* SLAP_LIGHTWEIGHT_DISPATCHER */
 
 # define SLAP_EPOLL_EVENT_CLR(i, mode) (revents[(i)].events &= ~(mode))
 
@@ -356,14 +354,12 @@ static struct slap_daemon {
 # define SLAP_SOCK_CLR_READ(s)         SLAP_DEVPOLL_SOCK_CLR((s), POLLIN)
 # define SLAP_SOCK_CLR_WRITE(s)                SLAP_DEVPOLL_SOCK_CLR((s), POLLOUT)
 
-# ifdef SLAP_LIGHTWEIGHT_DISPATCHER
 #  define SLAP_SOCK_SET_SUSPEND(s) \
        ( slap_daemon.sd_suspend[SLAP_DEVPOLL_SOCK_IX((s))] = 1 )
 #  define SLAP_SOCK_CLR_SUSPEND(s) \
        ( slap_daemon.sd_suspend[SLAP_DEVPOLL_SOCK_IX((s))] = 0 )
 #  define SLAP_SOCK_IS_SUSPEND(s) \
        ( slap_daemon.sd_suspend[SLAP_DEVPOLL_SOCK_IX((s))] == 1 )
-# endif /* SLAP_LIGHTWEIGHT_DISPATCHER */
 
 # define SLAP_DEVPOLL_EVENT_CLR(i, mode)       (revents[(i)].events &= ~(mode))
 
@@ -704,9 +700,7 @@ slapd_add( ber_socket_t s, int isactive, Listener *sl )
 
        ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
 
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
        WAKE_LISTENER(1);
-#endif /* SLAP_LIGHTWEIGHT_DISPATCHER */
 }
 
 /*
@@ -1128,9 +1122,7 @@ slap_open_listener(
 
        l.sl_url.bv_val = NULL;
        l.sl_mute = 0;
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
        l.sl_busy = 0;
-#endif /* SLAP_LIGHTWEIGHT_DISPATCHER */
 
 #ifndef HAVE_TLS
        if( ldap_pvt_url_scheme2tls( lud->lud_scheme ) ) {
@@ -1608,13 +1600,11 @@ slap_listener(
 
        s = accept( sl->sl_sd, (struct sockaddr *) &from, &len );
 
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
        /* Resume the listener FD to allow concurrent-processing of
         * additional incoming connections.
         */
        sl->sl_busy = 0;
        WAKE_LISTENER(1);
-#endif /* SLAP_LIGHTWEIGHT_DISPATCHER */
 
        if ( s == AC_SOCKET_INVALID ) {
                int err = sock_errno();
@@ -1844,7 +1834,6 @@ slap_listener(
        return 0;
 }
 
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
 static void*
 slap_listener_thread(
        void* ctx,
@@ -1885,7 +1874,6 @@ slap_listener_activate(
        }
        return rc;
 }
-#endif /* SLAP_LIGHTWEIGHT_DISPATCHER */
 
 static void *
 slapd_daemon_task(
@@ -1972,7 +1960,6 @@ slapd_daemon_task(
                        return (void*)-1;
                }
 
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
                /* make the listening socket non-blocking */
                if ( ber_pvt_socket_set_nonblock( slap_listeners[l]->sl_sd, 1 ) < 0 ) {
                        Debug( LDAP_DEBUG_ANY, "slapd_daemon_task: "
@@ -1981,7 +1968,6 @@ slapd_daemon_task(
                        slapd_shutdown = 2;
                        return (void*)-1;
                }
-#endif /* SLAP_LIGHTWEIGHT_DISPATCHER */
 
                slapd_add( slap_listeners[l]->sl_sd, 0, slap_listeners[l] );
        }
@@ -2061,11 +2047,7 @@ slapd_daemon_task(
 
                        if ( lr->sl_sd == AC_SOCKET_INVALID ) continue;
 
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
                        if ( lr->sl_mute || lr->sl_busy )
-#else /* ! SLAP_LIGHTWEIGHT_DISPATCHER */
-                       if ( lr->sl_mute )
-#endif /* ! SLAP_LIGHTWEIGHT_DISPATCHER */
                        {
                                SLAP_SOCK_CLR_READ( lr->sl_sd );
                        } else {
@@ -2140,7 +2122,6 @@ slapd_daemon_task(
                                continue;
                        }
 
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
                        if ( lr->sl_busy ) {
                                Debug( LDAP_DEBUG_CONNS,
                                        "daemon: " SLAP_EVENT_FNAME ": "
@@ -2148,7 +2129,6 @@ slapd_daemon_task(
                                        lr->sl_sd, 0, 0 );
                                continue;
                        }
-#endif /* SLAP_LIGHTWEIGHT_DISPATCHER */
 
                        Debug( LDAP_DEBUG_CONNS,
                                "daemon: " SLAP_EVENT_FNAME ": "
@@ -2231,11 +2211,7 @@ slapd_daemon_task(
                        SLAP_EVENT_CLR_WRITE( slap_listeners[l]->sl_sd );
                        ns--;
 
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
                        rc = slap_listener_activate( slap_listeners[l] );
-#else /* ! SLAP_LIGHTWEIGHT_DISPATCHER */
-                       rc = slap_listener( slap_listeners[l] );
-#endif /* ! SLAP_LIGHTWEIGHT_DISPATCHER */
                }
 
                /* bypass the following tests if no descriptors left */
@@ -2339,11 +2315,7 @@ slapd_daemon_task(
                         * active.
                         */
 
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
                        connection_read_activate( rd );
-#else /* ! SLAP_LIGHTWEIGHT_DISPATCHER */
-                       connection_read( rd );
-#endif /* ! SLAP_LIGHTWEIGHT_DISPATCHER */
                }
 #else  /* !SLAP_EVENTS_ARE_INDEXED */
        /* FIXME */
@@ -2395,11 +2367,7 @@ slapd_daemon_task(
                        int rc = 1, fd;
 
                        if ( SLAP_EVENT_IS_LISTENER( i ) ) {
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
                                rc = slap_listener_activate( SLAP_EVENT_LISTENER( i ) );
-#else /* ! SLAP_LIGHTWEIGHT_DISPATCHER */
-                               rc = slap_listener( SLAP_EVENT_LISTENER( i ) );
-#endif /* ! SLAP_LIGHTWEIGHT_DISPATCHER */
                        }
 
                        /* If we found a regular listener, rc is now zero, and we
@@ -2441,17 +2409,7 @@ slapd_daemon_task(
                                                fd, 0, 0 );
 
                                        SLAP_EVENT_CLR_READ( i );
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
                                        connection_read_activate( fd );
-#else /* ! SLAP_LIGHTWEIGHT_DISPATCHER */
-                                       /*
-                                        * NOTE: it is possible that the connection was closed
-                                        * and that the stream is now inactive.
-                                        * connection_read() must valid the stream is still
-                                        * active.
-                                        */
-                                       connection_read( fd );
-#endif /* ! SLAP_LIGHTWEIGHT_DISPATCHER */
                                } else {
                                        Debug( LDAP_DEBUG_CONNS,
                                                "daemon: hangup on %d\n", fd, 0, 0 );
index 28f30521c6913a6eec4709a5538f39a5f9461421..d1cb5ecc6eabebe18adb2918a263b0f359ff7415 100644 (file)
@@ -67,7 +67,7 @@ int                   connection_pool_max = SLAP_MAX_WORKER_THREADS;
 int            slap_tool_thread_max = 1;
 ldap_pvt_thread_mutex_t        gmtime_mutex;
 
-slap_counters_t                        slap_counters;
+slap_counters_t                        slap_counters, *slap_counters_list;
 
 static const char* slap_name = NULL;
 int slapMode = SLAP_UNDEFINED_MODE;
@@ -76,7 +76,6 @@ int
 slap_init( int mode, const char *name )
 {
        int rc;
-       int i;
 
        assert( mode );
 
@@ -144,27 +143,12 @@ slap_init( int mode, const char *name )
                ldap_pvt_thread_pool_init( &connection_pool,
                                connection_pool_max, 0);
 
-               ldap_pvt_thread_mutex_init( &slap_counters.sc_sent_mutex );
-               ldap_pvt_thread_mutex_init( &slap_counters.sc_ops_mutex );
-               ldap_pvt_mp_init( slap_counters.sc_bytes );
-               ldap_pvt_mp_init( slap_counters.sc_pdu );
-               ldap_pvt_mp_init( slap_counters.sc_entries );
-               ldap_pvt_mp_init( slap_counters.sc_refs );
-
-               ldap_pvt_mp_init( slap_counters.sc_ops_initiated );
-               ldap_pvt_mp_init( slap_counters.sc_ops_completed );
+               slap_counters_init( &slap_counters );
 
                ldap_pvt_thread_mutex_init( &slapd_rq.rq_mutex );
                LDAP_STAILQ_INIT( &slapd_rq.task_list );
                LDAP_STAILQ_INIT( &slapd_rq.run_list );
 
-#ifdef SLAPD_MONITOR
-               for ( i = 0; i < SLAP_OP_LAST; i++ ) {
-                       ldap_pvt_mp_init( slap_counters.sc_ops_initiated_[ i ] );
-                       ldap_pvt_mp_init( slap_counters.sc_ops_completed_[ i ] );
-               }
-#endif /* SLAPD_MONITOR */
-
                ldap_pvt_thread_mutex_init( &gmtime_mutex );
                slap_passwd_init();
 
@@ -264,7 +248,6 @@ int slap_shutdown( Backend *be )
 int slap_destroy(void)
 {
        int rc;
-       int i;
 
        Debug( LDAP_DEBUG_TRACE,
                "%s destroy: freeing system resources.\n",
@@ -288,24 +271,8 @@ int slap_destroy(void)
 
        switch ( slapMode & SLAP_MODE ) {
        case SLAP_SERVER_MODE:
-
        case SLAP_TOOL_MODE:
-
-               ldap_pvt_thread_mutex_destroy( &slap_counters.sc_sent_mutex );
-               ldap_pvt_thread_mutex_destroy( &slap_counters.sc_ops_mutex );
-               ldap_pvt_mp_clear( slap_counters.sc_bytes );
-               ldap_pvt_mp_clear( slap_counters.sc_pdu );
-               ldap_pvt_mp_clear( slap_counters.sc_entries );
-               ldap_pvt_mp_clear( slap_counters.sc_refs );
-               ldap_pvt_mp_clear( slap_counters.sc_ops_initiated );
-               ldap_pvt_mp_clear( slap_counters.sc_ops_completed );
-
-#ifdef SLAPD_MONITOR
-               for ( i = 0; i < SLAP_OP_LAST; i++ ) {
-                       ldap_pvt_mp_clear( slap_counters.sc_ops_initiated_[ i ] );
-                       ldap_pvt_mp_clear( slap_counters.sc_ops_completed_[ i ] );
-               }
-#endif /* SLAPD_MONITOR */
+               slap_counters_destroy( &slap_counters );
                break;
 
        default:
@@ -324,3 +291,46 @@ int slap_destroy(void)
        /* should destroy the above mutex */
        return rc;
 }
+
+void slap_counters_init( slap_counters_t *sc )
+{
+       int i;
+
+       ldap_pvt_thread_mutex_init( &sc->sc_mutex );
+       ldap_pvt_mp_init( sc->sc_bytes );
+       ldap_pvt_mp_init( sc->sc_pdu );
+       ldap_pvt_mp_init( sc->sc_entries );
+       ldap_pvt_mp_init( sc->sc_refs );
+
+       ldap_pvt_mp_init( sc->sc_ops_initiated );
+       ldap_pvt_mp_init( sc->sc_ops_completed );
+
+#ifdef SLAPD_MONITOR
+       for ( i = 0; i < SLAP_OP_LAST; i++ ) {
+               ldap_pvt_mp_init( sc->sc_ops_initiated_[ i ] );
+               ldap_pvt_mp_init( sc->sc_ops_completed_[ i ] );
+       }
+#endif /* SLAPD_MONITOR */
+}
+
+void slap_counters_destroy( slap_counters_t *sc )
+{
+       int i;
+
+       ldap_pvt_thread_mutex_destroy( &sc->sc_mutex );
+       ldap_pvt_mp_clear( sc->sc_bytes );
+       ldap_pvt_mp_clear( sc->sc_pdu );
+       ldap_pvt_mp_clear( sc->sc_entries );
+       ldap_pvt_mp_clear( sc->sc_refs );
+
+       ldap_pvt_mp_clear( sc->sc_ops_initiated );
+       ldap_pvt_mp_clear( sc->sc_ops_completed );
+
+#ifdef SLAPD_MONITOR
+       for ( i = 0; i < SLAP_OP_LAST; i++ ) {
+               ldap_pvt_mp_clear( sc->sc_ops_initiated_[ i ] );
+               ldap_pvt_mp_clear( sc->sc_ops_completed_[ i ] );
+       }
+#endif /* SLAPD_MONITOR */
+}
+
index b5b2f3d1e661b180962917607614e7a74be17893..124a3b85b90b8d2060f9c593fee4216f8b987172 100644 (file)
 #endif
 
 static ldap_pvt_thread_mutex_t slap_op_mutex;
-static LDAP_STAILQ_HEAD(s_o, Operation)        slap_free_ops;
 static time_t last_time;
 static int last_incr;
 
 void slap_op_init(void)
 {
        ldap_pvt_thread_mutex_init( &slap_op_mutex );
-       LDAP_STAILQ_INIT(&slap_free_ops);
 }
 
 void slap_op_destroy(void)
 {
-       Operation *o;
+       ldap_pvt_thread_mutex_destroy( &slap_op_mutex );
+}
 
-       while ( (o = LDAP_STAILQ_FIRST( &slap_free_ops )) != NULL) {
-               LDAP_STAILQ_REMOVE_HEAD( &slap_free_ops, o_next );
-               LDAP_STAILQ_NEXT(o, o_next) = NULL;
-               ch_free( o );
+static void
+slap_op_q_destroy( void *key, void *data )
+{
+       Operation *op, *op2;
+       for ( op = data; op; op = op2 ) {
+               op2 = LDAP_STAILQ_NEXT( op, o_next );
+               ber_memfree_x( op, NULL );
        }
-       ldap_pvt_thread_mutex_destroy( &slap_op_mutex );
 }
 
 void
@@ -72,7 +73,7 @@ slap_op_groups_free( Operation *op )
 }
 
 void
-slap_op_free( Operation *op )
+slap_op_free( Operation *op, void *ctx )
 {
        OperationBuffer *opbuf;
 
@@ -110,15 +111,22 @@ slap_op_free( Operation *op )
        }
 #endif /* defined( LDAP_SLAPI ) */
 
-
        opbuf = (OperationBuffer *) op;
        memset( opbuf, 0, sizeof(*opbuf) );
        op->o_hdr = &opbuf->ob_hdr;
        op->o_controls = opbuf->ob_controls;
 
-       ldap_pvt_thread_mutex_lock( &slap_op_mutex );
-       LDAP_STAILQ_INSERT_HEAD( &slap_free_ops, op, o_next );
-       ldap_pvt_thread_mutex_unlock( &slap_op_mutex );
+       if ( ctx ) {
+               Operation *op2;
+               void *otmp = NULL;
+               ldap_pvt_thread_pool_getkey( ctx, (void *)slap_op_free, &otmp, NULL );
+               op2 = otmp;
+               LDAP_STAILQ_NEXT( op, o_next ) = op2;
+               ldap_pvt_thread_pool_setkey( ctx, (void *)slap_op_free, (void *)op,
+                       slap_op_q_destroy );
+       } else {
+               ber_memfree_x( op, NULL );
+       }
 }
 
 void
@@ -141,16 +149,21 @@ slap_op_alloc(
     BerElement         *ber,
     ber_int_t  msgid,
     ber_tag_t  tag,
-    ber_int_t  id )
+    ber_int_t  id,
+       void *ctx )
 {
-       Operation       *op;
-
-       ldap_pvt_thread_mutex_lock( &slap_op_mutex );
-       if ((op = LDAP_STAILQ_FIRST( &slap_free_ops ))) {
-               LDAP_STAILQ_REMOVE_HEAD( &slap_free_ops, o_next );
+       Operation       *op = NULL;
+
+       if ( ctx ) {
+               void *otmp = NULL;
+               ldap_pvt_thread_pool_getkey( ctx, (void *)slap_op_free, &otmp, NULL );
+               if ( otmp ) {
+                       op = otmp;
+                       otmp = LDAP_STAILQ_NEXT( op, o_next );
+                       ldap_pvt_thread_pool_setkey( ctx, (void *)slap_op_free, otmp,
+                               slap_op_q_destroy );
+               }
        }
-       ldap_pvt_thread_mutex_unlock( &slap_op_mutex );
-
        if (!op) {
                op = (Operation *) ch_calloc( 1, sizeof(OperationBuffer) );
                op->o_hdr = &((OperationBuffer *) op)->ob_hdr;
index fbbc9ae67535995552860bb2163c3f83d278082b..11f05fec56d1c6bdf559a3f0b549bfab003d8ac6 100644 (file)
@@ -736,11 +736,7 @@ LDAP_SLAPD_F (int) connection_state_closing LDAP_P(( Connection *c ));
 LDAP_SLAPD_F (const char *) connection_state2str LDAP_P(( int state ))
        LDAP_GCCATTR((const));
 
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
 LDAP_SLAPD_F (int) connection_read_activate LDAP_P((ber_socket_t s));
-#else
-LDAP_SLAPD_F (int) connection_read LDAP_P((ber_socket_t s));
-#endif
 LDAP_SLAPD_F (int) connection_write LDAP_P((ber_socket_t s));
 
 LDAP_SLAPD_F (unsigned long) connections_nextid(void);
@@ -1067,6 +1063,8 @@ LDAP_SLAPD_F (int)        slap_init LDAP_P((int mode, const char* name));
 LDAP_SLAPD_F (int)     slap_startup LDAP_P(( Backend *be ));
 LDAP_SLAPD_F (int)     slap_shutdown LDAP_P(( Backend *be ));
 LDAP_SLAPD_F (int)     slap_destroy LDAP_P((void));
+LDAP_SLAPD_F (void) slap_counters_init LDAP_P((slap_counters_t *sc));
+LDAP_SLAPD_F (void) slap_counters_destroy LDAP_P((slap_counters_t *sc));
 
 LDAP_SLAPD_V (char *)  slap_known_controls[];
 
@@ -1372,11 +1370,11 @@ LDAP_SLAPD_F (int) parse_oidm LDAP_P((
 LDAP_SLAPD_F (void) slap_op_init LDAP_P(( void ));
 LDAP_SLAPD_F (void) slap_op_destroy LDAP_P(( void ));
 LDAP_SLAPD_F (void) slap_op_groups_free LDAP_P(( Operation *op ));
-LDAP_SLAPD_F (void) slap_op_free LDAP_P(( Operation *op ));
+LDAP_SLAPD_F (void) slap_op_free LDAP_P(( Operation *op, void *ctx ));
 LDAP_SLAPD_F (void) slap_op_time LDAP_P(( time_t *t, int *n ));
 LDAP_SLAPD_F (Operation *) slap_op_alloc LDAP_P((
        BerElement *ber, ber_int_t msgid,
-       ber_tag_t tag, ber_int_t id ));
+       ber_tag_t tag, ber_int_t id, void *ctx ));
 
 LDAP_SLAPD_F (int) slap_op_add LDAP_P(( Operation **olist, Operation *op ));
 LDAP_SLAPD_F (int) slap_op_remove LDAP_P(( Operation **olist, Operation *op ));
index c3e3861590b8ac4e02d05487795e89fe5939d0dd..7be8d952494c4f50a856de25e982e7e63e31f708 100644 (file)
@@ -149,7 +149,6 @@ static long send_ldap_ber(
        /* write the pdu */
        while( 1 ) {
                int err;
-               ber_socket_t    sd;
 
                if ( connection_state_closing( conn ) ) {
                        ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
@@ -184,8 +183,7 @@ static long send_ldap_ber(
 
                /* wait for socket to be write-ready */
                conn->c_writewaiter = 1;
-               ber_sockbuf_ctrl( conn->c_sb, LBER_SB_OPT_GET_FD, &sd );
-               slapd_set_write( sd, 1 );
+               slapd_set_write( conn->c_sd, 1 );
 
                ldap_pvt_thread_cond_wait( &conn->c_write_cv, &conn->c_mutex );
                conn->c_writewaiter = 0;
@@ -508,10 +506,10 @@ send_ldap_response(
                goto cleanup;
        }
 
-       ldap_pvt_thread_mutex_lock( &slap_counters.sc_sent_mutex );
-       ldap_pvt_mp_add_ulong( slap_counters.sc_pdu, 1 );
-       ldap_pvt_mp_add_ulong( slap_counters.sc_bytes, (unsigned long)bytes );
-       ldap_pvt_thread_mutex_unlock( &slap_counters.sc_sent_mutex );
+       ldap_pvt_thread_mutex_lock( &op->o_counters->sc_mutex );
+       ldap_pvt_mp_add_ulong( op->o_counters->sc_pdu, 1 );
+       ldap_pvt_mp_add_ulong( op->o_counters->sc_bytes, (unsigned long)bytes );
+       ldap_pvt_thread_mutex_unlock( &op->o_counters->sc_mutex );
 
 cleanup:;
        /* Tell caller that we did this for real, as opposed to being
@@ -1194,11 +1192,11 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
                }
                rs->sr_nentries++;
 
-               ldap_pvt_thread_mutex_lock( &slap_counters.sc_sent_mutex );
-               ldap_pvt_mp_add_ulong( slap_counters.sc_bytes, (unsigned long)bytes );
-               ldap_pvt_mp_add_ulong( slap_counters.sc_entries, 1 );
-               ldap_pvt_mp_add_ulong( slap_counters.sc_pdu, 1 );
-               ldap_pvt_thread_mutex_unlock( &slap_counters.sc_sent_mutex );
+               ldap_pvt_thread_mutex_lock( &op->o_counters->sc_mutex );
+               ldap_pvt_mp_add_ulong( op->o_counters->sc_bytes, (unsigned long)bytes );
+               ldap_pvt_mp_add_ulong( op->o_counters->sc_entries, 1 );
+               ldap_pvt_mp_add_ulong( op->o_counters->sc_pdu, 1 );
+               ldap_pvt_thread_mutex_unlock( &op->o_counters->sc_mutex );
        }
 
        Statslog( LDAP_DEBUG_STATS2, "%s ENTRY dn=\"%s\"\n",
@@ -1361,11 +1359,11 @@ slap_send_search_reference( Operation *op, SlapReply *rs )
        if ( bytes < 0 ) {
                rc = LDAP_UNAVAILABLE;
        } else {
-               ldap_pvt_thread_mutex_lock( &slap_counters.sc_sent_mutex );
-               ldap_pvt_mp_add_ulong( slap_counters.sc_bytes, (unsigned long)bytes );
-               ldap_pvt_mp_add_ulong( slap_counters.sc_refs, 1 );
-               ldap_pvt_mp_add_ulong( slap_counters.sc_pdu, 1 );
-               ldap_pvt_thread_mutex_unlock( &slap_counters.sc_sent_mutex );
+               ldap_pvt_thread_mutex_lock( &op->o_counters->sc_mutex );
+               ldap_pvt_mp_add_ulong( op->o_counters->sc_bytes, (unsigned long)bytes );
+               ldap_pvt_mp_add_ulong( op->o_counters->sc_refs, 1 );
+               ldap_pvt_mp_add_ulong( op->o_counters->sc_pdu, 1 );
+               ldap_pvt_thread_mutex_unlock( &op->o_counters->sc_mutex );
        }
 #ifdef LDAP_CONNECTIONLESS
        }
index eae710d0ce47fe862f5e7591eb49fc83cfccfe93..8e12ed64c6f2224a8c0e9ee9588b631006771800 100644 (file)
@@ -58,8 +58,6 @@
 
 LDAP_BEGIN_DECL
 
-#define SLAP_LIGHTWEIGHT_DISPATCHER /* experimental slapd architecture */
-
 #ifdef LDAP_DEVEL
 #define LDAP_COLLECTIVE_ATTRIBUTES
 #define LDAP_COMP_MATCH
@@ -2390,6 +2388,39 @@ struct slap_control_ids {
        int sc_valuesReturnFilter;
 };
 
+/*
+ * Operation indices
+ */
+typedef enum {
+       SLAP_OP_BIND = 0,
+       SLAP_OP_UNBIND,
+       SLAP_OP_SEARCH,
+       SLAP_OP_COMPARE,
+       SLAP_OP_MODIFY,
+       SLAP_OP_MODRDN,
+       SLAP_OP_ADD,
+       SLAP_OP_DELETE,
+       SLAP_OP_ABANDON,
+       SLAP_OP_EXTENDED,
+       SLAP_OP_LAST
+} slap_op_t;
+
+typedef struct slap_counters_t {
+       struct slap_counters_t  *sc_next;
+       ldap_pvt_thread_mutex_t sc_mutex;
+       ldap_pvt_mp_t           sc_bytes;
+       ldap_pvt_mp_t           sc_pdu;
+       ldap_pvt_mp_t           sc_entries;
+       ldap_pvt_mp_t           sc_refs;
+
+       ldap_pvt_mp_t           sc_ops_completed;
+       ldap_pvt_mp_t           sc_ops_initiated;
+#ifdef SLAPD_MONITOR
+       ldap_pvt_mp_t           sc_ops_completed_[SLAP_OP_LAST];
+       ldap_pvt_mp_t           sc_ops_initiated_[SLAP_OP_LAST];
+#endif /* SLAPD_MONITOR */
+} slap_counters_t;
+
 /*
  * represents an operation pending from an ldap client
  */
@@ -2407,6 +2438,8 @@ typedef struct Opheader {
        void    *oh_tmpmemctx;          /* slab malloc context */
        BerMemoryFunctions *oh_tmpmfuncs;
 
+       slap_counters_t *oh_counters;
+
        char            oh_log_prefix[ /* sizeof("conn=18446744073709551615 op=18446744073709551615") */ SLAP_TEXT_BUFLEN ];
 
 #ifdef LDAP_SLAPI
@@ -2439,6 +2472,7 @@ struct Operation {
 #define o_threadctx o_hdr->oh_threadctx
 #define o_tmpmemctx o_hdr->oh_tmpmemctx
 #define o_tmpmfuncs o_hdr->oh_tmpmfuncs
+#define o_counters o_hdr->oh_counters
 
 #define        o_tmpalloc      o_tmpmfuncs->bmf_malloc
 #define o_tmpcalloc    o_tmpmfuncs->bmf_calloc
@@ -2668,6 +2702,7 @@ struct Connection {
        int                     c_struct_state; /* structure management state */
        int                     c_conn_state;   /* connection state */
        int                     c_conn_idx;             /* slot in connections array */
+       ber_socket_t    c_sd;
        const char      *c_close_reason; /* why connection is closing */
 
        ldap_pvt_thread_mutex_t c_mutex; /* protect the connection */
@@ -2685,7 +2720,6 @@ struct Connection {
 #define c_sock_name c_listener->sl_name        /* sock name (trans=addr:port) */
 
        /* only can be changed by binding thread */
-       int             c_sasl_bind_in_progress;        /* multi-op bind in progress */
        struct berval   c_sasl_bind_mech;                       /* mech in progress */
        struct berval   c_sasl_dn;      /* temporary storage */
        struct berval   c_sasl_authz_dn;        /* SASL proxy authz */
@@ -2712,7 +2746,10 @@ struct Connection {
        ldap_pvt_thread_cond_t  c_write_cv;             /* used to wait for sd write-ready*/
 
        BerElement      *c_currentber;  /* ber we're attempting to read */
-       int             c_writewaiter;  /* true if writer is waiting */
+
+       char            c_sasl_bind_in_progress;        /* multi-op bind in progress */
+
+       char            c_writewaiter;  /* true if writer is waiting */
 
 #define        CONN_IS_TLS     1
 #define        CONN_IS_UDP     2
@@ -2720,14 +2757,14 @@ struct Connection {
 #define        CONN_IS_IPC     8
 
 #ifdef LDAP_CONNECTIONLESS
-       int     c_is_udp;               /* true if this is (C)LDAP over UDP */
+       char    c_is_udp;               /* true if this is (C)LDAP over UDP */
 #endif
 #ifdef HAVE_TLS
-       int     c_is_tls;               /* true if this LDAP over raw TLS */
-       int     c_needs_tls_accept;     /* true if SSL_accept should be called */
+       char    c_is_tls;               /* true if this LDAP over raw TLS */
+       char    c_needs_tls_accept;     /* true if SSL_accept should be called */
 #endif
-       int             c_sasl_layers;   /* true if we need to install SASL i/o handlers */
-       int     c_sasl_done;            /* SASL completed once */
+       char    c_sasl_layers;   /* true if we need to install SASL i/o handlers */
+       char    c_sasl_done;            /* SASL completed once */
        void    *c_sasl_authctx;        /* SASL authentication context */
        void    *c_sasl_sockctx;        /* SASL security layer context */
        void    *c_sasl_extra;          /* SASL session extra stuff */
@@ -2810,47 +2847,12 @@ struct slap_listener {
        int     sl_is_udp;              /* UDP listener is also data port */
 #endif
        int     sl_mute;        /* Listener is temporarily disabled due to emfile */
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
        int     sl_busy;        /* Listener is busy (accept thread activated) */
-#endif
        ber_socket_t sl_sd;
        Sockaddr sl_sa;
 #define sl_addr        sl_sa.sa_in_addr
 };
 
-/*
- * Operation indices
- */
-typedef enum {
-       SLAP_OP_BIND = 0,
-       SLAP_OP_UNBIND,
-       SLAP_OP_SEARCH,
-       SLAP_OP_COMPARE,
-       SLAP_OP_MODIFY,
-       SLAP_OP_MODRDN,
-       SLAP_OP_ADD,
-       SLAP_OP_DELETE,
-       SLAP_OP_ABANDON,
-       SLAP_OP_EXTENDED,
-       SLAP_OP_LAST
-} slap_op_t;
-
-typedef struct slap_counters_t {
-       ldap_pvt_thread_mutex_t sc_sent_mutex;
-       ldap_pvt_mp_t           sc_bytes;
-       ldap_pvt_mp_t           sc_pdu;
-       ldap_pvt_mp_t           sc_entries;
-       ldap_pvt_mp_t           sc_refs;
-
-       ldap_pvt_thread_mutex_t sc_ops_mutex;
-       ldap_pvt_mp_t           sc_ops_completed;
-       ldap_pvt_mp_t           sc_ops_initiated;
-#ifdef SLAPD_MONITOR
-       ldap_pvt_mp_t           sc_ops_completed_[SLAP_OP_LAST];
-       ldap_pvt_mp_t           sc_ops_initiated_[SLAP_OP_LAST];
-#endif /* SLAPD_MONITOR */
-} slap_counters_t;
-
 /*
  * Better know these all around slapd
  */