Commit 3e05f289 authored by Kurt Zeilenga's avatar Kurt Zeilenga
Browse files

Modify connection_closing() to abandon operations and wake blocked writer.

Modify send_result to return if connection state is closing.
Modify do_abandon() to remove abandon'ed operation if pending.
parent 06b5db46
......@@ -27,6 +27,7 @@ do_abandon(
{
int id;
Operation *o;
Operation **oo;
Debug( LDAP_DEBUG_TRACE, "do_abandon\n", 0, 0, 0 );
......@@ -52,25 +53,32 @@ do_abandon(
ldap_pvt_thread_mutex_lock( &conn->c_mutex );
for ( o = conn->c_ops; o != NULL; o = o->o_next ) {
if ( o->o_msgid == id )
goto found_op;
}
for ( o = conn->c_pending_ops; o != NULL; o = o->o_next ) {
if ( o->o_msgid == id )
break;
if ( o->o_msgid == id ) {
ldap_pvt_thread_mutex_lock( &o->o_abandonmutex );
o->o_abandon = 1;
ldap_pvt_thread_mutex_unlock( &o->o_abandonmutex );
goto found_it;
}
}
found_op:
for ( oo = &conn->c_pending_ops;
(*oo != NULL) && ((*oo)->o_msgid != id);
oo = &(*oo)->o_next )
{
/* EMPTY */ ;
}
if ( o != NULL ) {
ldap_pvt_thread_mutex_lock( &o->o_abandonmutex );
o->o_abandon = 1;
ldap_pvt_thread_mutex_unlock( &o->o_abandonmutex );
if( *oo != NULL ) {
o = *oo;
*oo = (*oo)->o_next;
slap_op_free( o );
} else {
Debug( LDAP_DEBUG_TRACE, "do_abandon: op not found\n", 0, 0,
0 );
goto found_it;
}
Debug( LDAP_DEBUG_TRACE, "do_abandon: op not found\n", 0, 0, 0 );
found_it:
ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
}
......@@ -308,6 +308,15 @@ connection_destroy( Connection *c )
lber_pvt_sb_destroy( &c->c_sb );
}
int connection_state_closing( Connection *c )
{
assert( c != NULL );
assert( c->c_struct_state == SLAP_C_USED );
assert( c->c_conn_state != SLAP_C_INVALID );
return c->c_conn_state == SLAP_C_CLOSING;
}
void connection_closing( Connection *c )
{
assert( connections != NULL );
......@@ -316,9 +325,35 @@ void connection_closing( Connection *c )
assert( c->c_conn_state != SLAP_C_INVALID );
if( c->c_conn_state != SLAP_C_CLOSING ) {
Operation *o;
Debug( LDAP_DEBUG_TRACE,
"connection_closing: readying conn=%ld sd=%d for close.\n",
c->c_connid, c->c_sb.sb_sd, 0 );
/* don't listen on this port anymore */
slapd_clr_read( c->c_sb.sb_sd, 1 );
c->c_conn_state = SLAP_C_CLOSING;
/* shutdown I/O -- not yet implemented */
/* abandon active operations */
for( o = c->c_ops; o != NULL; o = o->o_next ) {
ldap_pvt_thread_mutex_lock( &o->o_abandonmutex );
o->o_abandon = 1;
ldap_pvt_thread_mutex_unlock( &o->o_abandonmutex );
}
/* remove pending operations */
for( o = slap_op_pop( &c->c_pending_ops );
o != NULL;
o = slap_op_pop( &c->c_pending_ops ) )
{
slap_op_free( o );
}
/* wake write blocked operations */
ldap_pvt_thread_cond_signal( &c->c_write_cv );
}
}
......@@ -708,6 +743,9 @@ connection_resched( Connection *conn )
op != NULL;
op = slap_op_pop( &conn->c_pending_ops ) )
{
/* pending operations should not be marked for abandonment */
assert(!op->o_abandon);
connection_op_activate( conn, op );
if ( conn->c_conn_state == SLAP_C_BINDING ) {
......
......@@ -120,6 +120,7 @@ long connection_init LDAP_P((
const char* name, const char* addr));
void connection_closing LDAP_P(( Connection *c ));
int connection_state_closing LDAP_P(( Connection *c ));
int connection_write LDAP_P((int s));
int connection_read LDAP_P((int s));
......
......@@ -97,8 +97,21 @@ send_ldap_result2(
/* write the pdu */
bytes = ber->ber_ptr - ber->ber_buf;
while ( ber_flush( &conn->c_sb, ber, 1 ) != 0 ) {
int err = errno;
while ( 1 ) {
int err;
if ( connection_state_closing( conn ) ) {
ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
ldap_pvt_thread_mutex_unlock( &conn->c_write_mutex );
return;
}
if ( ber_flush( &conn->c_sb, ber, 1 ) == 0 ) {
break;
}
err = errno;
/*
* we got an error. if it's ewouldblock, we need to
* wait on the socket being writable. otherwise, figure
......@@ -326,8 +339,21 @@ send_search_entry(
ldap_pvt_thread_mutex_lock( &conn->c_mutex );
/* write the pdu */
while ( ber_flush( &conn->c_sb, ber, 1 ) != 0 ) {
int err = errno;
while( 1 ) {
int err;
if ( connection_state_closing( conn ) ) {
ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
ldap_pvt_thread_mutex_unlock( &conn->c_write_mutex );
return;
}
if ( ber_flush( &conn->c_sb, ber, 1 ) == 0 ) {
break;
}
err = errno;
/*
* we got an error. if it's ewouldblock, we need to
* wait on the socket being writable. otherwise, figure
......
Markdown is supported
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