From efff2660a416682116f97e0828f1f29a94998b22 Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Tue, 2 Sep 2008 23:17:53 +0200 Subject: [PATCH] First rough implementation of transactions (no exceptions yet). --- ucw/trans.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++++ ucw/trans.h | 13 ++++-- 2 files changed, 120 insertions(+), 4 deletions(-) diff --git a/ucw/trans.c b/ucw/trans.c index 1ceb3948..e2e881b8 100644 --- a/ucw/trans.c +++ b/ucw/trans.c @@ -7,8 +7,119 @@ * of the GNU Lesser General Public License. */ +#define LOCAL_DEBUG + #include "ucw/lib.h" #include "ucw/trans.h" #include "ucw/respool.h" #include "ucw/mempool.h" +#include + +void +trans_init(void) +{ + struct ucwlib_context *c = ucwlib_thread_context(); + if (!c->trans_pool) + c->trans_pool = mp_new(1024); +} + +void +trans_cleanup(void) +{ + struct ucwlib_context *c = ucwlib_thread_context(); + if (c->trans_pool) + { + mp_delete(c->trans_pool); + c->trans_pool = NULL; + } + c->current_trans = NULL; +} + +struct trans * +trans_open_rp(struct respool *rp) +{ + trans_init(); + struct ucwlib_context *c = ucwlib_thread_context(); + struct mempool *mp = c->trans_pool; + + struct mempool_state *mst = mp_push(mp); + struct trans *t = mp_alloc(mp, sizeof(*t)); + t->trans_pool_state = mst; + + if (!rp) + rp = rp_new("trans", mp); + t->rpool = rp; + t->prev_rpool = rp_switch(rp); + + t->prev_trans = c->current_trans; + c->current_trans = t; + DBG("Opened transaction %p", t); + return t; +} + +struct trans * +trans_get_current(void) +{ + return ucwlib_thread_context() -> current_trans; +} + +static void +trans_close(struct trans *t) +{ + struct ucwlib_context *c = ucwlib_thread_context(); + rp_switch(t->prev_rpool); + c->current_trans = t->prev_trans; + mp_restore(c->trans_pool, t->trans_pool_state); +} + +void +trans_commit(void) +{ + struct trans *t = trans_get_current(); + DBG("Commiting transaction %p", t); + ASSERT(t); + rp_detach(t->rpool); + trans_close(t); +} + +void +trans_rollback(void) +{ + struct trans *t = trans_get_current(); + DBG("Rolling back transaction %p", t); + ASSERT(t); + rp_delete(t->rpool); + trans_close(t); +} + +void +trans_dump(void) +{ + struct trans *t = trans_get_current(); + if (!t) + { + puts("No transaction open."); + return; + } + while (t) + { + printf("Transaction %p:\n", t); + rp_dump(t->rpool); + t = t->prev_trans; + } +} + +#ifdef TEST + +int main(void) +{ + trans_open(); + res_malloc(64, NULL); + trans_dump(); + trans_commit(); + trans_cleanup(); + return 0; +} + +#endif diff --git a/ucw/trans.h b/ucw/trans.h index 66502037..1b9e799b 100644 --- a/ucw/trans.h +++ b/ucw/trans.h @@ -17,16 +17,21 @@ /* Transactions */ struct trans { - struct trans *prev; - struct mempool_state trans_pool_state; - struct respool *res_pool; + struct trans *prev_trans; + struct mempool_state *trans_pool_state; + struct respool *rpool; + struct respool *prev_rpool; jmp_buf jmp; }; void trans_init(void); // Called automatically on trans_open() if needed void trans_cleanup(void); // Free memory occupied by the transaction system pools -struct trans *trans_open(void); +struct trans *trans_open_rp(struct respool *rp); +static inline struct trans *trans_open(void) +{ + return trans_open_rp(NULL); +} struct trans *trans_get_current(void); void trans_commit(void); void trans_rollback(void); -- 2.39.2