]> git.sur5r.net Git - openldap/commitdiff
more txn infrastructure
authorKurt Zeilenga <kurt@openldap.org>
Wed, 8 Mar 2006 05:54:10 +0000 (05:54 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Wed, 8 Mar 2006 05:54:10 +0000 (05:54 +0000)
servers/slapd/back-bdb/add.c
servers/slapd/back-bdb/delete.c
servers/slapd/back-bdb/modify.c
servers/slapd/back-bdb/modrdn.c
servers/slapd/connection.c
servers/slapd/slap.h
servers/slapd/txn.c

index 3cafbe42cb2ea49abb857251ac5a92f08cf09a8c..5fa8f7981ed4916cf93bf70275a5d864b0028865 100644 (file)
@@ -44,6 +44,10 @@ bdb_add(Operation *op, SlapReply *rs )
        LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
        int num_ctrls = 0;
 
+#ifdef LDAP_X_TXN
+       int settle = 0;
+#endif
+
        Debug(LDAP_DEBUG_ARGS, "==> " LDAP_XSTRING(bdb_add) ": %s\n",
                op->oq_add.rs_e->e_name.bv_val, 0, 0);
 
@@ -51,11 +55,15 @@ bdb_add(Operation *op, SlapReply *rs )
        if( op->o_txnSpec ) {
                /* acquire connection lock */
                ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
-               if( op->o_conn->c_txn == 0 ) {
+               if( op->o_conn->c_txn == CONN_TXN_INACTIVE ) {
                        rs->sr_text = "invalid transaction identifier";
                        rs->sr_err = LDAP_X_TXN_ID_INVALID;
                        goto txnReturn;
+               } else if( op->o_conn->c_txn == CONN_TXN_SETTLE ) {
+                       settle=1;
+                       goto txnReturn;
                }
+
                if( op->o_conn->c_txn_backend == NULL ) {
                        op->o_conn->c_txn_backend = op->o_bd;
 
@@ -74,8 +82,10 @@ txnReturn:
                /* release connection lock */
                ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
 
-               send_ldap_result( op, rs );
-               return rs->sr_err;
+               if( !settle ) {
+                       send_ldap_result( op, rs );
+                       return rs->sr_err;
+               }
        }
 #endif
 
index 60fa54f9a18f2f58c9a65abc265a7249463494ff..488cdafd3b2fbf026ec98550cbc6455b3520c018 100644 (file)
@@ -52,6 +52,10 @@ bdb_delete( Operation *op, SlapReply *rs )
        int     parent_is_glue = 0;
        int parent_is_leaf = 0;
 
+#ifdef LDAP_X_TXN
+       int settle = 0;
+#endif
+
        Debug( LDAP_DEBUG_ARGS, "==> " LDAP_XSTRING(bdb_delete) ": %s\n",
                op->o_req_dn.bv_val, 0, 0 );
 
@@ -59,11 +63,15 @@ bdb_delete( Operation *op, SlapReply *rs )
        if( op->o_txnSpec ) {
                /* acquire connection lock */
                ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
-               if( op->o_conn->c_txn == 0 ) {
+               if( op->o_conn->c_txn == CONN_TXN_INACTIVE ) {
                        rs->sr_text = "invalid transaction identifier";
                        rs->sr_err = LDAP_X_TXN_ID_INVALID;
                        goto txnReturn;
+               } else if( op->o_conn->c_txn == CONN_TXN_SETTLE ) {
+                       settle=1;
+                       goto txnReturn;
                }
+
                if( op->o_conn->c_txn_backend == NULL ) {
                        op->o_conn->c_txn_backend = op->o_bd;
 
@@ -82,8 +90,10 @@ txnReturn:
                /* release connection lock */
                ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
 
-               send_ldap_result( op, rs );
-               return rs->sr_err;
+               if( !settle ) {
+                       send_ldap_result( op, rs );
+                       return rs->sr_err;
+               }
        }
 #endif
 
index 7ad798b480182c77970395a904596c2dcd777880..19cd76f4abafbed78d9a54fac525d6ad26bc9e06 100644 (file)
@@ -293,6 +293,10 @@ bdb_modify( Operation *op, SlapReply *rs )
 
        int rc;
 
+#ifdef LDAP_X_TXN
+       int settle = 0;
+#endif
+
        Debug( LDAP_DEBUG_ARGS, LDAP_XSTRING(bdb_modify) ": %s\n",
                op->o_req_dn.bv_val, 0, 0 );
 
@@ -300,11 +304,15 @@ bdb_modify( Operation *op, SlapReply *rs )
        if( op->o_txnSpec ) {
                /* acquire connection lock */
                ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
-               if( op->o_conn->c_txn == 0 ) {
+               if( op->o_conn->c_txn == CONN_TXN_INACTIVE ) {
                        rs->sr_text = "invalid transaction identifier";
                        rs->sr_err = LDAP_X_TXN_ID_INVALID;
                        goto txnReturn;
+               } else if( op->o_conn->c_txn == CONN_TXN_SETTLE ) {
+                       settle=1;
+                       goto txnReturn;
                }
+
                if( op->o_conn->c_txn_backend == NULL ) {
                        op->o_conn->c_txn_backend = op->o_bd;
 
@@ -323,8 +331,10 @@ txnReturn:
                /* release connection lock */
                ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
 
-               send_ldap_result( op, rs );
-               return rs->sr_err;
+               if( !settle ) {
+                       send_ldap_result( op, rs );
+                       return rs->sr_err;
+               }
        }
 #endif
 
index 23d28810af3d4262c9c234a5a1bcab458ef72d71..f32abdf5671584e76e6b682f509d2ea33b11889e 100644 (file)
@@ -61,6 +61,10 @@ bdb_modrdn( Operation        *op, SlapReply *rs )
        int parent_is_glue = 0;
        int parent_is_leaf = 0;
 
+#ifdef LDAP_X_TXN
+       int settle = 0;
+#endif
+
        Debug( LDAP_DEBUG_TRACE, "==>" LDAP_XSTRING(bdb_modrdn) "(%s,%s,%s)\n",
                op->o_req_dn.bv_val,op->oq_modrdn.rs_newrdn.bv_val,
                op->oq_modrdn.rs_newSup ? op->oq_modrdn.rs_newSup->bv_val : "NULL" );
@@ -69,11 +73,15 @@ bdb_modrdn( Operation       *op, SlapReply *rs )
        if( op->o_txnSpec ) {
                /* acquire connection lock */
                ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
-               if( op->o_conn->c_txn == 0 ) {
+               if( op->o_conn->c_txn == CONN_TXN_INACTIVE ) {
                        rs->sr_text = "invalid transaction identifier";
                        rs->sr_err = LDAP_X_TXN_ID_INVALID;
                        goto txnReturn;
+               } else if( op->o_conn->c_txn == CONN_TXN_SETTLE ) {
+                       settle=1;
+                       goto txnReturn;
                }
+
                if( op->o_conn->c_txn_backend == NULL ) {
                        op->o_conn->c_txn_backend = op->o_bd;
 
@@ -92,8 +100,10 @@ txnReturn:
                /* release connection lock */
                ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
 
-               send_ldap_result( op, rs );
-               return rs->sr_err;
+               if( !settle ) {
+                       send_ldap_result( op, rs );
+                       return rs->sr_err;
+               }
        }
 #endif
 
index 252570efcf346df894ea59f935e4bcb2851357ba..71d6a35b5737bff7f6902429735d9e8ad614a883 100644 (file)
@@ -620,7 +620,7 @@ long connection_init(
                LDAP_STAILQ_INIT(&c->c_pending_ops);
 
 #ifdef LDAP_X_TXN
-               c->c_txn = 0;
+               c->c_txn = CONN_TXN_INACTIVE;
                c->c_txn_backend = NULL;
                LDAP_STAILQ_INIT(&c->c_txn_ops);
 #endif
@@ -667,7 +667,7 @@ long connection_init(
        assert( LDAP_STAILQ_EMPTY(&c->c_ops) );
        assert( LDAP_STAILQ_EMPTY(&c->c_pending_ops) );
 #ifdef LDAP_X_TXN
-       assert( c->c_txn == 0 );
+       assert( c->c_txn == CONN_TXN_INACTIVE );
        assert( c->c_txn_backend == NULL );
        assert( LDAP_STAILQ_EMPTY(&c->c_txn_ops) );
 #endif
@@ -830,6 +830,12 @@ connection_destroy( Connection *c )
        assert( c->c_struct_state != SLAP_C_UNUSED );
        assert( c->c_conn_state != SLAP_C_INVALID );
        assert( LDAP_STAILQ_EMPTY(&c->c_ops) );
+       assert( LDAP_STAILQ_EMPTY(&c->c_pending_ops) );
+#ifdef LDAP_X_TXN
+       assert( c->c_txn == CONN_TXN_INACTIVE );
+       assert( c->c_txn_backend == NULL );
+       assert( LDAP_STAILQ_EMPTY(&c->c_txn_ops) );
+#endif
        assert( c->c_writewaiter == 0);
 
        /* only for stats (print -1 as "%lu" may give unexpected results ;) */
@@ -928,6 +934,7 @@ static void connection_abandon( Connection *c )
        op.o_conn = c;
        op.o_connid = c->c_connid;
        op.o_tag = LDAP_REQ_ABANDON;
+
        for ( o = LDAP_STAILQ_FIRST( &c->c_ops ); o; o=next ) {
                next = LDAP_STAILQ_NEXT( o, o_next );
                op.orn_msgid = o->o_msgid;
@@ -936,6 +943,19 @@ static void connection_abandon( Connection *c )
                frontendDB->be_abandon( &op, &rs );
        }
 
+#ifdef LDAP_X_TXN
+       /* remove operations in pending transaction */
+       while ( (o = LDAP_STAILQ_FIRST( &c->c_txn_ops )) != NULL) {
+               LDAP_STAILQ_REMOVE_HEAD( &c->c_txn_ops, o_next );
+               LDAP_STAILQ_NEXT(o, o_next) = NULL;
+               slap_op_free( o );
+       }
+
+       /* clear transaction */
+       c->c_txn_backend = NULL;
+       c->c_txn = CONN_TXN_INACTIVE;
+#endif
+
        /* remove pending operations */
        while ( (o = LDAP_STAILQ_FIRST( &c->c_pending_ops )) != NULL) {
                LDAP_STAILQ_REMOVE_HEAD( &c->c_pending_ops, o_next );
@@ -978,6 +998,7 @@ void connection_closing( Connection *c, const char *why )
                        ldap_pvt_thread_yield();
                        ldap_pvt_thread_mutex_lock( &c->c_mutex );
                }
+
        } else if( why == NULL && c->c_close_reason == conn_lost_str ) {
                /* Client closed connection after doing Unbind. */
                c->c_close_reason = NULL;
index 51d5ae3a9f3b74017aa1bd6e2816cde03fa63dad..d1529f9d759fa0f606a06f518d69a4e5ffa54a0e 100644 (file)
@@ -2449,7 +2449,6 @@ typedef struct slap_op {
 #define SLAP_CONTROL_DATA2     0x40
 #define SLAP_CONTROL_DATA3     0x80
 
-
 #define _SCM(x)        ((x) & SLAP_CONTROL_MASK)
 
        char o_ctrlflag[SLAP_MAX_CIDS]; /* per-control flags */
@@ -2521,9 +2520,9 @@ typedef struct slap_op {
 
        void    *o_private;     /* anything the backend needs */
 
-       LDAP_STAILQ_ENTRY(slap_op)      o_next; /* next operation in list         */
-
+       LDAP_STAILQ_ENTRY(slap_op)      o_next; /* next operation in list */
 } Operation;
+
 #define        OPERATION_BUFFER_SIZE   ( sizeof(Operation) + sizeof(Opheader) + \
        SLAP_MAX_CIDS*sizeof(void *) )
 
@@ -2635,7 +2634,11 @@ typedef struct slap_conn {
        struct slap_op  *c_sasl_bindop; /* set to current op if it's a bind */
 
 #ifdef LDAP_X_TXN
-       int c_txn;      /* true if transaction started */
+#define CONN_TXN_INACTIVE 0
+#define CONN_TXN_SPECIFY 1
+#define CONN_TXN_SETTLE -1
+       int c_txn;
+
        Backend *c_txn_backend;
        LDAP_STAILQ_HEAD(c_to, slap_op) c_txn_ops; /* list of operations in txn */
 #endif
index c86cd12ca80c0d6cfe93cb94985aa86780617098..b087a35463fdf7ead229d613a90b27a8c6e1537e 100644 (file)
@@ -56,14 +56,14 @@ int txn_start_extop(
        /* acquire connection lock */
        ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
 
-       if( op->o_conn->c_txn ) {
+       if( op->o_conn->c_txn != CONN_TXN_INACTIVE ) {
                rs->sr_text = "Too many transactions";
                rc = LDAP_BUSY;
                goto done;
        }
 
        assert( op->o_conn->c_txn_backend == NULL );
-       ++op->o_conn->c_txn;
+       op->o_conn->c_txn = CONN_TXN_SPECIFY;
 
        bv = (struct berval *) ch_malloc( sizeof (struct berval) );
        bv->bv_len = 0;
@@ -173,13 +173,24 @@ int txn_end_extop(
        /* acquire connection lock */
        ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
 
-       if( op->o_conn->c_txn == 0 ) {
+       if( op->o_conn->c_txn != CONN_TXN_SPECIFY ) {
                rs->sr_text = "invalid transaction identifier";
                rc = LDAP_X_TXN_ID_INVALID;
                goto done;
        }
+       op->o_conn->c_txn = CONN_TXN_SETTLE;
 
        if( commit ) {
+               if ( op->o_abandon ) {
+               }
+
+               if( LDAP_STAILQ_EMPTY(&op->o_conn->c_txn_ops) ) {
+                       /* no updates to commit */
+                       rs->sr_text = "no updates to commit";
+                       rc = LDAP_OPERATIONS_ERROR;
+                       goto settled;
+               }
+
                rs->sr_text = "not yet implemented";
                rc = LDAP_UNWILLING_TO_PERFORM;
 
@@ -188,7 +199,13 @@ int txn_end_extop(
                rc = LDAP_SUCCESS;;
        }
 
-       op->o_conn->c_txn = 0;
+drain:
+       /* drain txn ops list */
+
+settled:
+       assert( LDAP_STAILQ_EMPTY(&op->o_conn->c_txn_ops) );
+       assert( op->o_conn->c_txn == CONN_TXN_SETTLE );
+       op->o_conn->c_txn = CONN_TXN_INACTIVE;
        op->o_conn->c_txn_backend = NULL;
 
 done: