From 542c20a171cbc8cb63155fa6344708d26e9c446b Mon Sep 17 00:00:00 2001 From: Agustina Arzille Date: Sun, 18 Mar 2018 17:27:00 +0100 Subject: 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. --- ChangeLog | 9 +++++++++ sysdeps/mach/libc-lock.h | 47 ++++++++++++++++++++++++++++++----------------- 2 files changed, 39 insertions(+), 17 deletions(-) diff --git a/ChangeLog b/ChangeLog index c0074a6c3b..36430d6169 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2018-03-18 Agustina Arzille + + * 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. + 2018-03-18 Samuel Thibault * sysdeps/mach/hurd/cthreads.c: Include . 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. */ -- cgit 1.4.1