]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
Handle upstream connection shutdown properly
authorOndřej Kuzník <ondra@mistotebe.net>
Tue, 13 Jun 2017 18:40:50 +0000 (19:40 +0100)
committerOndřej Kuzník <okuznik@symas.com>
Tue, 17 Nov 2020 17:55:46 +0000 (17:55 +0000)
servers/lloadd/backend.c
servers/lloadd/client.c
servers/lloadd/upstream.c

index 93e12e923a75ff8e99e3726045b5f7230032aef1..8628d4626477ff053e4bdc525e7e3fec3516bd78 100644 (file)
@@ -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);
         }
index 8063eb987a8ddd27c38a9e5edf6fdee33305bb65..239ca00f327fe679419fa06e7e146db99395bc76 100644 (file)
@@ -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",
index c632ab080f4514cd4675d060924e759786fc5b1f..19fd327e880a2b448016f8f1de16373cacb2dcd5 100644 (file)
@@ -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,