From: Howard Chu Date: Fri, 14 Oct 2022 14:19:22 +0000 (+0100) Subject: ITS#9930 fix cn=config / write_waiter deadlock X-Git-Tag: OPENLDAP_REL_ENG_2_5_14~59 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bf5607b462788697d8be997aa3c62a767e0fedc9;p=thirdparty%2Fopenldap.git 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. --- 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.