]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
Handle a client connection disconnected from op
authorOndřej Kuzník <ondra@mistotebe.net>
Tue, 11 Jul 2017 12:08:21 +0000 (13:08 +0100)
committerOndřej Kuzník <okuznik@symas.com>
Tue, 17 Nov 2020 17:55:46 +0000 (17:55 +0000)
servers/lloadd/bind.c
servers/lloadd/operation.c
servers/lloadd/upstream.c

index 393989f76c2fa8c98be4d061723d3182e4972695..d19aa782a7ef29b465067277416f6410c7c25670 100644 (file)
@@ -263,7 +263,6 @@ void
 client_reset( Connection *c )
 {
     TAvlnode *root;
-    int freed;
 
     root = c->c_ops;
     c->c_ops = NULL;
@@ -292,19 +291,8 @@ client_reset( Connection *c )
     CONNECTION_UNLOCK_INCREF(c);
 
     if ( root ) {
-        TAvlnode *node = tavl_end( root, TAVL_DIR_LEFT );
-        do {
-            Operation *op = node->avl_data;
-
-            operation_abandon( op );
-
-            CONNECTION_LOCK(c);
-            op->o_client_refcnt--;
-            operation_destroy_from_client( op );
-            CONNECTION_UNLOCK(c);
-        } while ( (node = tavl_next( node, TAVL_DIR_RIGHT )) );
-
-        freed = tavl_free( root, NULL );
+        int freed;
+        freed = tavl_free( root, (AVL_FREE)operation_abandon );
         Debug( LDAP_DEBUG_TRACE, "client_reset: "
                 "dropped %d operations\n",
                 freed );
index 37abe89b649d415c9d6f2a9a08e0c2e236438dbe..f5a9b6a0152d73185dfc5612068507be73ac585b 100644 (file)
@@ -513,6 +513,13 @@ fail:
     return NULL;
 }
 
+/*
+ * Will remove the operation from its upstream and if it was still there,
+ * sends an abandon request.
+ *
+ * Being called from client_reset or request_abandon, the following hold:
+ * - op->o_client_refcnt > 0 (and it follows that op->o_client != NULL)
+ */
 void
 operation_abandon( Operation *op )
 {
@@ -524,22 +531,15 @@ operation_abandon( Operation *op )
     ldap_pvt_thread_mutex_lock( &operation_mutex );
     c = op->o_upstream;
     if ( !c ) {
-        c = op->o_client;
-        assert( c );
-
-        /* Caller should hold a reference on client */
-        CONNECTION_LOCK(c);
         ldap_pvt_thread_mutex_unlock( &operation_mutex );
-        operation_destroy_from_client( op );
-        CLIENT_UNLOCK_OR_DESTROY(c);
-        return;
+        goto done;
     }
 
     CONNECTION_LOCK(c);
     ldap_pvt_thread_mutex_unlock( &operation_mutex );
     if ( tavl_delete( &c->c_ops, op, operation_upstream_cmp ) == NULL ) {
         /* The operation has already been abandoned or finished */
-        goto done;
+        goto unlock;
     }
     c->c_n_ops_executing--;
     b = (Backend *)c->c_private;
@@ -557,7 +557,7 @@ operation_abandon( Operation *op )
                 "ber_alloc failed\n" );
         ldap_pvt_thread_mutex_unlock( &c->c_io_mutex );
         CONNECTION_LOCK_DECREF(c);
-        goto done;
+        goto unlock;
     }
     c->c_pendingber = ber;
 
@@ -577,9 +577,18 @@ operation_abandon( Operation *op )
     }
 
     CONNECTION_LOCK_DECREF(c);
-done:
-    operation_destroy_from_upstream( op );
+unlock:
     UPSTREAM_UNLOCK_OR_DESTROY(c);
+
+done:
+    c = op->o_client;
+    assert( c );
+
+    /* Caller should hold a reference on client */
+    CONNECTION_LOCK(c);
+    op->o_client_refcnt--;
+    operation_destroy_from_client( op );
+    CONNECTION_UNLOCK(c);
 }
 
 int
index 40b125276bf3f95a6e93f8a90d29aa08cd977fee..c6d8bc2c7a76ea619d48140398450ee1ce560fd2 100644 (file)
@@ -418,8 +418,13 @@ handle_one_response( Connection *c )
         client = op->o_client;
         if ( client ) {
             CONNECTION_LOCK(client);
-            op->o_client_refcnt++;
-            CONNECTION_UNLOCK_INCREF(client);
+            if ( client->c_live ) {
+                op->o_client_refcnt++;
+                CONNECTION_UNLOCK_INCREF(client);
+            } else {
+                CONNECTION_UNLOCK(client);
+                client = NULL;
+            }
         }
         ldap_pvt_thread_mutex_unlock( &operation_mutex );