]> mj.ucw.cz Git - libucw.git/blob - ucw/trans.h
608581fade8a96b1f6200a8e28df9aa569aeb3af
[libucw.git] / ucw / trans.h
1 /*
2  *      The UCW Library -- Transactions
3  *
4  *      (c) 2008--2011 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 #ifndef _UCW_TRANS_H
11 #define _UCW_TRANS_H
12
13 #include "ucw/mempool.h"
14
15 #include <setjmp.h>
16
17 /* Transactions */
18
19 struct trans {
20   struct trans *prev_trans;
21   struct mempool_state *trans_pool_state;
22   struct respool *rpool;
23   struct respool *prev_rpool;
24   struct exception *thrown_exc;
25   jmp_buf jmp;
26 };
27
28 void trans_init(void);          // Called automatically on trans_open() if needed
29 void trans_cleanup(void);       // Free memory occupied by the transaction system pools
30
31 struct trans *trans_open(void);
32 struct trans *trans_get_current(void);
33 void trans_commit(void);
34 void trans_rollback(void);
35 void trans_fold(void);
36 void trans_dump(void);
37
38 struct mempool *trans_get_pool(void);
39
40 /* Exceptions */
41
42 struct exception {
43   const char *id;               // Hierarchic identifier of the exception
44   const char *msg;              // Error message to present to the user
45   void *object;                 // Object on which the exception happened
46   // More data specific for the particular `id' can follow
47 };
48
49 void trans_throw_exc(struct exception *x) NONRET;
50 void trans_throw(const char *id, void *object, const char *fmt, ...) FORMAT_CHECK(printf,3,4) NONRET;
51 void trans_vthrow(const char *id, void *object, const char *fmt, va_list args) NONRET;
52 void trans_caught(void);
53
54 struct exception *trans_current_exc(void);
55
56 #define TRANS_TRY do {                          \
57   struct trans *_t = trans_open();              \
58   if (!setjmp(_t->jmp))                         \
59     {
60
61 #define TRANS_CATCH(x)                          \
62       trans_commit();                           \
63     }                                           \
64   else                                          \
65     {                                           \
66       struct exception *x UNUSED = trans_current_exc();
67
68 #define TRANS_END                               \
69       trans_caught();                           \
70     }                                           \
71   } while(0)
72
73 #endif