Commit 9a3e63ba authored by Howard Chu's avatar Howard Chu Committed by Quanah Gibson-Mount
Browse files

ITS#9338 alternate fix

Don't resume pending ops unless there are no other threads
waiting to write
parent cfcf418c
......@@ -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;
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment