mirror of
https://git.openldap.org/openldap/openldap.git
synced 2024-12-15 03:01:09 +08:00
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.
This commit is contained in:
parent
06b5db46eb
commit
3e05f28963
@ -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:
|
||||
|
||||
if ( o != NULL ) {
|
||||
ldap_pvt_thread_mutex_lock( &o->o_abandonmutex );
|
||||
o->o_abandon = 1;
|
||||
ldap_pvt_thread_mutex_unlock( &o->o_abandonmutex );
|
||||
|
||||
} else {
|
||||
Debug( LDAP_DEBUG_TRACE, "do_abandon: op not found\n", 0, 0,
|
||||
0 );
|
||||
for ( oo = &conn->c_pending_ops;
|
||||
(*oo != NULL) && ((*oo)->o_msgid != id);
|
||||
oo = &(*oo)->o_next )
|
||||
{
|
||||
/* EMPTY */ ;
|
||||
}
|
||||
|
||||
if( *oo != NULL ) {
|
||||
o = *oo;
|
||||
*oo = (*oo)->o_next;
|
||||
slap_op_free( o );
|
||||
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user