]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
Do not unlock upstream without referencing its dying ops
authorOndřej Kuzník <okuznik@symas.com>
Tue, 20 Mar 2018 17:25:11 +0000 (17:25 +0000)
committerOndřej Kuzník <okuznik@symas.com>
Tue, 17 Nov 2020 17:58:15 +0000 (17:58 +0000)
servers/lloadd/operation.c
servers/lloadd/upstream.c

index efd2531a5afb1179d6d25adcb36e7e2df6530cb4..c9e69cd94d276a7d8343975230c6d30f36ce897b 100644 (file)
@@ -806,16 +806,11 @@ void
 operation_lost_upstream( LloadOperation *op )
 {
     LloadConnection *c = op->o_upstream;
-    CONNECTION_LOCK(c);
-    op->o_res = LLOAD_OP_FAILED;
-    op->o_upstream_refcnt++;
-    /* Matching the op reference on the connection as well */
-    CONNECTION_UNLOCK_INCREF(c);
 
     operation_send_reject( op, LDAP_UNAVAILABLE,
             "connection to the remote server has been severed", 0 );
 
-    CONNECTION_LOCK_DECREF(c);
+    CONNECTION_LOCK(c);
     op->o_upstream_refcnt--;
     operation_destroy_from_upstream( op );
     CONNECTION_UNLOCK(c);
index a1d17ab9bfc839ba21fc7fc8c5869c5fb4e55602..391b609108924036d6fdcace7168f5b78cab8f84 100644 (file)
@@ -760,7 +760,7 @@ upstream_destroy( LloadConnection *c )
 {
     LloadBackend *b = c->c_private;
     struct event *read_event, *write_event;
-    TAvlnode *root;
+    TAvlnode *root, *node;
     long freed, executing;
     enum sc_state state;
 
@@ -780,6 +780,14 @@ upstream_destroy( LloadConnection *c )
     read_event = c->c_read_event;
     write_event = c->c_write_event;
 
+    for ( node = tavl_end( root, TAVL_DIR_LEFT ); node;
+            node = tavl_next( node, TAVL_DIR_RIGHT ) ) {
+        LloadOperation *op = node->avl_data;
+
+        op->o_res = LLOAD_OP_FAILED;
+        op->o_upstream_refcnt++;
+    }
+
     CONNECTION_UNLOCK_INCREF(c);
 
     freed = tavl_free( root, (AVL_FREE)operation_lost_upstream );