From: Ondřej Kuzník Date: Tue, 13 Jun 2017 18:40:50 +0000 (+0100) Subject: Handle upstream connection shutdown properly X-Git-Tag: OPENLDAP_REL_ENG_2_5_1ALPHA~18^2~155 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5b1ad431789d4e5bc3f4370f72516be026c75997;p=thirdparty%2Fopenldap.git Handle upstream connection shutdown properly --- diff --git a/servers/lloadd/backend.c b/servers/lloadd/backend.c index 93e12e923a..8628d46264 100644 --- a/servers/lloadd/backend.c +++ b/servers/lloadd/backend.c @@ -320,29 +320,17 @@ backends_destroy( void ) while ( !LDAP_CIRCLEQ_EMPTY( &b->b_bindconns ) ) { Connection *c = LDAP_CIRCLEQ_FIRST( &b->b_bindconns ); - TAvlnode *root; - long freed; CONNECTION_LOCK(c); Debug( LDAP_DEBUG_CONNS, "backends_destroy: " "destroying bind connection connid=%lu, pending ops=%ld\n", c->c_connid, c->c_n_ops_executing ); - root = c->c_ops; - c->c_ops = NULL; - CONNECTION_UNLOCK_INCREF(c); - - freed = tavl_free( root, (AVL_FREE)operation_lost_upstream ); - - CONNECTION_LOCK_DECREF(c); - assert( freed == c->c_n_ops_executing ); assert( c->c_live ); UPSTREAM_DESTROY(c); } while ( !LDAP_CIRCLEQ_EMPTY( &b->b_conns ) ) { Connection *c = LDAP_CIRCLEQ_FIRST( &b->b_conns ); - TAvlnode *root; - long freed; CONNECTION_LOCK(c); Debug( LDAP_DEBUG_CONNS, "backends_destroy: " @@ -350,14 +338,6 @@ backends_destroy( void ) "ops=%ld\n", c->c_connid, c->c_n_ops_executing ); - root = c->c_ops; - c->c_ops = NULL; - CONNECTION_UNLOCK_INCREF(c); - - freed = tavl_free( root, (AVL_FREE)operation_lost_upstream ); - - CONNECTION_LOCK_DECREF(c); - assert( freed == c->c_n_ops_executing ); assert( c->c_live ); UPSTREAM_DESTROY(c); } diff --git a/servers/lloadd/client.c b/servers/lloadd/client.c index 8063eb987a..239ca00f32 100644 --- a/servers/lloadd/client.c +++ b/servers/lloadd/client.c @@ -225,6 +225,9 @@ client_write_cb( evutil_socket_t s, short what, void *arg ) } CONNECTION_UNLOCK_INCREF(c); + /* Before we acquire any locks */ + event_del( c->c_write_event ); + ldap_pvt_thread_mutex_lock( &c->c_io_mutex ); Debug( LDAP_DEBUG_CONNS, "client_write_cb: " "have something to write to client %lu\n", diff --git a/servers/lloadd/upstream.c b/servers/lloadd/upstream.c index c632ab080f..19fd327e88 100644 --- a/servers/lloadd/upstream.c +++ b/servers/lloadd/upstream.c @@ -711,6 +711,9 @@ upstream_write_cb( evutil_socket_t s, short what, void *arg ) } CONNECTION_UNLOCK_INCREF(c); + /* Before we acquire any locks */ + event_del( c->c_write_event ); + ldap_pvt_thread_mutex_lock( &c->c_io_mutex ); Debug( LDAP_DEBUG_CONNS, "upstream_write_cb: " "have something to write to upstream %lu\n", @@ -892,6 +895,8 @@ upstream_destroy( Connection *c ) { Backend *b = c->c_private; struct event *read_event, *write_event; + TAvlnode *root; + long freed; Debug( LDAP_DEBUG_CONNS, "upstream_destroy: " "freeing connection %lu\n", @@ -899,10 +904,15 @@ upstream_destroy( Connection *c ) c->c_state = SLAP_C_INVALID; + root = c->c_ops; + c->c_ops = NULL; + read_event = c->c_read_event; write_event = c->c_write_event; CONNECTION_UNLOCK_INCREF(c); + freed = tavl_free( root, (AVL_FREE)operation_lost_upstream ); + /* * Avoid a deadlock: * event_del will block if the event is currently executing its callback,