Mercurial > dovecot > original-hg > dovecot-1.2
changeset 6939:c7b42fea5fcc HEAD
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.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 05 Dec 2007 17:47:19 +0200 |
parents | 8aaec038767c |
children | 414c9d631a81 |
files | src/lib/data-stack.c src/lib/data-stack.h |
diffstat | 2 files changed, 23 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- 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 @@ -192,6 +192,13 @@ 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) { struct stack_block *block;
--- 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 @@ */ 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.