]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
Refactor operation_send_reject
authorOndřej Kuzník <ondra@mistotebe.net>
Fri, 22 Sep 2017 10:26:26 +0000 (11:26 +0100)
committerOndřej Kuzník <okuznik@symas.com>
Tue, 17 Nov 2020 17:55:46 +0000 (17:55 +0000)
servers/lloadd/client.c
servers/lloadd/operation.c
servers/lloadd/proto-slap.h

index 915e90e61dde0e7ac58207344a1e5bc2d1b1dc09..189f895863aa3b8fade088e1877a66cc2ef38d13 100644 (file)
@@ -67,14 +67,8 @@ handle_one_request( Connection *c )
             break;
         default:
             if ( c->c_state == SLAP_C_BINDING ) {
-                op->o_client_refcnt++;
-                CONNECTION_UNLOCK_INCREF(c);
-                operation_send_reject(
+                return operation_send_reject_locked(
                         op, LDAP_PROTOCOL_ERROR, "bind in progress", 0 );
-                CONNECTION_LOCK_DECREF(c);
-                op->o_client_refcnt--;
-                operation_destroy_from_client( op );
-                return LDAP_SUCCESS;
             }
             handler = request_process;
             break;
index 568f8ea1bde79eb710c9ddd00f8e1a04d73ac02a..7b44cfe6f1115290963715b9253e99759f84b464 100644 (file)
@@ -620,11 +620,10 @@ request_abandon( Connection *c, Operation *op )
                 "connid=%lu msgid=%d invalid integer sent in abandon request\n",
                 c->c_connid, op->o_client_msgid );
 
-        CONNECTION_UNLOCK_INCREF(c);
-        operation_send_reject(
-                op, LDAP_PROTOCOL_ERROR, "invalid PDU received", 0 );
-        CONNECTION_LOCK_DECREF(c);
-        CONNECTION_DESTROY(c);
+        if ( operation_send_reject_locked( op, LDAP_PROTOCOL_ERROR,
+                     "invalid PDU received", 0 ) == LDAP_SUCCESS ) {
+            CONNECTION_DESTROY(c);
+        }
         return -1;
     }
 
@@ -657,43 +656,27 @@ done:
     return rc;
 }
 
-void
-operation_send_reject(
+/*
+ * Called with op->o_client non-NULL and already locked.
+ */
+int
+operation_send_reject_locked(
         Operation *op,
         int result,
         const char *msg,
         int send_anyway )
 {
-    Connection *c;
+    Connection *c = op->o_client;
     BerElement *ber;
     int found;
 
-    Debug( LDAP_DEBUG_TRACE, "operation_send_reject: "
+    Debug( LDAP_DEBUG_TRACE, "operation_send_reject_locked: "
             "rejecting %s from client connid=%lu with message: \"%s\"\n",
-            slap_msgtype2str( op->o_tag ), op->o_client_connid, msg );
-
-    ldap_pvt_thread_mutex_lock( &op->o_link_mutex );
-    c = op->o_client;
-    if ( !c ) {
-        c = op->o_upstream;
-        /* One of the connections has initiated this and keeps a reference, if
-         * client is dead, it must have been the upstream */
-        assert( c );
-        CONNECTION_LOCK(c);
-        ldap_pvt_thread_mutex_unlock( &op->o_link_mutex );
-        Debug( LDAP_DEBUG_TRACE, "operation_send_reject: "
-                "not sending msgid=%d, client connid=%lu is dead\n",
-                op->o_client_msgid, op->o_client_connid );
-        operation_destroy_from_upstream( op );
-        CONNECTION_UNLOCK_OR_DESTROY(c);
-        return;
-    }
-    CONNECTION_LOCK(c);
-    ldap_pvt_thread_mutex_unlock( &op->o_link_mutex );
+            slap_msgtype2str( op->o_tag ), c->c_connid, msg );
 
     found = ( tavl_delete( &c->c_ops, op, operation_client_cmp ) == op );
     if ( !found && !send_anyway ) {
-        Debug( LDAP_DEBUG_TRACE, "operation_send_reject: "
+        Debug( LDAP_DEBUG_TRACE, "operation_send_reject_locked: "
                 "msgid=%d not scheduled for client connid=%lu anymore, "
                 "not sending\n",
                 op->o_client_msgid, c->c_connid );
@@ -706,13 +689,13 @@ operation_send_reject(
     ber = c->c_pendingber;
     if ( ber == NULL && (ber = ber_alloc()) == NULL ) {
         ldap_pvt_thread_mutex_unlock( &c->c_io_mutex );
-        Debug( LDAP_DEBUG_ANY, "operation_send_reject: "
+        Debug( LDAP_DEBUG_ANY, "operation_send_reject_locked: "
                 "ber_alloc failed, closing connid=%lu\n",
                 c->c_connid );
         CONNECTION_LOCK_DECREF(c);
         operation_destroy_from_client( op );
         CONNECTION_DESTROY(c);
-        return;
+        return -1;
     }
     c->c_pendingber = ber;
 
@@ -727,7 +710,43 @@ operation_send_reject(
     CONNECTION_LOCK_DECREF(c);
 done:
     operation_destroy_from_client( op );
-    CONNECTION_UNLOCK_OR_DESTROY(c);
+    return LDAP_SUCCESS;
+}
+
+void
+operation_send_reject(
+        Operation *op,
+        int result,
+        const char *msg,
+        int send_anyway )
+{
+    Connection *c;
+
+    ldap_pvt_thread_mutex_lock( &op->o_link_mutex );
+    c = op->o_client;
+    if ( !c ) {
+        c = op->o_upstream;
+        /* One of the connections has initiated this and keeps a reference, if
+         * client is dead, it must have been the upstream */
+        assert( c );
+        CONNECTION_LOCK(c);
+        ldap_pvt_thread_mutex_unlock( &op->o_link_mutex );
+        Debug( LDAP_DEBUG_TRACE, "operation_send_reject: "
+                "not sending msgid=%d, client connid=%lu is dead\n",
+                op->o_client_msgid, op->o_client_connid );
+        operation_destroy_from_upstream( op );
+        CONNECTION_UNLOCK_OR_DESTROY(c);
+        return;
+    }
+    CONNECTION_LOCK(c);
+    ldap_pvt_thread_mutex_unlock( &op->o_link_mutex );
+
+    /* Non-zero return means connection has been unlocked and might be
+     * destroyed */
+    if ( operation_send_reject_locked( op, result, msg, send_anyway ) ==
+            LDAP_SUCCESS ) {
+        CONNECTION_UNLOCK_OR_DESTROY(c);
+    }
 }
 
 /*
index a8a43928f511496fd3e5864a501785b852d93877..83cd1f7dba58eb61a24e355cd19c3d378f8bea6e 100644 (file)
@@ -159,6 +159,7 @@ LDAP_SLAPD_F (int) operation_client_cmp( const void *l, const void *r );
 LDAP_SLAPD_F (Operation *) operation_init( Connection *c, BerElement *ber );
 LDAP_SLAPD_F (void) operation_abandon( Operation *op );
 LDAP_SLAPD_F (void) operation_send_reject( Operation *op, int result, const char *msg, int send_anyway );
+LDAP_SLAPD_F (int) operation_send_reject_locked( Operation *op, int result, const char *msg, int send_anyway );
 LDAP_SLAPD_F (void) operation_lost_upstream( Operation *op );
 LDAP_SLAPD_F (void) operation_destroy_from_client( Operation *op );
 LDAP_SLAPD_F (void) operation_destroy_from_upstream( Operation *op );