From bf5607b462788697d8be997aa3c62a767e0fedc9 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Fri, 14 Oct 2022 15:19:22 +0100 Subject: [PATCH] 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. --- servers/slapd/result.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/servers/slapd/result.c b/servers/slapd/result.c index 9da5e7e1d1..a50f66498e 100644 --- a/servers/slapd/result.c +++ b/servers/slapd/result.c @@ -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. -- 2.47.2