/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
- * Copyright 1998-2006 The OpenLDAP Foundation.
+ * Copyright 1998-2007 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
ber_socket_t i;
for ( i = 0; i < dtblsize; i++ ) {
- if( connections[i].c_struct_state != SLAP_C_USED ) {
- continue;
- }
- /* give persistent clients a chance to cleanup */
- if( connections[i].c_conn_state == SLAP_C_CLIENT ) {
- ldap_pvt_thread_pool_submit( &connection_pool,
- connections[i].c_clientfunc, connections[i].c_clientarg );
- continue;
+ if( connections[i].c_struct_state != SLAP_C_UNINITIALIZED ) {
+ ldap_pvt_thread_mutex_lock( &connections[i].c_mutex );
+ if( connections[i].c_struct_state == SLAP_C_USED ) {
+
+ /* give persistent clients a chance to cleanup */
+ if( connections[i].c_conn_state == SLAP_C_CLIENT ) {
+ ldap_pvt_thread_pool_submit( &connection_pool,
+ connections[i].c_clientfunc, connections[i].c_clientarg );
+ } else {
+ /* c_mutex is locked */
+ connection_closing( &connections[i], "slapd shutdown" );
+ connection_close( &connections[i] );
+ }
+ }
+ ldap_pvt_thread_mutex_unlock( &connections[i].c_mutex );
}
-
- ldap_pvt_thread_mutex_lock( &connections[i].c_mutex );
-
- /* c_mutex is locked */
- connection_closing( &connections[i], "slapd shutdown" );
- connection_close( &connections[i] );
-
- ldap_pvt_thread_mutex_unlock( &connections[i].c_mutex );
}
return 0;
if( c != NULL ) {
ber_socket_t sd;
- assert( c->c_struct_state != SLAP_C_UNINITIALIZED );
-
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 ) {
+ ldap_pvt_thread_mutex_unlock( &c->c_mutex );
+ return NULL;
+ }
+#endif
if( c->c_struct_state != SLAP_C_USED ) {
/* connection must have been closed due to resched */
if ( sd != AC_SOCKET_INVALID ) {
slapd_remove( sd, sb, 1, 0, 0 );
- Statslog( LDAP_DEBUG_STATS, (close_reason
- ? "conn=%lu fd=%ld closed (%s)\n"
- : "conn=%lu fd=%ld closed\n"),
- connid, (long) sd, close_reason, 0, 0 );
+ if ( close_reason == NULL ) {
+ Statslog( LDAP_DEBUG_STATS, "conn=%lu fd=%ld closed\n",
+ connid, (long) sd, 0, 0, 0 );
+ } else {
+ Statslog( LDAP_DEBUG_STATS, "conn=%lu fd=%ld closed (%s)\n",
+ connid, (long) sd, close_reason, 0, 0 );
+ }
}
}
/* wake write blocked operations */
if ( c->c_writewaiter ) {
ldap_pvt_thread_cond_signal( &c->c_write_cv );
- ldap_pvt_thread_mutex_unlock( &c->c_mutex );
+ /* ITS#4667 this may allow another thread to drop into
+ * connection_resched / connection_close before we
+ * finish, but that's OK.
+ */
slapd_clr_write( 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 );
assert( connections != NULL );
assert( c != NULL );
- if ( c->c_conn_state != SLAP_C_CLOSING )
+ /* ITS#4667 we may have gotten here twice */
+ if ( c->c_conn_state == SLAP_C_INVALID )
return;
assert( c->c_struct_state == SLAP_C_USED );
+ assert( c->c_conn_state == SLAP_C_CLOSING );
/* NOTE: c_mutex should be locked by caller */
ber_sockbuf_ctrl( conn->c_sb, LBER_SB_OPT_GET_FD, &sd );
- Debug( LDAP_DEBUG_TRACE,
- "ber_get_next on fd %d failed errno=%d (%s)\n",
- sd, err, sock_errstr(err) );
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) );
ber_free( conn->c_currentber, 1 );
conn->c_currentber = NULL;
{
op->o_conn->c_sasl_bindop = NULL;
+ ch_free( op->o_callback );
+ op->o_callback = NULL;
+
return SLAP_CB_CONTINUE;
}
static int connection_bind_cb( Operation *op, SlapReply *rs )
{
ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
- op->o_conn->c_conn_state = SLAP_C_ACTIVE;
+ if ( op->o_conn->c_conn_state == SLAP_C_BINDING )
+ op->o_conn->c_conn_state = SLAP_C_ACTIVE;
op->o_conn->c_sasl_bind_in_progress =
( rs->sr_err == LDAP_SASL_BIND_IN_PROGRESS );