mirror of
https://sourceware.org/git/glibc.git
synced 2025-08-01 10:06:57 +03:00
Update.
2003-11-05 Jakub Jelinek <jakub@redhat.com> * unwind.c (FRAME_LEFT): Define. (unwind_stop): Handle old style cleanups here. (__pthread_unwind): Handle old style cleanups only if !HAVE_FORCED_UNWIND. * Makefile (tests): Add tst-cleanup4 and tst-cleanupx4. (CFLAGS-tst-cleanupx4.c): Add -fexceptions. ($(objpfx)tst-cleanup4): Depend on $(objpfx)tst-cleanup4aux.o. ($(objpfx)tst-cleanupx4): Likewise. * tst-cleanup4.c: New test. * tst-cleanup4aux.c: New. * tst-cleanupx4.c: New test.
This commit is contained in:
@ -1,3 +1,17 @@
|
|||||||
|
2003-11-05 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
|
* unwind.c (FRAME_LEFT): Define.
|
||||||
|
(unwind_stop): Handle old style cleanups here.
|
||||||
|
(__pthread_unwind): Handle old style cleanups only if
|
||||||
|
!HAVE_FORCED_UNWIND.
|
||||||
|
* Makefile (tests): Add tst-cleanup4 and tst-cleanupx4.
|
||||||
|
(CFLAGS-tst-cleanupx4.c): Add -fexceptions.
|
||||||
|
($(objpfx)tst-cleanup4): Depend on $(objpfx)tst-cleanup4aux.o.
|
||||||
|
($(objpfx)tst-cleanupx4): Likewise.
|
||||||
|
* tst-cleanup4.c: New test.
|
||||||
|
* tst-cleanup4aux.c: New.
|
||||||
|
* tst-cleanupx4.c: New test.
|
||||||
|
|
||||||
2003-11-04 Ulrich Drepper <drepper@redhat.com>
|
2003-11-04 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
* sysdeps/pthread/bits/stdio-lock.h: Use lll_*lock instead of
|
* sysdeps/pthread/bits/stdio-lock.h: Use lll_*lock instead of
|
||||||
|
@ -216,7 +216,7 @@ tests = tst-attr1 tst-attr2 tst-attr3 \
|
|||||||
tst-cancel6 tst-cancel7 tst-cancel8 tst-cancel9 tst-cancel10 \
|
tst-cancel6 tst-cancel7 tst-cancel8 tst-cancel9 tst-cancel10 \
|
||||||
tst-cancel11 tst-cancel12 tst-cancel13 tst-cancel14 tst-cancel15 \
|
tst-cancel11 tst-cancel12 tst-cancel13 tst-cancel14 tst-cancel15 \
|
||||||
tst-cancel16 tst-cancel17 tst-cancel18 tst-cancel19 \
|
tst-cancel16 tst-cancel17 tst-cancel18 tst-cancel19 \
|
||||||
tst-cleanup0 tst-cleanup1 tst-cleanup2 tst-cleanup3 \
|
tst-cleanup0 tst-cleanup1 tst-cleanup2 tst-cleanup3 tst-cleanup4 \
|
||||||
tst-flock1 tst-flock2 \
|
tst-flock1 tst-flock2 \
|
||||||
tst-signal1 tst-signal2 tst-signal3 tst-signal4 tst-signal5 \
|
tst-signal1 tst-signal2 tst-signal3 tst-signal4 tst-signal5 \
|
||||||
tst-signal6 \
|
tst-signal6 \
|
||||||
@ -248,7 +248,7 @@ tests += tst-cancelx2 tst-cancelx3 tst-cancelx4 tst-cancelx5 \
|
|||||||
tst-cancelx6 tst-cancelx7 tst-cancelx8 tst-cancelx9 tst-cancelx10 \
|
tst-cancelx6 tst-cancelx7 tst-cancelx8 tst-cancelx9 tst-cancelx10 \
|
||||||
tst-cancelx11 tst-cancelx12 tst-cancelx13 tst-cancelx14 tst-cancelx15\
|
tst-cancelx11 tst-cancelx12 tst-cancelx13 tst-cancelx14 tst-cancelx15\
|
||||||
tst-cancelx16 tst-cancelx17 tst-cancelx18 \
|
tst-cancelx16 tst-cancelx17 tst-cancelx18 \
|
||||||
tst-cleanupx0 tst-cleanupx1 tst-cleanupx2 tst-cleanupx3 \
|
tst-cleanupx0 tst-cleanupx1 tst-cleanupx2 tst-cleanupx3 tst-cleanupx4 \
|
||||||
tst-oncex3 tst-oncex4
|
tst-oncex3 tst-oncex4
|
||||||
endif
|
endif
|
||||||
ifeq ($(build-shared),yes)
|
ifeq ($(build-shared),yes)
|
||||||
@ -393,6 +393,7 @@ CFLAGS-tst-cleanupx0.c += -fexceptions -fasynchronous-unwind-tables
|
|||||||
CFLAGS-tst-cleanupx1.c += -fexceptions -fasynchronous-unwind-tables
|
CFLAGS-tst-cleanupx1.c += -fexceptions -fasynchronous-unwind-tables
|
||||||
CFLAGS-tst-cleanupx2.c += -fexceptions
|
CFLAGS-tst-cleanupx2.c += -fexceptions
|
||||||
CFLAGS-tst-cleanupx3.c += -fexceptions
|
CFLAGS-tst-cleanupx3.c += -fexceptions
|
||||||
|
CFLAGS-tst-cleanupx4.c += -fexceptions
|
||||||
CFLAGS-tst-oncex3.c += -fexceptions
|
CFLAGS-tst-oncex3.c += -fexceptions
|
||||||
CFLAGS-tst-oncex4.c += -fexceptions
|
CFLAGS-tst-oncex4.c += -fexceptions
|
||||||
CFLAGS-tst-align.c += $(stack-align-test-flags)
|
CFLAGS-tst-align.c += $(stack-align-test-flags)
|
||||||
@ -405,6 +406,9 @@ LDFLAGS-tst-atfork2 = -rdynamic
|
|||||||
tst-atfork2-ENV = MALLOC_TRACE=$(objpfx)tst-atfork2.mtrace
|
tst-atfork2-ENV = MALLOC_TRACE=$(objpfx)tst-atfork2.mtrace
|
||||||
$(objpfx)tst-atfork2mod.so: $(shared-thread-library)
|
$(objpfx)tst-atfork2mod.so: $(shared-thread-library)
|
||||||
|
|
||||||
|
$(objpfx)tst-cleanup4: $(objpfx)tst-cleanup4aux.o $(shared-thread-library)
|
||||||
|
$(objpfx)tst-cleanupx4: $(objpfx)tst-cleanup4aux.o $(shared-thread-library)
|
||||||
|
|
||||||
$(objpfx)tst-tls3: $(libdl) $(shared-thread-library)
|
$(objpfx)tst-tls3: $(libdl) $(shared-thread-library)
|
||||||
LDFLAGS-tst-tls3 = -rdynamic
|
LDFLAGS-tst-tls3 = -rdynamic
|
||||||
$(objpfx)tst-tls3.out: $(objpfx)tst-tls3mod.so
|
$(objpfx)tst-tls3.out: $(objpfx)tst-tls3mod.so
|
||||||
|
198
nptl/tst-cleanup4.c
Normal file
198
nptl/tst-cleanup4.c
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
/* Copyright (C) 2003 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
The GNU C Library 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
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; if not, write to the Free
|
||||||
|
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
02111-1307 USA. */
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
/* LinuxThreads pthread_cleanup_{push,pop} helpers. */
|
||||||
|
extern void _pthread_cleanup_push (struct _pthread_cleanup_buffer *__buffer,
|
||||||
|
void (*__routine) (void *),
|
||||||
|
void *__arg);
|
||||||
|
extern void _pthread_cleanup_pop (struct _pthread_cleanup_buffer *__buffer,
|
||||||
|
int __execute);
|
||||||
|
|
||||||
|
static int fds[2];
|
||||||
|
static pthread_barrier_t b2;
|
||||||
|
static int global;
|
||||||
|
|
||||||
|
/* Defined in tst-cleanup4aux.c, never compiled with -fexceptions. */
|
||||||
|
extern void fn5 (void);
|
||||||
|
extern void fn7 (void);
|
||||||
|
extern void fn9 (void);
|
||||||
|
|
||||||
|
void
|
||||||
|
clh (void *arg)
|
||||||
|
{
|
||||||
|
int val = (long int) arg;
|
||||||
|
|
||||||
|
printf ("clh (%d)\n", val);
|
||||||
|
|
||||||
|
global *= val;
|
||||||
|
global += val;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static __attribute__((noinline)) void
|
||||||
|
fn_read (void)
|
||||||
|
{
|
||||||
|
int r = pthread_barrier_wait (&b2);
|
||||||
|
if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD)
|
||||||
|
{
|
||||||
|
printf ("%s: barrier_wait failed\n", __FUNCTION__);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
char c;
|
||||||
|
read (fds[0], &c, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
__attribute__((noinline)) void
|
||||||
|
fn0 (void)
|
||||||
|
{
|
||||||
|
pthread_cleanup_push (clh, (void *) 1l);
|
||||||
|
|
||||||
|
fn_read ();
|
||||||
|
|
||||||
|
pthread_cleanup_pop (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
__attribute__((noinline)) void
|
||||||
|
fn1 (void)
|
||||||
|
{
|
||||||
|
/* This is the old LinuxThreads pthread_cleanup_{push,pop}. */
|
||||||
|
struct _pthread_cleanup_buffer b;
|
||||||
|
_pthread_cleanup_push (&b, clh, (void *) 2l);
|
||||||
|
|
||||||
|
fn0 ();
|
||||||
|
|
||||||
|
_pthread_cleanup_pop (&b, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static __attribute__((noinline)) void
|
||||||
|
fn2 (void)
|
||||||
|
{
|
||||||
|
pthread_cleanup_push (clh, (void *) 3l);
|
||||||
|
|
||||||
|
fn1 ();
|
||||||
|
|
||||||
|
pthread_cleanup_pop (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void *
|
||||||
|
tf (void *a)
|
||||||
|
{
|
||||||
|
switch ((long) a)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
fn2 ();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
fn5 ();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
fn7 ();
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
fn9 ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
do_test (void)
|
||||||
|
{
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
if (pipe (fds) != 0)
|
||||||
|
{
|
||||||
|
puts ("pipe failed");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pthread_barrier_init (&b2, NULL, 2) != 0)
|
||||||
|
{
|
||||||
|
puts ("b2 init failed");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const int expect[] =
|
||||||
|
{
|
||||||
|
15, /* 1 2 3 */
|
||||||
|
276, /* 1 4 5 6 */
|
||||||
|
120, /* 1 7 8 */
|
||||||
|
460 /* 1 2 9 10 */
|
||||||
|
};
|
||||||
|
|
||||||
|
long i;
|
||||||
|
for (i = 0; i < 4; ++i)
|
||||||
|
{
|
||||||
|
global = 0;
|
||||||
|
|
||||||
|
printf ("test %ld\n", i);
|
||||||
|
|
||||||
|
pthread_t th;
|
||||||
|
if (pthread_create (&th, NULL, tf, (void *) i) != 0)
|
||||||
|
{
|
||||||
|
puts ("create failed");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int e = pthread_barrier_wait (&b2);
|
||||||
|
if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
|
||||||
|
{
|
||||||
|
printf ("%s: barrier_wait failed\n", __FUNCTION__);
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_cancel (th);
|
||||||
|
|
||||||
|
void *r;
|
||||||
|
if ((e = pthread_join (th, &r)) != 0)
|
||||||
|
{
|
||||||
|
printf ("join failed: %d\n", e);
|
||||||
|
_exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r != PTHREAD_CANCELED)
|
||||||
|
{
|
||||||
|
puts ("thread not canceled");
|
||||||
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (global != expect[i])
|
||||||
|
{
|
||||||
|
printf ("global = %d, expected %d\n", global, expect[i]);
|
||||||
|
result = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define TEST_FUNCTION do_test ()
|
||||||
|
#include "../test-skeleton.c"
|
121
nptl/tst-cleanup4aux.c
Normal file
121
nptl/tst-cleanup4aux.c
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
/* Copyright (C) 2003 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
The GNU C Library 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
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; if not, write to the Free
|
||||||
|
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
02111-1307 USA. */
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
extern void _pthread_cleanup_push (struct _pthread_cleanup_buffer *__buffer,
|
||||||
|
void (*__routine) (void *),
|
||||||
|
void *__arg);
|
||||||
|
extern void _pthread_cleanup_pop (struct _pthread_cleanup_buffer *__buffer,
|
||||||
|
int __execute);
|
||||||
|
|
||||||
|
extern void clh (void *arg);
|
||||||
|
extern void fn0 (void);
|
||||||
|
extern void fn1 (void);
|
||||||
|
extern void fn5 (void);
|
||||||
|
extern void fn7 (void);
|
||||||
|
extern void fn9 (void);
|
||||||
|
|
||||||
|
|
||||||
|
static __attribute__((noinline)) void
|
||||||
|
fn3 (void)
|
||||||
|
{
|
||||||
|
/* This is the old LinuxThreads pthread_cleanup_{push,pop}. */
|
||||||
|
struct _pthread_cleanup_buffer b;
|
||||||
|
_pthread_cleanup_push (&b, clh, (void *) 4l);
|
||||||
|
|
||||||
|
fn0 ();
|
||||||
|
|
||||||
|
_pthread_cleanup_pop (&b, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static __attribute__((noinline)) void
|
||||||
|
fn4 (void)
|
||||||
|
{
|
||||||
|
pthread_cleanup_push (clh, (void *) 5l);
|
||||||
|
|
||||||
|
fn3 ();
|
||||||
|
|
||||||
|
pthread_cleanup_pop (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
fn5 (void)
|
||||||
|
{
|
||||||
|
/* This is the old LinuxThreads pthread_cleanup_{push,pop}. */
|
||||||
|
struct _pthread_cleanup_buffer b;
|
||||||
|
_pthread_cleanup_push (&b, clh, (void *) 6l);
|
||||||
|
|
||||||
|
fn4 ();
|
||||||
|
|
||||||
|
_pthread_cleanup_pop (&b, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static __attribute__((noinline)) void
|
||||||
|
fn6 (void)
|
||||||
|
{
|
||||||
|
pthread_cleanup_push (clh, (void *) 7l);
|
||||||
|
|
||||||
|
fn0 ();
|
||||||
|
|
||||||
|
pthread_cleanup_pop (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
fn7 (void)
|
||||||
|
{
|
||||||
|
/* This is the old LinuxThreads pthread_cleanup_{push,pop}. */
|
||||||
|
struct _pthread_cleanup_buffer b;
|
||||||
|
_pthread_cleanup_push (&b, clh, (void *) 8l);
|
||||||
|
|
||||||
|
fn6 ();
|
||||||
|
|
||||||
|
_pthread_cleanup_pop (&b, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static __attribute__((noinline)) void
|
||||||
|
fn8 (void)
|
||||||
|
{
|
||||||
|
pthread_cleanup_push (clh, (void *) 9l);
|
||||||
|
|
||||||
|
fn1 ();
|
||||||
|
|
||||||
|
pthread_cleanup_pop (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
fn9 (void)
|
||||||
|
{
|
||||||
|
/* This is the old LinuxThreads pthread_cleanup_{push,pop}. */
|
||||||
|
struct _pthread_cleanup_buffer b;
|
||||||
|
_pthread_cleanup_push (&b, clh, (void *) 10l);
|
||||||
|
|
||||||
|
fn8 ();
|
||||||
|
|
||||||
|
_pthread_cleanup_pop (&b, 1);
|
||||||
|
}
|
1
nptl/tst-cleanupx4.c
Normal file
1
nptl/tst-cleanupx4.c
Normal file
@ -0,0 +1 @@
|
|||||||
|
#include "tst-cleanup4.c"
|
@ -27,6 +27,14 @@
|
|||||||
|
|
||||||
#ifdef HAVE_FORCED_UNWIND
|
#ifdef HAVE_FORCED_UNWIND
|
||||||
|
|
||||||
|
#ifdef _STACK_GROWS_DOWN
|
||||||
|
# define FRAME_LEFT(frame, other) ((char *) frame >= (char *) other)
|
||||||
|
#elif _STACK_GROWS_UP
|
||||||
|
# define FRAME_LEFT(frame, other) ((char *) frame <= (char *) other)
|
||||||
|
#else
|
||||||
|
# error "Define either _STACK_GROWS_DOWN or _STACK_GROWS_UP"
|
||||||
|
#endif
|
||||||
|
|
||||||
static _Unwind_Reason_Code
|
static _Unwind_Reason_Code
|
||||||
unwind_stop (int version, _Unwind_Action actions,
|
unwind_stop (int version, _Unwind_Action actions,
|
||||||
_Unwind_Exception_Class exc_class,
|
_Unwind_Exception_Class exc_class,
|
||||||
@ -34,6 +42,9 @@ unwind_stop (int version, _Unwind_Action actions,
|
|||||||
struct _Unwind_Context *context, void *stop_parameter)
|
struct _Unwind_Context *context, void *stop_parameter)
|
||||||
{
|
{
|
||||||
struct pthread_unwind_buf *buf = stop_parameter;
|
struct pthread_unwind_buf *buf = stop_parameter;
|
||||||
|
struct pthread *self = THREAD_SELF;
|
||||||
|
struct _pthread_cleanup_buffer *curp = THREAD_GETMEM (self, cleanup);
|
||||||
|
int do_longjump = 0;
|
||||||
|
|
||||||
/* Do longjmp if we're at "end of stack", aka "end of unwind data".
|
/* Do longjmp if we're at "end of stack", aka "end of unwind data".
|
||||||
We assume there are only C frame without unwind data in between
|
We assume there are only C frame without unwind data in between
|
||||||
@ -42,6 +53,37 @@ unwind_stop (int version, _Unwind_Action actions,
|
|||||||
previous frame. */
|
previous frame. */
|
||||||
if ((actions & _UA_END_OF_STACK)
|
if ((actions & _UA_END_OF_STACK)
|
||||||
|| ! _JMPBUF_CFA_UNWINDS (buf->cancel_jmp_buf[0].jmp_buf, context))
|
|| ! _JMPBUF_CFA_UNWINDS (buf->cancel_jmp_buf[0].jmp_buf, context))
|
||||||
|
do_longjump = 1;
|
||||||
|
|
||||||
|
if (__builtin_expect (curp != NULL, 0))
|
||||||
|
{
|
||||||
|
/* Handle the compatibility stuff. Execute all handlers
|
||||||
|
registered with the old method which would be unwound by this
|
||||||
|
step. */
|
||||||
|
struct _pthread_cleanup_buffer *oldp = buf->priv.data.cleanup;
|
||||||
|
void *cfa = (void *) _Unwind_GetCFA (context);
|
||||||
|
|
||||||
|
if (curp != oldp && (do_longjump || FRAME_LEFT (cfa, curp)))
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
/* Pointer to the next element. */
|
||||||
|
struct _pthread_cleanup_buffer *nextp = curp->__prev;
|
||||||
|
|
||||||
|
/* Call the handler. */
|
||||||
|
curp->__routine (curp->__arg);
|
||||||
|
|
||||||
|
/* To the next. */
|
||||||
|
curp = nextp;
|
||||||
|
}
|
||||||
|
while (curp != oldp && (do_longjump || FRAME_LEFT (cfa, curp)));
|
||||||
|
|
||||||
|
/* Mark the current element as handled. */
|
||||||
|
THREAD_SETMEM (self, cleanup, curp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (do_longjump)
|
||||||
__libc_longjmp ((struct __jmp_buf_tag *) buf->cancel_jmp_buf, 1);
|
__libc_longjmp ((struct __jmp_buf_tag *) buf->cancel_jmp_buf, 1);
|
||||||
|
|
||||||
return _URC_NO_REASON;
|
return _URC_NO_REASON;
|
||||||
@ -70,6 +112,14 @@ __pthread_unwind (__pthread_unwind_buf_t *buf)
|
|||||||
struct pthread_unwind_buf *ibuf = (struct pthread_unwind_buf *) buf;
|
struct pthread_unwind_buf *ibuf = (struct pthread_unwind_buf *) buf;
|
||||||
struct pthread *self = THREAD_SELF;
|
struct pthread *self = THREAD_SELF;
|
||||||
|
|
||||||
|
#ifdef HAVE_FORCED_UNWIND
|
||||||
|
/* This is not a catchable exception, so don't provide any details about
|
||||||
|
the exception type. We do need to initialize the field though. */
|
||||||
|
THREAD_SETMEM (self, exc.exception_class, 0);
|
||||||
|
THREAD_SETMEM (self, exc.exception_cleanup, unwind_cleanup);
|
||||||
|
|
||||||
|
_Unwind_ForcedUnwind (&self->exc, unwind_stop, ibuf);
|
||||||
|
#else
|
||||||
/* Handle the compatibility stuff first. Execute all handlers
|
/* Handle the compatibility stuff first. Execute all handlers
|
||||||
registered with the old method. We don't execute them in order,
|
registered with the old method. We don't execute them in order,
|
||||||
instead, they will run first. */
|
instead, they will run first. */
|
||||||
@ -95,14 +145,6 @@ __pthread_unwind (__pthread_unwind_buf_t *buf)
|
|||||||
THREAD_SETMEM (self, cleanup, curp);
|
THREAD_SETMEM (self, cleanup, curp);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_FORCED_UNWIND
|
|
||||||
/* This is not a catchable exception, so don't provide any details about
|
|
||||||
the exception type. We do need to initialize the field though. */
|
|
||||||
THREAD_SETMEM (self, exc.exception_class, 0);
|
|
||||||
THREAD_SETMEM (self, exc.exception_cleanup, unwind_cleanup);
|
|
||||||
|
|
||||||
_Unwind_ForcedUnwind (&self->exc, unwind_stop, ibuf);
|
|
||||||
#else
|
|
||||||
/* We simply jump to the registered setjmp buffer. */
|
/* We simply jump to the registered setjmp buffer. */
|
||||||
__libc_longjmp ((struct __jmp_buf_tag *) ibuf->cancel_jmp_buf, 1);
|
__libc_longjmp ((struct __jmp_buf_tag *) ibuf->cancel_jmp_buf, 1);
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user