mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-02-23 14:09:39 +08:00
ITS#7115 blocked writers should not interfere with pool pause
This commit is contained in:
parent
c61b0c3b29
commit
68ee165fb5
@ -261,6 +261,14 @@ LDAP_F( int )
|
||||
ldap_pvt_thread_pool_backload LDAP_P((
|
||||
ldap_pvt_thread_pool_t *pool ));
|
||||
|
||||
LDAP_F( void )
|
||||
ldap_pvt_thread_pool_idle LDAP_P((
|
||||
ldap_pvt_thread_pool_t *pool ));
|
||||
|
||||
LDAP_F( void )
|
||||
ldap_pvt_thread_pool_unidle LDAP_P((
|
||||
ldap_pvt_thread_pool_t *pool ));
|
||||
|
||||
LDAP_F( int )
|
||||
ldap_pvt_thread_pool_pausecheck LDAP_P((
|
||||
ldap_pvt_thread_pool_t *pool ));
|
||||
|
@ -711,10 +711,16 @@ ldap_int_thread_pool_wrapper (
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
#define DO_PAUSE 0
|
||||
#define CHECK_PAUSE 1
|
||||
#define GO_IDLE 2
|
||||
#define GO_UNIDLE 3
|
||||
|
||||
static int
|
||||
handle_pause( ldap_pvt_thread_pool_t *tpool, int do_pause )
|
||||
handle_pause( ldap_pvt_thread_pool_t *tpool, int pause_type )
|
||||
{
|
||||
struct ldap_int_thread_pool_s *pool;
|
||||
int ret = 0;
|
||||
|
||||
if (tpool == NULL)
|
||||
return(-1);
|
||||
@ -724,26 +730,13 @@ handle_pause( ldap_pvt_thread_pool_t *tpool, int do_pause )
|
||||
if (pool == NULL)
|
||||
return(0);
|
||||
|
||||
if (! (do_pause || pool->ltp_pause))
|
||||
if (pause_type == CHECK_PAUSE && !pool->ltp_pause)
|
||||
return(0);
|
||||
|
||||
ldap_pvt_thread_mutex_lock(&pool->ltp_mutex);
|
||||
|
||||
/* If someone else has already requested a pause, we have to wait */
|
||||
if (pool->ltp_pause) {
|
||||
pool->ltp_pending_count++;
|
||||
pool->ltp_active_count--;
|
||||
/* let the other pool_pause() know when it can proceed */
|
||||
if (pool->ltp_active_count < 2)
|
||||
ldap_pvt_thread_cond_signal(&pool->ltp_pcond);
|
||||
do {
|
||||
ldap_pvt_thread_cond_wait(&pool->ltp_cond, &pool->ltp_mutex);
|
||||
} while (pool->ltp_pause);
|
||||
pool->ltp_pending_count--;
|
||||
pool->ltp_active_count++;
|
||||
}
|
||||
|
||||
if (do_pause) {
|
||||
switch( pause_type ) {
|
||||
case DO_PAUSE:
|
||||
/* Wait for everyone else to pause or finish */
|
||||
pool->ltp_pause = 1;
|
||||
/* Let ldap_pvt_thread_pool_submit() through to its ltp_pause test,
|
||||
@ -756,10 +749,48 @@ handle_pause( ldap_pvt_thread_pool_t *tpool, int do_pause )
|
||||
while (pool->ltp_active_count > 1) {
|
||||
ldap_pvt_thread_cond_wait(&pool->ltp_pcond, &pool->ltp_mutex);
|
||||
}
|
||||
break;
|
||||
case GO_UNIDLE:
|
||||
pool->ltp_pending_count--;
|
||||
pool->ltp_active_count++;
|
||||
/* FALLTHRU */
|
||||
case CHECK_PAUSE:
|
||||
case GO_IDLE:
|
||||
/* If someone else has already requested a pause, we have to wait */
|
||||
if (pool->ltp_pause) {
|
||||
pool->ltp_pending_count++;
|
||||
pool->ltp_active_count--;
|
||||
/* let the other pool_pause() know when it can proceed */
|
||||
if (pool->ltp_active_count < 2)
|
||||
ldap_pvt_thread_cond_signal(&pool->ltp_pcond);
|
||||
do {
|
||||
ldap_pvt_thread_cond_wait(&pool->ltp_cond, &pool->ltp_mutex);
|
||||
} while (pool->ltp_pause);
|
||||
pool->ltp_pending_count--;
|
||||
pool->ltp_active_count++;
|
||||
ret = 1;
|
||||
}
|
||||
if (pause_type != GO_IDLE)
|
||||
break;
|
||||
pool->ltp_pending_count++;
|
||||
pool->ltp_active_count--;
|
||||
break;
|
||||
}
|
||||
|
||||
ldap_pvt_thread_mutex_unlock(&pool->ltp_mutex);
|
||||
return(!do_pause);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
void
|
||||
ldap_pvt_thread_pool_idle( ldap_pvt_thread_pool_t *tpool )
|
||||
{
|
||||
handle_pause( tpool, GO_IDLE );
|
||||
}
|
||||
|
||||
void
|
||||
ldap_pvt_thread_pool_unidle( ldap_pvt_thread_pool_t *tpool )
|
||||
{
|
||||
handle_pause( tpool, GO_UNIDLE );
|
||||
}
|
||||
|
||||
/*
|
||||
@ -770,14 +801,14 @@ handle_pause( ldap_pvt_thread_pool_t *tpool, int do_pause )
|
||||
int
|
||||
ldap_pvt_thread_pool_pausecheck( ldap_pvt_thread_pool_t *tpool )
|
||||
{
|
||||
return handle_pause( tpool, 0 );
|
||||
return handle_pause( tpool, CHECK_PAUSE );
|
||||
}
|
||||
|
||||
/* Pause the pool. Return when all other threads are paused. */
|
||||
int
|
||||
ldap_pvt_thread_pool_pause( ldap_pvt_thread_pool_t *tpool )
|
||||
{
|
||||
return handle_pause( tpool, 1 );
|
||||
return handle_pause( tpool, DO_PAUSE );
|
||||
}
|
||||
|
||||
/* End a pause */
|
||||
|
@ -369,9 +369,11 @@ static long send_ldap_ber(
|
||||
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_write1_mutex );
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
|
||||
ldap_pvt_thread_pool_idle( &connection_pool );
|
||||
ldap_pvt_thread_cond_wait( &conn->c_write2_cv, &conn->c_write2_mutex );
|
||||
conn->c_writewaiter = 0;
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_write2_mutex );
|
||||
ldap_pvt_thread_pool_unidle( &connection_pool );
|
||||
ldap_pvt_thread_mutex_lock( &conn->c_write1_mutex );
|
||||
if ( conn->c_writers < 0 ) {
|
||||
ret = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user