]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
ITS#9930 fix cn=config / write_waiter deadlock
authorHoward Chu <hyc@openldap.org>
Fri, 14 Oct 2022 14:19:22 +0000 (15:19 +0100)
committerQuanah Gibson-Mount <quanah@openldap.org>
Tue, 25 Oct 2022 16:04:12 +0000 (16:04 +0000)
If a writer is blocked and a config pause is pending, just
close the blocked connection. Don't wait around for a slow
client to catch up.

servers/slapd/result.c

index 9da5e7e1d1e554062ad6c94b0402744b26b3af3d..a50f66498eec9944d7a903dcd892ba6c9964b4ef 100644 (file)
@@ -354,9 +354,7 @@ static long send_ldap_ber(
        conn->c_writers++;
 
        while ( conn->c_writers > 0 && conn->c_writing ) {
-               ldap_pvt_thread_pool_idle( &connection_pool );
                ldap_pvt_thread_cond_wait( &conn->c_write1_cv, &conn->c_write1_mutex );
-               ldap_pvt_thread_pool_unidle( &connection_pool );
        }
 
        /* connection was closed under us */
@@ -405,15 +403,21 @@ fail:
                        return -1;
                }
 
+               /* if writer is blocked and we're waiting for a pool pause,
+                * just drop this connection.
+                */
+               if ( ldap_pvt_thread_pool_pausing( &connection_pool ) > 0 ) {
+                       close_reason = "writer blocked and pool pause pending";
+                       goto fail;
+               }
+
                /* wait for socket to be write-ready */
                do_resume = 1;
                conn->c_writewaiter = 1;
                ldap_pvt_thread_mutex_unlock( &conn->c_write1_mutex );
-               ldap_pvt_thread_pool_idle( &connection_pool );
                slap_writewait_play( op );
                err = slapd_wait_writer( conn->c_sd );
                conn->c_writewaiter = 0;
-               ldap_pvt_thread_pool_unidle( &connection_pool );
                ldap_pvt_thread_mutex_lock( &conn->c_write1_mutex );
                /* 0 is timeout, so we close it.
                 * -1 is an error, close it.