diff options
author | Agustina Arzille <avarzille@riseup.net> | 2018-03-18 17:27:00 +0100 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2018-03-18 17:27:00 +0100 |
commit | 542c20a171cbc8cb63155fa6344708d26e9c446b (patch) | |
tree | 0abb2c4b09254ca8d4af9e18d8f28dee4f01086d /sysdeps/mach | |
parent | 9a37922ee049c2a12ba9d9457f7711ecd9813c88 (diff) | |
download | glibc-542c20a171cbc8cb63155fa6344708d26e9c446b.tar.gz glibc-542c20a171cbc8cb63155fa6344708d26e9c446b.tar.xz glibc-542c20a171cbc8cb63155fa6344708d26e9c446b.zip |
hurd: Rewrite __libc_cleanup_*
This makes it notably safe against 'return' and such, and used for __libc_cleanup_push/pop. * sysdeps/mach/libc-lock.h (__libc_cleanup_frame): Define structure. (__libc_cleanup_fct): Define function. (__libc_cleanup_region_start, __libc_cleanup_region_end, __libc_cleanup_end): Rewrite implementation using __attribute__ ((__cleanup__)). (__libc_cleanup_push, __libc_cleanup_pop): New macros.
Diffstat (limited to 'sysdeps/mach')
-rw-r--r-- | sysdeps/mach/libc-lock.h | 47 |
1 files changed, 30 insertions, 17 deletions
diff --git a/sysdeps/mach/libc-lock.h b/sysdeps/mach/libc-lock.h index 89e5715341..1bb0235cf2 100644 --- a/sysdeps/mach/libc-lock.h +++ b/sysdeps/mach/libc-lock.h @@ -73,25 +73,38 @@ typedef cthread_key_t __libc_key_t; #define __libc_rwlock_trywrlock __libc_lock_trylock #define __libc_rwlock_unlock __libc_lock_unlock - -/* Start a critical region with a cleanup function */ -#define __libc_cleanup_region_start(DOIT, FCT, ARG) \ -{ \ - typeof (***(FCT)) *__save_FCT = (DOIT) ? (FCT) : 0; \ - typeof (ARG) __save_ARG = ARG; \ - /* close brace is in __libc_cleanup_region_end below. */ - -/* End a critical region started with __libc_cleanup_region_start. */ -#define __libc_cleanup_region_end(DOIT) \ - if ((DOIT) && __save_FCT != 0) \ - (*__save_FCT)(__save_ARG); \ +struct __libc_cleanup_frame +{ + void (*__fct) (void *); + void *__argp; + int __doit; +}; + +__extern_inline void +__libc_cleanup_fct (struct __libc_cleanup_frame *framep) +{ + if (framep->__doit) + framep->__fct (framep->__argp); } -/* Sometimes we have to exit the block in the middle. */ -#define __libc_cleanup_end(DOIT) \ - if ((DOIT) && __save_FCT != 0) \ - (*__save_FCT)(__save_ARG); \ - +/* Start a critical region with a cleanup function */ +#define __libc_cleanup_region_start(DOIT, FCT, ARG) \ + do \ + { \ + struct __libc_cleanup_frame __cleanup \ + __attribute__ ((__cleanup__ (__libc_cleanup_fct))) = \ + { .__fct = (FCT), .__argp = (ARG), .__doit = (DOIT) }; + +/* This one closes the brace above. */ +#define __libc_cleanup_region_end(DOIT) \ + __cleanup.__doit = (DOIT); \ + } \ + while (0) + +#define __libc_cleanup_end(DOIT) __cleanup.__doit = (DOIT); + +#define __libc_cleanup_push(fct, arg) __libc_cleanup_region_start (1, fct, arg) +#define __libc_cleanup_pop(execute) __libc_cleanup_region_end (execute) /* Use mutexes as once control variables. */ |