ITS#4108 Cleanup accept/close race conditions.

This commit is contained in:
Howard Chu 2005-10-29 04:17:56 +00:00
parent 638b84db6e
commit 4bb234bac8
3 changed files with 43 additions and 21 deletions

View file

@ -844,17 +844,19 @@ connection_destroy( Connection *c )
}
ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_GET_FD, &sd );
slapd_sd_lock();
ber_sockbuf_free( c->c_sb );
if ( sd != AC_SOCKET_INVALID ) {
slapd_remove( sd, 1, 0 );
slapd_remove( sd, 1, 0, 1 );
Statslog( LDAP_DEBUG_STATS, (close_reason
? "conn=%lu fd=%ld closed (%s)\n"
: "conn=%lu fd=%ld closed\n"),
connid, (long) sd, close_reason, 0, 0 );
} else {
slapd_sd_unlock();
}
ber_sockbuf_free( c->c_sb );
c->c_sb = ber_sockbuf_alloc( );
{
@ -1389,6 +1391,7 @@ void connection_client_stop(
c->c_conn_state = SLAP_C_INVALID;
c->c_struct_state = SLAP_C_UNUSED;
c->c_close_reason = "?"; /* should never be needed */
slapd_sd_lock();
ber_sockbuf_free( c->c_sb );
c->c_sb = ber_sockbuf_alloc( );
{
@ -1396,7 +1399,7 @@ void connection_client_stop(
ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_SET_MAX_INCOMING, &max );
}
slapd_remove( s, 0, 1 );
slapd_remove( s, 0, 1, 1 );
connection_return( c );
}
@ -1414,15 +1417,13 @@ static void* connection_read_thread( void* ctx, void* argv )
* the first one is returned with new_op
*/
if( ( rc = connection_read( s, &new_op ) ) < 0 ) {
Debug( LDAP_DEBUG_TRACE, "connection_read(%d) error\n", s, 0, 0 );
tcp_close( s );
Debug( LDAP_DEBUG_CONNS, "connection_read(%d) error\n", s, 0, 0 );
return (void*)(long)rc;
}
/* execute the queued request in the same thread */
if( new_op ) {
rc = (long)connection_operation(
ldap_pvt_thread_pool_context(), new_op );
rc = (long)connection_operation( ctx, new_op );
}
return (void*)(long)rc;
@ -1437,7 +1438,9 @@ int connection_read_activate( ber_socket_t s )
* thread reads data on it. Otherwise the listener thread will repeatedly
* submit the same event on it to the pool.
*/
slapd_clr_read( s, 0 );
rc = slapd_clr_read( s, 0 );
if ( rc )
return rc;
rc = ldap_pvt_thread_pool_submit( &connection_pool,
connection_read_thread, (void *)(long)s );
@ -1473,7 +1476,6 @@ int connection_read(ber_socket_t s)
Debug( LDAP_DEBUG_ANY,
"connection_read(%ld): no connection!\n",
(long) s, 0, 0 );
slapd_remove(s, 1, 0);
ldap_pvt_thread_mutex_unlock( MCA_GET_CONN_MUTEX(s) );
return -1;
@ -2080,7 +2082,6 @@ int connection_write(ber_socket_t s)
Debug( LDAP_DEBUG_ANY,
"connection_write(%ld): no connection!\n",
(long)s, 0, 0 );
slapd_remove(s, 1, 0);
ldap_pvt_thread_mutex_unlock( MCA_GET_CONN_MUTEX( s ) );
return -1;
}

View file

@ -452,18 +452,32 @@ static void slapd_add(ber_socket_t s, int isactive, Listener *sl) {
#endif
}
void slapd_sd_lock()
{
ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
}
void slapd_sd_unlock()
{
ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
}
/*
* Remove the descriptor from daemon control
*/
void slapd_remove(
ber_socket_t s,
int wasactive,
int wake )
int wake,
int locked )
{
int waswriter;
int wasreader;
ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
if ( !locked )
ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
assert( SLAP_SOCK_IS_ACTIVE( s ));
if ( wasactive ) slap_daemon.sd_nactives--;
@ -533,14 +547,18 @@ void slapd_set_write(ber_socket_t s, int wake) {
WAKE_LISTENER(wake);
}
void slapd_clr_read(ber_socket_t s, int wake) {
int slapd_clr_read(ber_socket_t s, int wake) {
int rc = 1;
ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex );
assert( SLAP_SOCK_IS_ACTIVE( s ));
SLAP_SOCK_CLR_READ( s );
if ( SLAP_SOCK_IS_ACTIVE( s )) {
SLAP_SOCK_CLR_READ( s );
rc = 0;
}
ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
WAKE_LISTENER(wake);
if ( !rc )
WAKE_LISTENER(wake);
return rc;
}
void slapd_set_read(ber_socket_t s, int wake) {
@ -1212,7 +1230,7 @@ close_listeners(
Listener *lr = slap_listeners[l];
if ( lr->sl_sd != AC_SOCKET_INVALID ) {
if ( remove ) slapd_remove( lr->sl_sd, 0, 0 );
if ( remove ) slapd_remove( lr->sl_sd, 0, 0, 0 );
#ifdef LDAP_PF_LOCAL
if ( lr->sl_sa.sa_addr.sa_family == AF_LOCAL ) {

View file

@ -718,7 +718,10 @@ LDAP_SLAPD_F (int) slapd_daemon_init( const char *urls );
LDAP_SLAPD_F (int) slapd_daemon_destroy(void);
LDAP_SLAPD_F (int) slapd_daemon(void);
LDAP_SLAPD_F (Listener **) slapd_get_listeners LDAP_P((void));
LDAP_SLAPD_F (void) slapd_remove LDAP_P((ber_socket_t s, int wasactive, int wake));
LDAP_SLAPD_F (void) slapd_remove LDAP_P((ber_socket_t s, int wasactive,
int wake, int locked ));
LDAP_SLAPD_F (void) slapd_sd_lock();
LDAP_SLAPD_F (void) slapd_sd_unlock();
LDAP_SLAPD_F (RETSIGTYPE) slap_sig_shutdown LDAP_P((int sig));
LDAP_SLAPD_F (RETSIGTYPE) slap_sig_wake LDAP_P((int sig));
@ -727,7 +730,7 @@ LDAP_SLAPD_F (void) slap_wake_listener LDAP_P((void));
LDAP_SLAPD_F (void) slapd_set_write LDAP_P((ber_socket_t s, int wake));
LDAP_SLAPD_F (void) slapd_clr_write LDAP_P((ber_socket_t s, int wake));
LDAP_SLAPD_F (void) slapd_set_read LDAP_P((ber_socket_t s, int wake));
LDAP_SLAPD_F (void) slapd_clr_read LDAP_P((ber_socket_t s, int wake));
LDAP_SLAPD_F (int) slapd_clr_read LDAP_P((ber_socket_t s, int wake));
LDAP_SLAPD_V (volatile sig_atomic_t) slapd_abrupt_shutdown;
LDAP_SLAPD_V (volatile sig_atomic_t) slapd_shutdown;