diff options
Diffstat (limited to 'linuxthreads/ptlongjmp.c')
-rw-r--r-- | linuxthreads/ptlongjmp.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/linuxthreads/ptlongjmp.c b/linuxthreads/ptlongjmp.c new file mode 100644 index 0000000000..1397dba43a --- /dev/null +++ b/linuxthreads/ptlongjmp.c @@ -0,0 +1,44 @@ +/* Linuxthreads - a simple clone()-based implementation of Posix */ +/* threads for Linux. */ +/* Copyright (C) 1998 Xavier Leroy (Xavier.Leroy@inria.fr) */ +/* */ +/* This program is free software; you can redistribute it and/or */ +/* modify it under the terms of the GNU Library General Public License */ +/* as published by the Free Software Foundation; either version 2 */ +/* of the License, or (at your option) any later version. */ +/* */ +/* This program is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +/* GNU Library General Public License for more details. */ + +/* Redefine siglongjmp and longjmp so that they interact correctly + with cleanup handlers */ + +#include <setjmp.h> +#include "pthread.h" +#include "internals.h" + +static void pthread_cleanup_upto(__jmp_buf target) +{ + pthread_descr self = thread_self(); + struct _pthread_cleanup_buffer * c; + + for (c = self->p_cleanup; + c != NULL && _JMPBUF_UNWINDS(target, c); + c = c->prev) + c->routine(c->arg); + self->p_cleanup = c; +} + +void siglongjmp(sigjmp_buf env, int val) +{ + pthread_cleanup_upto(env->__jmpbuf); + __libc_siglongjmp(env, val); +} + +void longjmp(jmp_buf env, int val) +{ + pthread_cleanup_upto(env->__jmpbuf); + __libc_longjmp(env, val); +} |