Browse Source

Change pthread_cleanup_{push,pop} to macros that store the cleanup info

on the stack instead of mallocing the list and move the APIs from libpthread
to libc so that they can be used inside libc.
Note: the standard was explicitly written to permit/support this
"macro with unmatched brace" style and it's what basically everyone
else already does.  We xor the info with random cookies with a
random magic to detect/trip-up overwrites.
Major bump to both libc and libpthread due to the API move.
ok mpi@
OPENBSD_6_3
guenther 7 years ago
parent
commit
88624e3e2e
1 changed files with 32 additions and 3 deletions
  1. +32
    -3
      src/include/pthread.h

+ 32
- 3
src/include/pthread.h View File

@ -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 * 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_STRICT_NP PTHREAD_MUTEX_STRICT_NP
#define PTHREAD_MUTEX_DEFAULT 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: * Thread function prototype definitions:
*/ */
__BEGIN_DECLS __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_atfork(void (*)(void), void (*)(void), void (*)(void));
int pthread_attr_destroy(pthread_attr_t *); int pthread_attr_destroy(pthread_attr_t *);
int pthread_attr_getstack(const 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_setstackaddr(pthread_attr_t *, void *);
int pthread_attr_setguardsize(pthread_attr_t *, size_t); int pthread_attr_setguardsize(pthread_attr_t *, size_t);
int pthread_attr_setdetachstate(pthread_attr_t *, int); 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_destroy(pthread_condattr_t *);
int pthread_condattr_init(pthread_condattr_t *); int pthread_condattr_init(pthread_condattr_t *);


Loading…
Cancel
Save