]> mj.ucw.cz Git - libucw.git/blob - ucw/trans.c
e2e881b8738c3e58b2a73c988a601072d26bc214
[libucw.git] / ucw / trans.c
1 /*
2  *      The UCW Library -- Transactions
3  *
4  *      (c) 2008 Martin Mares <mj@ucw.cz>
5  *
6  *      This software may be freely distributed and used according to the terms
7  *      of the GNU Lesser General Public License.
8  */
9
10 #define LOCAL_DEBUG
11
12 #include "ucw/lib.h"
13 #include "ucw/trans.h"
14 #include "ucw/respool.h"
15 #include "ucw/mempool.h"
16
17 #include <stdio.h>
18
19 void
20 trans_init(void)
21 {
22   struct ucwlib_context *c = ucwlib_thread_context();
23   if (!c->trans_pool)
24     c->trans_pool = mp_new(1024);
25 }
26
27 void
28 trans_cleanup(void)
29 {
30   struct ucwlib_context *c = ucwlib_thread_context();
31   if (c->trans_pool)
32     {
33       mp_delete(c->trans_pool);
34       c->trans_pool = NULL;
35     }
36   c->current_trans = NULL;
37 }
38
39 struct trans *
40 trans_open_rp(struct respool *rp)
41 {
42   trans_init();
43   struct ucwlib_context *c = ucwlib_thread_context();
44   struct mempool *mp = c->trans_pool;
45
46   struct mempool_state *mst = mp_push(mp);
47   struct trans *t = mp_alloc(mp, sizeof(*t));
48   t->trans_pool_state = mst;
49
50   if (!rp)
51     rp = rp_new("trans", mp);
52   t->rpool = rp;
53   t->prev_rpool = rp_switch(rp);
54
55   t->prev_trans = c->current_trans;
56   c->current_trans = t;
57   DBG("Opened transaction %p", t);
58   return t;
59 }
60
61 struct trans *
62 trans_get_current(void)
63 {
64   return ucwlib_thread_context() -> current_trans;
65 }
66
67 static void
68 trans_close(struct trans *t)
69 {
70   struct ucwlib_context *c = ucwlib_thread_context();
71   rp_switch(t->prev_rpool);
72   c->current_trans = t->prev_trans;
73   mp_restore(c->trans_pool, t->trans_pool_state);
74 }
75
76 void
77 trans_commit(void)
78 {
79   struct trans *t = trans_get_current();
80   DBG("Commiting transaction %p", t);
81   ASSERT(t);
82   rp_detach(t->rpool);
83   trans_close(t);
84 }
85
86 void
87 trans_rollback(void)
88 {
89   struct trans *t = trans_get_current();
90   DBG("Rolling back transaction %p", t);
91   ASSERT(t);
92   rp_delete(t->rpool);
93   trans_close(t);
94 }
95
96 void
97 trans_dump(void)
98 {
99   struct trans *t = trans_get_current();
100   if (!t)
101     {
102       puts("No transaction open.");
103       return;
104     }
105   while (t)
106     {
107       printf("Transaction %p:\n", t);
108       rp_dump(t->rpool);
109       t = t->prev_trans;
110     }
111 }
112
113 #ifdef TEST
114
115 int main(void)
116 {
117   trans_open();
118   res_malloc(64, NULL);
119   trans_dump();
120   trans_commit();
121   trans_cleanup();
122   return 0;
123 }
124
125 #endif