ITS#9930 fix cn=config / write_waiter deadlock

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.
This commit is contained in:
Howard Chu 2022-10-14 15:19:22 +01:00
parent 6489b6a857
commit 04eded74fe

View 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.