mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-29 02:59:34 -05:00
more txn infrastructure
This commit is contained in:
parent
3b4fc9b393
commit
71511a0569
7 changed files with 103 additions and 22 deletions
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
Loading…
Reference in a new issue