mirror of
https://git.openldap.org/openldap/openldap.git
synced 2026-01-16 20:06:06 -05:00
ITS#9338 alternate fix
Don't resume pending ops unless there are no other threads waiting to write
This commit is contained in:
parent
cfcf418c94
commit
9a3e63ba00
3 changed files with 41 additions and 5 deletions
|
|
@ -2039,6 +2039,34 @@ int connection_write(ber_socket_t s)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int connection_write_resume( Connection *c )
|
||||
{
|
||||
Operation *op;
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &c->c_mutex );
|
||||
/* If there are ops pending because of a writewaiter,
|
||||
* start one up.
|
||||
*/
|
||||
while ((op = LDAP_STAILQ_FIRST( &c->c_pending_ops )) != NULL) {
|
||||
if ( c->c_n_ops_executing > connection_pool_max/2 ) break;
|
||||
|
||||
LDAP_STAILQ_REMOVE_HEAD( &c->c_pending_ops, o_next );
|
||||
LDAP_STAILQ_NEXT(op, o_next) = NULL;
|
||||
|
||||
/* pending operations should not be marked for abandonment */
|
||||
assert(!op->o_abandon);
|
||||
|
||||
c->c_n_ops_pending--;
|
||||
c->c_n_ops_executing++;
|
||||
|
||||
connection_op_activate( op );
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
connection_return( c );
|
||||
}
|
||||
|
||||
#ifdef LDAP_SLAPI
|
||||
typedef struct conn_fake_extblock {
|
||||
void *eb_conn;
|
||||
|
|
|
|||
|
|
@ -809,6 +809,7 @@ LDAP_SLAPD_F (const char *) connection_state2str LDAP_P(( int state ))
|
|||
|
||||
LDAP_SLAPD_F (int) connection_read_activate LDAP_P((ber_socket_t s));
|
||||
LDAP_SLAPD_F (int) connection_write LDAP_P((ber_socket_t s));
|
||||
LDAP_SLAPD_F (int) connection_write_resume LDAP_P((Connection *c));
|
||||
|
||||
LDAP_SLAPD_F (void) connection_op_finish LDAP_P((
|
||||
Operation *op ));
|
||||
|
|
|
|||
|
|
@ -339,6 +339,7 @@ static long send_ldap_ber(
|
|||
ber_len_t bytes;
|
||||
long ret = 0;
|
||||
char *close_reason;
|
||||
int do_resume = 0;
|
||||
|
||||
ber_get_option( ber, LBER_OPT_BER_BYTES_TO_WRITE, &bytes );
|
||||
|
||||
|
|
@ -404,11 +405,13 @@ 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.
|
||||
|
|
@ -419,14 +422,9 @@ fail:
|
|||
close_reason = "writetimeout";
|
||||
else
|
||||
close_reason = "connection lost on writewait";
|
||||
conn->c_writewaiter = 0;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Resched connection if there are pending ops */
|
||||
connection_write( conn->c_sd );
|
||||
conn->c_writewaiter = 0;
|
||||
|
||||
if ( conn->c_writers < 0 ) {
|
||||
ret = 0;
|
||||
break;
|
||||
|
|
@ -435,15 +433,24 @@ fail:
|
|||
|
||||
conn->c_writing = 0;
|
||||
if ( conn->c_writers < 0 ) {
|
||||
/* shutting down, don't resume any ops */
|
||||
do_resume = 0;
|
||||
conn->c_writers++;
|
||||
if ( !conn->c_writers )
|
||||
ldap_pvt_thread_cond_signal( &conn->c_write1_cv );
|
||||
} else {
|
||||
conn->c_writers--;
|
||||
/* other writers are waiting, don't resume any ops */
|
||||
if ( conn->c_writers )
|
||||
do_resume = 0;
|
||||
ldap_pvt_thread_cond_signal( &conn->c_write1_cv );
|
||||
}
|
||||
ldap_pvt_thread_mutex_unlock( &conn->c_write1_mutex );
|
||||
|
||||
/* If there are no more writers, release a pending op */
|
||||
if ( do_resume )
|
||||
connection_write_resume( conn );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue