]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/connection.c
Cleanup
[openldap] / servers / slapd / connection.c
index 4e5ccd5fbdd1890216de452c14855885e2837a3b..43faf736a511b65f30d575dcbf813fbade6c81ed 100644 (file)
@@ -242,14 +242,15 @@ int connections_timeout_idle(time_t now)
                        continue;
                }
 
-               if( difftime( c->c_activitytime+global_idletimeout, now) < 0 ) {
+               if( global_idletimeout && 
+                       difftime( c->c_activitytime+global_idletimeout, now) < 0 ) {
                        /* close it */
                        connection_closing( c, "idletimeout" );
                        connection_close( c );
                        i++;
                        continue;
                }
-               if ( c->c_writewaiter ) {
+               if ( c->c_writewaiter && global_writetimeout ) {
                        writers = 1;
                        if( difftime( c->c_activitytime+global_writetimeout, now) < 0 ) {
                                /* close it */
@@ -260,7 +261,7 @@ int connections_timeout_idle(time_t now)
                }
        }
        connection_done( c );
-       if ( !writers )
+       if ( old && !writers )
                slapd_clr_writetime( old );
 
        return i;
@@ -752,11 +753,39 @@ static void connection_abandon( Connection *c )
        }
 }
 
+static void
+connection_wake_writers( Connection *c )
+{
+       /* wake write blocked operations */
+       ldap_pvt_thread_mutex_lock( &c->c_write1_mutex );
+       if ( c->c_writers > 0 ) {
+               c->c_writers = -c->c_writers;
+               ldap_pvt_thread_cond_broadcast( &c->c_write1_cv );
+               ldap_pvt_thread_mutex_unlock( &c->c_write1_mutex );
+               if ( c->c_writewaiter ) {
+                       ldap_pvt_thread_mutex_lock( &c->c_write2_mutex );
+                       ldap_pvt_thread_cond_signal( &c->c_write2_cv );
+                       slapd_clr_write( c->c_sd, 1 );
+                       ldap_pvt_thread_mutex_unlock( &c->c_write2_mutex );
+               }
+               ldap_pvt_thread_mutex_lock( &c->c_write1_mutex );
+               while ( c->c_writers ) {
+                       ldap_pvt_thread_cond_wait( &c->c_write1_cv, &c->c_write1_mutex );
+               }
+               ldap_pvt_thread_mutex_unlock( &c->c_write1_mutex );
+       } else {
+               ldap_pvt_thread_mutex_unlock( &c->c_write1_mutex );
+               slapd_clr_write( c->c_sd, 1 );
+       }
+}
+
 void connection_closing( Connection *c, const char *why )
 {
        assert( connections != NULL );
        assert( c != NULL );
-       assert( c->c_struct_state == SLAP_C_USED );
+
+       if ( c->c_struct_state != SLAP_C_USED ) return;
+
        assert( c->c_conn_state != SLAP_C_INVALID );
 
        /* c_mutex must be locked by caller */
@@ -776,26 +805,7 @@ void connection_closing( Connection *c, const char *why )
                connection_abandon( c );
 
                /* wake write blocked operations */
-               ldap_pvt_thread_mutex_lock( &c->c_write1_mutex );
-               if ( c->c_writers > 0 ) {
-                       c->c_writers = -c->c_writers;
-                       ldap_pvt_thread_cond_broadcast( &c->c_write1_cv );
-                       ldap_pvt_thread_mutex_unlock( &c->c_write1_mutex );
-                       if ( c->c_writewaiter ) {
-                               ldap_pvt_thread_mutex_lock( &c->c_write2_mutex );
-                               ldap_pvt_thread_cond_signal( &c->c_write2_cv );
-                               slapd_clr_write( c->c_sd, 1 );
-                               ldap_pvt_thread_mutex_unlock( &c->c_write2_mutex );
-                       }
-                       ldap_pvt_thread_mutex_lock( &c->c_write1_mutex );
-                       while ( c->c_writers ) {
-                               ldap_pvt_thread_cond_wait( &c->c_write1_cv, &c->c_write1_mutex );
-                       }
-                       ldap_pvt_thread_mutex_unlock( &c->c_write1_mutex );
-               } else {
-                       ldap_pvt_thread_mutex_unlock( &c->c_write1_mutex );
-                       slapd_clr_write( c->c_sd, 1 );
-               }
+               connection_wake_writers( c );
 
        } else if( why == NULL && c->c_close_reason == conn_lost_str ) {
                /* Client closed connection after doing Unbind. */
@@ -808,7 +818,9 @@ connection_close( Connection *c )
 {
        assert( connections != NULL );
        assert( c != NULL );
-       assert( c->c_struct_state == SLAP_C_USED );
+
+       if ( c->c_struct_state != SLAP_C_USED ) return;
+
        assert( c->c_conn_state == SLAP_C_CLOSING );
 
        /* NOTE: c_mutex should be locked by caller */
@@ -1021,7 +1033,7 @@ conn_counter_init( Operation *op, void *ctx )
 static void *
 connection_operation( void *ctx, void *arg_v )
 {
-       int rc = LDAP_OTHER;
+       int rc = LDAP_OTHER, cancel;
        Operation *op = arg_v;
        SlapReply rs = {REP_RESULT};
        ber_tag_t tag = op->o_tag;
@@ -1125,22 +1137,32 @@ operations_error:
                INCR_OP_COMPLETED( opidx );
        }
 
-       if ( op->o_cancel == SLAP_CANCEL_REQ ) {
-               if ( rc == SLAPD_ABANDON ) {
-                       op->o_cancel = SLAP_CANCEL_ACK;
-               } else {
-                       op->o_cancel = LDAP_TOO_LATE;
+       ldap_pvt_thread_mutex_lock( &conn->c_mutex );
+
+       if ( opidx == SLAP_OP_BIND && conn->c_conn_state == SLAP_C_BINDING )
+               conn->c_conn_state = SLAP_C_ACTIVE;
+
+       cancel = op->o_cancel;
+       if ( cancel != SLAP_CANCEL_NONE && cancel != SLAP_CANCEL_DONE ) {
+               if ( cancel == SLAP_CANCEL_REQ ) {
+                       op->o_cancel = rc == SLAPD_ABANDON
+                               ? SLAP_CANCEL_ACK : LDAP_TOO_LATE;
                }
-       }
 
-       while ( op->o_cancel != SLAP_CANCEL_NONE &&
-               op->o_cancel != SLAP_CANCEL_DONE )
-       {
-               ldap_pvt_thread_yield();
+               do {
+                       /* Fake a cond_wait with thread_yield, then
+                        * verify the result properly mutex-protected.
+                        */
+                       ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
+                       do {
+                               ldap_pvt_thread_yield();
+                       } while ( (cancel = op->o_cancel) != SLAP_CANCEL_NONE
+                                       && cancel != SLAP_CANCEL_DONE );
+                       ldap_pvt_thread_mutex_lock( &conn->c_mutex );
+               } while ( (cancel = op->o_cancel) != SLAP_CANCEL_NONE
+                               && cancel != SLAP_CANCEL_DONE );
        }
 
-       ldap_pvt_thread_mutex_lock( &conn->c_mutex );
-
        ber_set_option( op->o_ber, LBER_OPT_BER_MEMCTX, &memctx_null );
 
        LDAP_STAILQ_REMOVE( &conn->c_ops, op, Operation, o_next);
@@ -1259,6 +1281,11 @@ int connection_read_activate( ber_socket_t s )
        if ( rc )
                return rc;
 
+       /* Don't let blocked writers block a pause request */
+       if ( connections[s].c_writewaiter &&
+               ldap_pvt_thread_pool_pausing( &connection_pool ))
+               connection_wake_writers( &connections[s] );
+
        rc = ldap_pvt_thread_pool_submit( &connection_pool,
                connection_read_thread, (void *)(long)s );
 
@@ -1271,24 +1298,6 @@ int connection_read_activate( ber_socket_t s )
        return rc;
 }
 
-void
-connection_hangup( ber_socket_t s )
-{
-       Connection *c;
-
-       c = connection_get( s );
-       if ( c ) {
-               if ( c->c_conn_state == SLAP_C_CLIENT ) {
-                       connection_return( c );
-                       connection_read_activate( s );
-               } else {
-                       connection_closing( c, "connection lost" );
-                       connection_close( c );
-                       connection_return( c );
-               }
-       }
-}
-
 static int
 connection_read( ber_socket_t s, conn_readinfo *cri )
 {
@@ -1545,6 +1554,9 @@ connection_input( Connection *conn , conn_readinfo *cri )
        ctx = cri->ctx;
        op = slap_op_alloc( ber, msgid, tag, conn->c_n_ops_received++, ctx );
 
+       Debug( LDAP_DEBUG_TRACE, "op tag 0x%lx, time %ld\n", tag,
+               (long) op->o_time, 0);
+
        op->o_conn = conn;
        /* clear state if the connection is being reused from inactive */
        if ( conn->c_conn_state == SLAP_C_INACTIVE ) {
@@ -1730,8 +1742,6 @@ static int connection_bind_cleanup_cb( Operation *op, SlapReply *rs )
 static int connection_bind_cb( Operation *op, SlapReply *rs )
 {
        ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
-       if ( op->o_conn->c_conn_state == SLAP_C_BINDING )
-               op->o_conn->c_conn_state = SLAP_C_ACTIVE;
        op->o_conn->c_sasl_bind_in_progress =
                ( rs->sr_err == LDAP_SASL_BIND_IN_PROGRESS );