|
12 | 12 |
|
13 | 13 | BFDEV_BEGIN_DECLS |
14 | 14 |
|
15 | | -#define BFDEV_CLEAN_TEMPLATE(name, type, free) \ |
| 15 | +/** |
| 16 | + * Guards: |
| 17 | + * |
| 18 | + * The "goto error" pattern is notorious for introducing subtle resource |
| 19 | + * leaks. It is tedious and error prone to add new resource acquisition |
| 20 | + * constraints into code paths that already have several unwind |
| 21 | + * conditions. The "cleanup" helpers enable the compiler to help with |
| 22 | + * this tedium and can aid in maintaining LIFO (last in first out) |
| 23 | + * unwind ordering to avoid unintentional leaks. |
| 24 | + */ |
| 25 | + |
| 26 | +#define BFDEV_DEFINE_CLEAN(name, type, free) \ |
16 | 27 | static inline void \ |
17 | 28 | __bfdev_cleanup_##name(void *object) \ |
18 | 29 | { \ |
19 | 30 | type _T = *(type *)object; \ |
20 | 31 | free; \ |
21 | 32 | } |
22 | 33 |
|
23 | | -#define bfdev_clean_lasting(object) ({ \ |
24 | | - __auto_type __ptr = (object); \ |
25 | | - (object) = BFDEV_NULL; __ptr; \ |
26 | | -}) |
27 | | - |
28 | | -#define bfdev_clean(name) \ |
| 34 | +#define BFDEV_CLEAN(name) \ |
29 | 35 | __bfdev_cleanup(__bfdev_cleanup_##name) |
30 | 36 |
|
31 | | -#define bfdev_clean_return(object) \ |
32 | | - return bfdev_clean_lasting(object) |
| 37 | +#define BFDEV_DEFINE_CLASS(name, type, ctor, dtor, args...) \ |
| 38 | +typedef type __bfdev_class_##name##_t; \ |
| 39 | +static inline type \ |
| 40 | +__bfdev_class_##name##_constructor(args) \ |
| 41 | +{ \ |
| 42 | + type __tmp = ctor; \ |
| 43 | + return __tmp; \ |
| 44 | +} \ |
| 45 | +static inline void \ |
| 46 | +__bfdev_class_##name##_destructor(type *p) \ |
| 47 | +{ \ |
| 48 | + type _T = *p; \ |
| 49 | + dtor; \ |
| 50 | +} |
| 51 | + |
| 52 | +#define BFDEV_CLASS(name, var) \ |
| 53 | + __bfdev_class_##name##_t var \ |
| 54 | + __bfdev_cleanup(__bfdev_class_##name##_destructor) = \ |
| 55 | + __bfdev_class_##name##_constructor |
| 56 | + |
| 57 | +#define bfdev_lasting(object) ({ \ |
| 58 | + __auto_type __ptr = (object); \ |
| 59 | + (object) = BFDEV_NULL; __ptr; \ |
| 60 | +}) |
| 61 | + |
| 62 | +#define bfdev_return(object) \ |
| 63 | + return bfdev_lasting(object) |
33 | 64 |
|
34 | 65 | BFDEV_END_DECLS |
35 | 66 |
|
|
0 commit comments