]> mj.ucw.cz Git - libucw.git/commitdiff
First rough implementation of transactions (no exceptions yet).
authorMartin Mares <mj@ucw.cz>
Tue, 2 Sep 2008 21:17:53 +0000 (23:17 +0200)
committerMartin Mares <mj@ucw.cz>
Tue, 29 Mar 2011 10:55:05 +0000 (12:55 +0200)
ucw/trans.c
ucw/trans.h

index 1ceb3948423d8b836e484b5b44b45af6528a833f..e2e881b8738c3e58b2a73c988a601072d26bc214 100644 (file)
@@ -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 <stdio.h>
+
+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
index 665020370ddb27f6f3eacaa3d9c350d6fffaa27b..1b9e799babd3bc05738b3337b214e742c2906d47 100644 (file)
 /* 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);