diff --git a/src/include/pthread.h b/src/include/pthread.h index f2a4dff1..937fef36 100644 --- a/src/include/pthread.h +++ b/src/include/pthread.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pthread.h,v 1.1 2017/10/15 23:40:33 guenther Exp $ */ +/* $OpenBSD: pthread.h,v 1.2 2017/10/28 21:23:14 guenther Exp $ */ /* * Copyright (c) 1993, 1994 by Chris Provenzano, proven@mit.edu @@ -179,10 +179,41 @@ enum pthread_mutextype { #define PTHREAD_MUTEX_STRICT_NP PTHREAD_MUTEX_STRICT_NP #define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_STRICT_NP +/* + * On-stack structure for the pthread_cleanup_{push,pop} macros + * The actual values are xor'ed with random cookies. + */ +struct __thread_cleanup { + __uintptr_t __tc_magic; + __uintptr_t __tc_next; + __uintptr_t __tc_fn; + __uintptr_t __tc_arg; +}; + +/* + * These macro must be used in pairs in the same scope, such that + * pthread_cleanup_push() can start a block declaring a variable and + * pthread_cleanup_pop() closes that same block. Any other usage + * violates the requirements of the POSIX and Single UNIX standards. + */ +#define pthread_cleanup_push(cb, arg) \ + { /* MATCHED BY CLOSE BRACKET IN pthread_cleanup_pop() */ \ + struct __thread_cleanup __tc; \ + _thread_cleanup_push(cb, arg, &__tc); + +#define pthread_cleanup_pop(execute) \ + _thread_cleanup_pop(execute, &__tc); \ + } /* MATCHED BY OPEN BRACKET IN pthread_cleanup_push() */ + + + /* * Thread function prototype definitions: */ __BEGIN_DECLS +void _thread_cleanup_pop(int _execute, struct __thread_cleanup *_tc); +void _thread_cleanup_push(void (*_fn)(void *), void *_arg, + struct __thread_cleanup *_tc); int pthread_atfork(void (*)(void), void (*)(void), void (*)(void)); int pthread_attr_destroy(pthread_attr_t *); int pthread_attr_getstack(const pthread_attr_t *, @@ -197,8 +228,6 @@ int pthread_attr_setstack(pthread_attr_t *, void *, size_t); int pthread_attr_setstackaddr(pthread_attr_t *, void *); int pthread_attr_setguardsize(pthread_attr_t *, size_t); int pthread_attr_setdetachstate(pthread_attr_t *, int); -void pthread_cleanup_pop(int); -void pthread_cleanup_push(void (*) (void *), void *routine_arg); int pthread_condattr_destroy(pthread_condattr_t *); int pthread_condattr_init(pthread_condattr_t *);