]> git.sur5r.net Git - openldap/commitdiff
Modify connection_closing() to abandon operations and wake blocked writer.
authorKurt Zeilenga <kurt@openldap.org>
Fri, 23 Apr 1999 20:22:18 +0000 (20:22 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Fri, 23 Apr 1999 20:22:18 +0000 (20:22 +0000)
Modify send_result to return if connection state is closing.
Modify do_abandon() to remove abandon'ed operation if pending.

servers/slapd/abandon.c
servers/slapd/connection.c
servers/slapd/proto-slap.h
servers/slapd/result.c

index 4a55d34e118809b5b2d17ec3bde3cdb17107f117..968c64d4cfe02576a310f88bfa57a10f349568b8 100644 (file)
@@ -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 );
 }
index 2e7a7604d3ccfb29535b71047a5fb16e3d44fafa..5b6bd4df3d5aa9fc12e1fd12f4985053a697399d 100644 (file)
@@ -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 ) {
index 7d147b5a6345ebf89345350ee180289ea79bd0a7..d35ab85802ffc7fb24877fd6494e97756a42806d 100644 (file)
@@ -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));
index 014cdc42e905765c5f16c5697602b2325970a0e5..66ffd1346f3073be59199fc24d2aa18e587e792d 100644 (file)
@@ -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