]> mj.ucw.cz Git - libucw.git/blob - ucw/trans.h
Lizard: Fixed compilation warning in tests.
[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 #ifdef CONFIG_UCW_CLEAN_ABI
18 #define trans_caught ucw_trans_caught
19 #define trans_cleanup ucw_trans_cleanup
20 #define trans_commit ucw_trans_commit
21 #define trans_current_exc ucw_trans_current_exc
22 #define trans_dump ucw_trans_dump
23 #define trans_fold ucw_trans_fold
24 #define trans_get_current ucw_trans_get_current
25 #define trans_get_pool ucw_trans_get_pool
26 #define trans_init ucw_trans_init
27 #define trans_open ucw_trans_open
28 #define trans_rollback ucw_trans_rollback
29 #define trans_throw ucw_trans_throw
30 #define trans_throw_exc ucw_trans_throw_exc
31 #define trans_vthrow ucw_trans_vthrow
32 #endif
33
34 /** A structure describing a transaction. All fields are for internal use only. **/
35 struct trans {
36   struct trans *prev_trans;
37   struct mempool_state *trans_pool_state;
38   struct respool *rpool;
39   struct respool *prev_rpool;
40   struct exception *thrown_exc;
41   jmp_buf jmp;
42 };
43
44 void trans_init(void);          /** Initializes the transaction system for the current thread. Called automatically as needed. **/
45 void trans_cleanup(void);       /** Frees memory occupied by the transaction system pools for the current thread. **/
46
47 struct trans *trans_open(void); /** Creates a new transaction. Used inside `TRANS_TRY`. **/
48 struct trans *trans_get_current(void);  /** Get a pointer to the currently running transaction, or NULL if there is none. **/
49 void trans_commit(void);        /** Commits the current transaction. **/
50 void trans_rollback(void);      /** Rolls back the current transaction. **/
51 void trans_fold(void);          /** Folds the current transaction to its parent. **/
52 void trans_dump(void);          /** Prints out a debugging dump of the transaction stack to stdout. **/
53
54 struct mempool *trans_get_pool(void);
55
56 /**
57  * Data associated with an exception. Usually, this structure is created
58  * by calling @trans_throw(), but if you want to pass more data, you can
59  * create your own exception and throw it using @trans_throw_exc().
60  **/
61 struct exception {
62   const char *id;               // Hierarchical identifier of the exception
63   const char *msg;              // Error message to present to the user
64   void *object;                 // Object on which the exception happened
65   // More data specific for the particular `id' can follow
66 };
67
68 /** Creates an exception and throws it. The error message can contain `printf`-like formatting. **/
69 void trans_throw(const char *id, void *object, const char *fmt, ...) FORMAT_CHECK(printf,3,4) NONRET;
70
71 /** A `va_list` variant of @trans_throw(). **/
72 void trans_vthrow(const char *id, void *object, const char *fmt, va_list args) NONRET;
73
74 /** Throw an already constructed exception (or re-throw an exception you have caught). **/
75 void trans_throw_exc(struct exception *x) NONRET;
76
77 /** Declare the current exception caught and roll back the current transaction. Called from `TRANS_END`. **/
78 void trans_caught(void);
79
80 struct exception *trans_current_exc(void);      /** Return the exception in flight, or NULL if there is none. **/
81
82 #define TRANS_TRY do {                          \
83   struct trans *_t = trans_open();              \
84   if (!setjmp(_t->jmp))                         \
85     {
86
87 #define TRANS_CATCH(x)                          \
88       trans_commit();                           \
89     }                                           \
90   else                                          \
91     {                                           \
92       struct exception *x UNUSED = trans_current_exc();
93
94 #define TRANS_END                               \
95       trans_caught();                           \
96     }                                           \
97   } while(0)
98
99 #endif