]> mj.ucw.cz Git - libucw.git/blob - ucw/trans.h
Implemented trans_vthrow().
[libucw.git] / ucw / trans.h
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 #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   jmp_buf jmp;
25 };
26
27 void trans_init(void);          // Called automatically on trans_open() if needed
28 void trans_cleanup(void);       // Free memory occupied by the transaction system pools
29
30 struct trans *trans_open_rp(struct respool *rp);
31 static inline struct trans *trans_open(void)
32 {
33   return trans_open_rp(NULL);
34 }
35 struct trans *trans_get_current(void);
36 void trans_commit(void);
37 void trans_rollback(void);
38 void trans_dump(void);
39
40 struct mempool *trans_get_pool(void);
41 struct mempool *trans_get_exc_pool(void);
42
43 /* Exceptions */
44
45 struct exception {
46   const char *id;               // Hierarchic identifier of the exception
47   const char *msg;              // Error message to present to the user
48   void *object;                 // Object on which the exception happened
49   struct trans *trans;          // Transaction in which it happened (set by trans_throw*)
50   // More data specific for the particular `id' can follow
51 };
52
53 void trans_throw_exc(struct exception *x) NONRET;
54 void trans_throw(const char *id, void *object, const char *fmt, ...) FORMAT_CHECK(printf,3,4) NONRET;
55 void trans_vthrow(const char *id, void *object, const char *fmt, va_list args) NONRET;
56
57 struct exception *trans_current_exc(void);
58
59 #define TRANS_TRY do {                          \
60   struct trans *_t = trans_open();              \
61   if (!setjmp(_t->jmp))                         \
62     {
63
64 #define TRANS_CATCH(x)                          \
65       trans_commit();                           \
66     }                                           \
67   else                                          \
68     {                                           \
69       struct exception *x UNUSED = trans_current_exc();
70
71 #define TRANS_END                               \
72       trans_rollback();                         \
73     }                                           \
74   } while(0)
75
76 #endif