mirror of
https://git.openldap.org/openldap/openldap.git
synced 2026-01-09 00:14:25 -05:00
ITS#4108 Cleanup accept/close race conditions.
This commit is contained in:
parent
638b84db6e
commit
4bb234bac8
3 changed files with 43 additions and 21 deletions
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 ) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue