]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/connection.c
Merge remote-tracking branch 'origin/mdb.RE/0.9'
[openldap] / servers / slapd / connection.c
index 3e039004975e4276395df29e4fe58fdaa826dd43..2488065c405ac77cc8ac0397607c9db0a6e8c8ab 100644 (file)
@@ -1,7 +1,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 1998-2014 The OpenLDAP Foundation.
+ * Copyright 1998-2015 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -669,8 +669,6 @@ connection_destroy( Connection *c )
 
        sd = c->c_sd;
        c->c_sd = AC_SOCKET_INVALID;
-       c->c_conn_state = SLAP_C_INVALID;
-       c->c_struct_state = SLAP_C_UNUSED;
        c->c_close_reason = "?";                        /* should never be needed */
 
        sb = c->c_sb;
@@ -679,6 +677,8 @@ connection_destroy( Connection *c )
                ber_len_t max = sockbuf_max_incoming;
                ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_SET_MAX_INCOMING, &max );
        }
+       c->c_conn_state = SLAP_C_INVALID;
+       c->c_struct_state = SLAP_C_UNUSED;
 
        /* c must be fully reset by this point; when we call slapd_remove
         * it may get immediately reused by a new connection.
@@ -723,6 +723,9 @@ static void connection_abandon( Connection *c )
                SlapReply rs = {REP_RESULT};
 
                next = LDAP_STAILQ_NEXT( o, o_next );
+               /* don't abandon an op twice */
+               if ( o->o_abandon )
+                       continue;
                op.orn_msgid = o->o_msgid;
                o->o_abandon = 1;
                op.o_bd = frontendDB;
@@ -1172,8 +1175,13 @@ operations_error:
 
        ber_set_option( op->o_ber, LBER_OPT_BER_MEMCTX, &memctx_null );
 
-       LDAP_STAILQ_REMOVE( &conn->c_ops, op, Operation, o_next);
-       LDAP_STAILQ_NEXT(op, o_next) = NULL;
+#ifdef LDAP_X_TXN
+       if ( rc != LDAP_X_TXN_SPECIFY_OKAY )
+#endif
+       {
+               LDAP_STAILQ_REMOVE( &conn->c_ops, op, Operation, o_next);
+               LDAP_STAILQ_NEXT(op, o_next) = NULL;
+       }
        conn->c_n_ops_executing--;
        conn->c_n_ops_completed++;
 
@@ -1188,7 +1196,12 @@ operations_error:
 
        connection_resched( conn );
        ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
-       slap_op_free( op, ctx );
+#ifdef LDAP_X_TXN
+       if ( rc != LDAP_X_TXN_SPECIFY_OKAY )
+#endif
+       {
+               slap_op_free( op, ctx );
+       }
        return NULL;
 }
 
@@ -1232,8 +1245,6 @@ void connection_client_stop(
        assert( c->c_conn_state == SLAP_C_CLIENT );
 
        c->c_listener = NULL;
-       c->c_conn_state = SLAP_C_INVALID;
-       c->c_struct_state = SLAP_C_UNUSED;
        c->c_sd = AC_SOCKET_INVALID;
        c->c_close_reason = "?";                        /* should never be needed */
        sb = c->c_sb;
@@ -1242,6 +1253,8 @@ void connection_client_stop(
                ber_len_t max = sockbuf_max_incoming;
                ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_SET_MAX_INCOMING, &max );
        }
+       c->c_conn_state = SLAP_C_INVALID;
+       c->c_struct_state = SLAP_C_UNUSED;
        slapd_remove( s, sb, 0, 1, 0 );
 
        connection_return( c );