From 3e05f289633b79093c56789aa84ae5280882b8a5 Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Fri, 23 Apr 1999 20:22:18 +0000 Subject: [PATCH] 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. --- servers/slapd/abandon.c | 36 ++++++++++++++++++++++-------------- servers/slapd/connection.c | 38 ++++++++++++++++++++++++++++++++++++++ servers/slapd/proto-slap.h | 1 + servers/slapd/result.c | 34 ++++++++++++++++++++++++++++++---- 4 files changed, 91 insertions(+), 18 deletions(-) diff --git a/servers/slapd/abandon.c b/servers/slapd/abandon.c index 4a55d34e11..968c64d4cf 100644 --- a/servers/slapd/abandon.c +++ b/servers/slapd/abandon.c @@ -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 ); } diff --git a/servers/slapd/connection.c b/servers/slapd/connection.c index 2e7a7604d3..5b6bd4df3d 100644 --- a/servers/slapd/connection.c +++ b/servers/slapd/connection.c @@ -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 ) { diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index 7d147b5a63..d35ab85802 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -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)); diff --git a/servers/slapd/result.c b/servers/slapd/result.c index 014cdc42e9..66ffd1346f 100644 --- a/servers/slapd/result.c +++ b/servers/slapd/result.c @@ -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 -- 2.39.5