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))
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
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
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
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
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;
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
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));
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 */
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
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
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 )
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 )
{
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 */
} 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...
/* 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;
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;
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);
}
(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);
}
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 */
*/
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;
}
/*
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;
}
}
struct berval rdn;
int i;
Attribute *a;
+ slap_counters_t *sc;
static struct berval bv_ops = BER_BVC( "cn=operations" );
assert( mi != NULL );
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;
}
}
struct berval nrdn;
ldap_pvt_mp_t n;
Attribute *a;
+ slap_counters_t *sc;
int i;
assert( mi != NULL );
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 );
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;
}
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 );
#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 )
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;
}
* so don't assert details here.
*/
- if( sd == s ) {
+ if( connections[i].c_sd == s ) {
c = &connections[i];
break;
}
#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;
}
/* 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",
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 )
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;
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;
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 );
assert( c->c_writewaiter == 0);
c->c_listener = listener;
+ c->c_sd = s;
if ( flags & CONN_IS_CLIENT ) {
c->c_connid = 0;
static void
connection_destroy( Connection *c )
{
- ber_socket_t sd;
unsigned long connid;
const char *close_reason;
Sockbuf *sb;
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;
}
}
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 */
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 );
}
}
/* 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 );
* 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 ) {
static void
connection_close( Connection *c )
{
- ber_socket_t sd = AC_SOCKET_INVALID;
-
assert( connections != NULL );
assert( c != NULL );
/* 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 );
}
/* 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 */
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 )
{
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 );
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++;
connection_resched( conn );
ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
+ slap_op_free( op, ctx );
return NULL;
}
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 )
* 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;
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;
}
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;
}
/* 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;
}
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;
}
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 ));
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;
char *cdn = NULL;
#endif
char *defer = NULL;
+ void *ctx;
if ( conn->c_currentber == NULL &&
( conn->c_currentber = ber_alloc()) == NULL )
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;
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 */
} 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.
}
connection_op_activate( op );
}
-#else
- connection_op_activate( op );
-#endif
}
#ifdef NO_THREADS
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;
}
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;
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 );
# 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))
# 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))
ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
WAKE_LISTENER(1);
-#endif /* SLAP_LIGHTWEIGHT_DISPATCHER */
}
/*
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 ) ) {
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();
return 0;
}
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
static void*
slap_listener_thread(
void* ctx,
}
return rc;
}
-#endif /* SLAP_LIGHTWEIGHT_DISPATCHER */
static void *
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: "
slapd_shutdown = 2;
return (void*)-1;
}
-#endif /* SLAP_LIGHTWEIGHT_DISPATCHER */
slapd_add( slap_listeners[l]->sl_sd, 0, slap_listeners[l] );
}
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 {
continue;
}
-#ifdef SLAP_LIGHTWEIGHT_DISPATCHER
if ( lr->sl_busy ) {
Debug( LDAP_DEBUG_CONNS,
"daemon: " SLAP_EVENT_FNAME ": "
lr->sl_sd, 0, 0 );
continue;
}
-#endif /* SLAP_LIGHTWEIGHT_DISPATCHER */
Debug( LDAP_DEBUG_CONNS,
"daemon: " SLAP_EVENT_FNAME ": "
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 */
* 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 */
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
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 );
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;
slap_init( int mode, const char *name )
{
int rc;
- int i;
assert( mode );
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();
int slap_destroy(void)
{
int rc;
- int i;
Debug( LDAP_DEBUG_TRACE,
"%s destroy: freeing system resources.\n",
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:
/* 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 */
+}
+
#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
}
void
-slap_op_free( Operation *op )
+slap_op_free( Operation *op, void *ctx )
{
OperationBuffer *opbuf;
}
#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
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;
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);
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[];
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 ));
/* write the pdu */
while( 1 ) {
int err;
- ber_socket_t sd;
if ( connection_state_closing( conn ) ) {
ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
/* 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;
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
}
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",
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
}
LDAP_BEGIN_DECL
-#define SLAP_LIGHTWEIGHT_DISPATCHER /* experimental slapd architecture */
-
#ifdef LDAP_DEVEL
#define LDAP_COLLECTIVE_ATTRIBUTES
#define LDAP_COMP_MATCH
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
*/
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
#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
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 */
#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 */
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
#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 */
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
*/