dovecot: Added T_FRAME*() macros. It's too easy to accidentally ...
dovecot at dovecot.org
dovecot at dovecot.org
Wed Dec 5 17:47:53 EET 2007
details: http://hg.dovecot.org/dovecot/rev/c7b42fea5fcc
changeset: 6939:c7b42fea5fcc
user: Timo Sirainen <tss at iki.fi>
date: Wed Dec 05 17:47:19 2007 +0200
description:
Added T_FRAME*() macros. It's too easy to accidentally break t_push/t_pop
pairing. These new macros make it a lot more difficult.
diffstat:
2 files changed, 23 insertions(+)
src/lib/data-stack.c | 7 +++++++
src/lib/data-stack.h | 16 ++++++++++++++++
diffs (43 lines):
diff -r 8aaec038767c -r c7b42fea5fcc src/lib/data-stack.c
--- a/src/lib/data-stack.c Wed Dec 05 17:45:16 2007 +0200
+++ b/src/lib/data-stack.c Wed Dec 05 17:47:19 2007 +0200
@@ -190,6 +190,13 @@ unsigned int t_pop(void)
}
return --data_stack_frame;
+}
+
+void t_pop_check(unsigned int *id)
+{
+ if (unlikely(t_pop() != *id))
+ i_panic("Leaked t_pop() call");
+ *id = 0;
}
static struct stack_block *mem_block_alloc(size_t min_size)
diff -r 8aaec038767c -r c7b42fea5fcc src/lib/data-stack.h
--- a/src/lib/data-stack.h Wed Dec 05 17:45:16 2007 +0200
+++ b/src/lib/data-stack.h Wed Dec 05 17:47:19 2007 +0200
@@ -42,6 +42,22 @@ extern unsigned int data_stack_frame;
*/
unsigned int t_push(void);
unsigned int t_pop(void);
+/* Simplifies the if (t_pop() != x) check by comparing it internally and
+ panicking if it doesn't match. */
+void t_pop_check(unsigned int *id);
+
+/* Usage: T_FRAME_BEGIN { code } T_FRAME_END */
+#define T_FRAME_BEGIN \
+ STMT_START { unsigned int _data_stack_cur_id = t_push();
+#define T_FRAME_END \
+ t_pop_check(&_data_stack_cur_id); } STMT_END
+
+/* Usage: T_FRAME(code). This doesn't work if there are commas within the code
+ outside function parameters. */
+#define T_FRAME(_data_stack_code) \
+ T_FRAME_BEGIN { \
+ _data_stack_code; \
+ } T_FRAME_END
/* WARNING: Be careful when using these functions, it's too easy to
accidentally save the returned value somewhere permanently.
More information about the dovecot-cvs
mailing list