mirror of
https://sourceware.org/git/glibc.git
synced 2025-08-01 10:06:57 +03:00
nptl: Consolidate async cancel enable/disable implementation in libc
Previously, the source file nptl/cancellation.c was compiled multiple times, for libc, libpthread, librt. This commit switches to a single implementation, with new __pthread_enable_asynccancel@@GLIBC_PRIVATE, __pthread_disable_asynccancel@@GLIBC_PRIVATE exports. The almost-unused CANCEL_ASYNC and CANCEL_RESET macros are replaced by LIBC_CANCEL_ASYNC and LIBC_CANCEL_ASYNC macros. They call the __pthread_* functions unconditionally now. The macros are still needed because shared code uses them; Hurd has different definitions. Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
This commit is contained in:
@ -528,8 +528,10 @@ $(objpfx)dl-allobjs.os: $(all-rtld-routines:%=$(objpfx)%.os)
|
|||||||
# discovery mechanism is not compatible with the libc implementation
|
# discovery mechanism is not compatible with the libc implementation
|
||||||
# when compiled for libc.
|
# when compiled for libc.
|
||||||
rtld-stubbed-symbols = \
|
rtld-stubbed-symbols = \
|
||||||
__libc_disable_asynccancel \
|
__GI___pthread_disable_asynccancel \
|
||||||
__libc_enable_asynccancel \
|
__GI___pthread_enable_asynccancel \
|
||||||
|
__pthread_disable_asynccancel \
|
||||||
|
__pthread_enable_asynccancel \
|
||||||
calloc \
|
calloc \
|
||||||
free \
|
free \
|
||||||
malloc \
|
malloc \
|
||||||
|
@ -2534,13 +2534,13 @@ aiocb64}, since the LFS transparently replaces the old interface.
|
|||||||
@c sigemptyset ok
|
@c sigemptyset ok
|
||||||
@c sigaddset ok
|
@c sigaddset ok
|
||||||
@c setjmp ok
|
@c setjmp ok
|
||||||
@c CANCEL_ASYNC -> pthread_enable_asynccancel ok
|
@c LIBC_CANCEL_ASYNC -> __pthread_enable_asynccancel ok
|
||||||
@c do_cancel ok
|
@c do_cancel ok
|
||||||
@c pthread_unwind ok
|
@c pthread_unwind ok
|
||||||
@c Unwind_ForcedUnwind or longjmp ok [@ascuheap @acsmem?]
|
@c Unwind_ForcedUnwind or longjmp ok [@ascuheap @acsmem?]
|
||||||
@c lll_lock @asulock @aculock
|
@c lll_lock @asulock @aculock
|
||||||
@c lll_unlock @asulock @aculock
|
@c lll_unlock @asulock @aculock
|
||||||
@c CANCEL_RESET -> pthread_disable_asynccancel ok
|
@c LIBC_CANCEL_RESET -> __pthread_disable_asynccancel ok
|
||||||
@c lll_futex_wait ok
|
@c lll_futex_wait ok
|
||||||
@c ->start_routine ok -----
|
@c ->start_routine ok -----
|
||||||
@c call_tls_dtors @asulock @ascuheap @aculock @acsmem
|
@c call_tls_dtors @asulock @ascuheap @aculock @acsmem
|
||||||
|
@ -30,6 +30,7 @@ extra-libs-others := $(extra-libs)
|
|||||||
|
|
||||||
routines = \
|
routines = \
|
||||||
alloca_cutoff \
|
alloca_cutoff \
|
||||||
|
cancellation \
|
||||||
cleanup_compat \
|
cleanup_compat \
|
||||||
cleanup_defer_compat \
|
cleanup_defer_compat \
|
||||||
cleanup_routine \
|
cleanup_routine \
|
||||||
@ -39,7 +40,6 @@ routines = \
|
|||||||
elision-trylock \
|
elision-trylock \
|
||||||
elision-unlock \
|
elision-unlock \
|
||||||
futex-internal \
|
futex-internal \
|
||||||
libc-cancellation \
|
|
||||||
libc-cleanup \
|
libc-cleanup \
|
||||||
libc_multiple_threads \
|
libc_multiple_threads \
|
||||||
libc_pthread_init \
|
libc_pthread_init \
|
||||||
@ -157,7 +157,6 @@ shared-only-routines = forward
|
|||||||
static-only-routines = pthread_atfork
|
static-only-routines = pthread_atfork
|
||||||
|
|
||||||
libpthread-routines = \
|
libpthread-routines = \
|
||||||
cancellation \
|
|
||||||
cleanup \
|
cleanup \
|
||||||
cleanup_defer \
|
cleanup_defer \
|
||||||
events \
|
events \
|
||||||
@ -239,7 +238,6 @@ CFLAGS-pthread_setcanceltype.c += -fexceptions -fasynchronous-unwind-tables
|
|||||||
# These are internal functions which similar functionality as setcancelstate
|
# These are internal functions which similar functionality as setcancelstate
|
||||||
# and setcanceltype.
|
# and setcanceltype.
|
||||||
CFLAGS-cancellation.c += -fasynchronous-unwind-tables
|
CFLAGS-cancellation.c += -fasynchronous-unwind-tables
|
||||||
CFLAGS-libc-cancellation.c += -fasynchronous-unwind-tables
|
|
||||||
|
|
||||||
# Calling pthread_exit() must cause the registered cancel handlers to
|
# Calling pthread_exit() must cause the registered cancel handlers to
|
||||||
# be executed. Therefore exceptions have to be thrown through this
|
# be executed. Therefore exceptions have to be thrown through this
|
||||||
|
@ -281,6 +281,8 @@ libc {
|
|||||||
__pthread_cleanup_push;
|
__pthread_cleanup_push;
|
||||||
__pthread_cleanup_upto;
|
__pthread_cleanup_upto;
|
||||||
__pthread_current_priority;
|
__pthread_current_priority;
|
||||||
|
__pthread_disable_asynccancel;
|
||||||
|
__pthread_enable_asynccancel;
|
||||||
__pthread_force_elision;
|
__pthread_force_elision;
|
||||||
__pthread_getattr_default_np;
|
__pthread_getattr_default_np;
|
||||||
__pthread_keys;
|
__pthread_keys;
|
||||||
|
@ -28,7 +28,6 @@
|
|||||||
AS-safe, with the exception of the actual cancellation, because they
|
AS-safe, with the exception of the actual cancellation, because they
|
||||||
are called by wrappers around AS-safe functions like write().*/
|
are called by wrappers around AS-safe functions like write().*/
|
||||||
int
|
int
|
||||||
attribute_hidden
|
|
||||||
__pthread_enable_asynccancel (void)
|
__pthread_enable_asynccancel (void)
|
||||||
{
|
{
|
||||||
struct pthread *self = THREAD_SELF;
|
struct pthread *self = THREAD_SELF;
|
||||||
@ -60,11 +59,11 @@ __pthread_enable_asynccancel (void)
|
|||||||
|
|
||||||
return oldval;
|
return oldval;
|
||||||
}
|
}
|
||||||
|
libc_hidden_def (__pthread_enable_asynccancel)
|
||||||
|
|
||||||
/* See the comment for __pthread_enable_asynccancel regarding
|
/* See the comment for __pthread_enable_asynccancel regarding
|
||||||
the AS-safety of this function. */
|
the AS-safety of this function. */
|
||||||
void
|
void
|
||||||
attribute_hidden
|
|
||||||
__pthread_disable_asynccancel (int oldtype)
|
__pthread_disable_asynccancel (int oldtype)
|
||||||
{
|
{
|
||||||
/* If asynchronous cancellation was enabled before we do not have
|
/* If asynchronous cancellation was enabled before we do not have
|
||||||
@ -102,3 +101,4 @@ __pthread_disable_asynccancel (int oldtype)
|
|||||||
newval = THREAD_GETMEM (self, cancelhandling);
|
newval = THREAD_GETMEM (self, cancelhandling);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
libc_hidden_def (__pthread_disable_asynccancel)
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
/* Copyright (C) 2002-2021 Free Software Foundation, Inc.
|
|
||||||
This file is part of the GNU C Library.
|
|
||||||
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
|
|
||||||
|
|
||||||
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, see
|
|
||||||
<https://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#include "pthreadP.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define __pthread_enable_asynccancel __libc_enable_asynccancel
|
|
||||||
#define __pthread_disable_asynccancel __libc_disable_asynccancel
|
|
||||||
#include <nptl/cancellation.c>
|
|
@ -567,8 +567,6 @@ libc_hidden_proto (__pthread_exit)
|
|||||||
extern int __pthread_join (pthread_t threadid, void **thread_return);
|
extern int __pthread_join (pthread_t threadid, void **thread_return);
|
||||||
extern int __pthread_setcanceltype (int type, int *oldtype);
|
extern int __pthread_setcanceltype (int type, int *oldtype);
|
||||||
libc_hidden_proto (__pthread_setcanceltype)
|
libc_hidden_proto (__pthread_setcanceltype)
|
||||||
extern int __pthread_enable_asynccancel (void) attribute_hidden;
|
|
||||||
extern void __pthread_disable_asynccancel (int oldtype) attribute_hidden;
|
|
||||||
extern void __pthread_testcancel (void);
|
extern void __pthread_testcancel (void);
|
||||||
libc_hidden_proto (__pthread_testcancel)
|
libc_hidden_proto (__pthread_testcancel)
|
||||||
extern int __pthread_clockjoin_ex (pthread_t, void **, clockid_t,
|
extern int __pthread_clockjoin_ex (pthread_t, void **, clockid_t,
|
||||||
|
@ -353,7 +353,7 @@ START_THREAD_DEFN
|
|||||||
have ownership (see CONCURRENCY NOTES above). */
|
have ownership (see CONCURRENCY NOTES above). */
|
||||||
if (__glibc_unlikely (pd->stopped_start))
|
if (__glibc_unlikely (pd->stopped_start))
|
||||||
{
|
{
|
||||||
int oldtype = CANCEL_ASYNC ();
|
int oldtype = LIBC_CANCEL_ASYNC ();
|
||||||
|
|
||||||
/* Get the lock the parent locked to force synchronization. */
|
/* Get the lock the parent locked to force synchronization. */
|
||||||
lll_lock (pd->lock, LLL_PRIVATE);
|
lll_lock (pd->lock, LLL_PRIVATE);
|
||||||
@ -363,7 +363,7 @@ START_THREAD_DEFN
|
|||||||
/* And give it up right away. */
|
/* And give it up right away. */
|
||||||
lll_unlock (pd->lock, LLL_PRIVATE);
|
lll_unlock (pd->lock, LLL_PRIVATE);
|
||||||
|
|
||||||
CANCEL_RESET (oldtype);
|
LIBC_CANCEL_RESET (oldtype);
|
||||||
}
|
}
|
||||||
|
|
||||||
LIBC_PROBE (pthread_start, 3, (pthread_t) pd, pd->start_routine, pd->arg);
|
LIBC_PROBE (pthread_start, 3, (pthread_t) pd, pd->start_routine, pd->arg);
|
||||||
|
@ -59,7 +59,6 @@ include ../Rules
|
|||||||
CFLAGS-aio_suspend.c += -fexceptions
|
CFLAGS-aio_suspend.c += -fexceptions
|
||||||
CFLAGS-mq_timedreceive.c += -fexceptions -fasynchronous-unwind-tables
|
CFLAGS-mq_timedreceive.c += -fexceptions -fasynchronous-unwind-tables
|
||||||
CFLAGS-mq_timedsend.c += -fexceptions -fasynchronous-unwind-tables
|
CFLAGS-mq_timedsend.c += -fexceptions -fasynchronous-unwind-tables
|
||||||
CFLAGS-librt-cancellation.c += -fasynchronous-unwind-tables
|
|
||||||
|
|
||||||
LDFLAGS-rt.so = -Wl,--enable-new-dtags,-z,nodelete
|
LDFLAGS-rt.so = -Wl,--enable-new-dtags,-z,nodelete
|
||||||
|
|
||||||
|
@ -21,8 +21,7 @@ libpthread-sysdep_routines += errno-loc
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(subdir),rt)
|
ifeq ($(subdir),rt)
|
||||||
librt-sysdep_routines += timer_routines librt-cancellation
|
librt-sysdep_routines += timer_routines
|
||||||
CFLAGS-librt-cancellation.c += -fexceptions -fasynchronous-unwind-tables
|
|
||||||
|
|
||||||
tests += tst-mqueue8x
|
tests += tst-mqueue8x
|
||||||
CFLAGS-tst-mqueue8x.c += -fexceptions
|
CFLAGS-tst-mqueue8x.c += -fexceptions
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
/* Copyright (C) 2002-2021 Free Software Foundation, Inc.
|
|
||||||
This file is part of the GNU C Library.
|
|
||||||
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
|
|
||||||
|
|
||||||
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, see
|
|
||||||
<https://www.gnu.org/licenses/>. */
|
|
||||||
|
|
||||||
#include <nptl/pthreadP.h>
|
|
||||||
|
|
||||||
|
|
||||||
#define __pthread_enable_asynccancel __librt_enable_asynccancel
|
|
||||||
#define __pthread_disable_asynccancel __librt_disable_asynccancel
|
|
||||||
#include <nptl/cancellation.c>
|
|
@ -121,18 +121,18 @@
|
|||||||
/* Like lll_futex_wait, but acting as a cancellable entrypoint. */
|
/* Like lll_futex_wait, but acting as a cancellable entrypoint. */
|
||||||
# define lll_futex_wait_cancel(futexp, val, private) \
|
# define lll_futex_wait_cancel(futexp, val, private) \
|
||||||
({ \
|
({ \
|
||||||
int __oldtype = CANCEL_ASYNC (); \
|
int __oldtype = LIBC_CANCEL_ASYNC (); \
|
||||||
long int __err = lll_futex_wait (futexp, val, LLL_SHARED); \
|
long int __err = lll_futex_wait (futexp, val, LLL_SHARED); \
|
||||||
CANCEL_RESET (__oldtype); \
|
LIBC_CANCEL_RESET (__oldtype); \
|
||||||
__err; \
|
__err; \
|
||||||
})
|
})
|
||||||
|
|
||||||
/* Like lll_futex_timed_wait, but acting as a cancellable entrypoint. */
|
/* Like lll_futex_timed_wait, but acting as a cancellable entrypoint. */
|
||||||
# define lll_futex_timed_wait_cancel(futexp, val, timeout, private) \
|
# define lll_futex_timed_wait_cancel(futexp, val, timeout, private) \
|
||||||
({ \
|
({ \
|
||||||
int __oldtype = CANCEL_ASYNC (); \
|
int __oldtype = LIBC_CANCEL_ASYNC (); \
|
||||||
long int __err = lll_futex_timed_wait (futexp, val, timeout, private); \
|
long int __err = lll_futex_timed_wait (futexp, val, timeout, private); \
|
||||||
CANCEL_RESET (__oldtype); \
|
LIBC_CANCEL_RESET (__oldtype); \
|
||||||
__err; \
|
__err; \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -89,11 +89,6 @@
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
#if IS_IN (libc)
|
|
||||||
# define __pthread_enable_asynccancel __libc_enable_asynccancel
|
|
||||||
# define __pthread_disable_asynccancel __libc_disable_asynccancel
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SOCKETCALL_CANCEL(name, args...) \
|
#define SOCKETCALL_CANCEL(name, args...) \
|
||||||
({ \
|
({ \
|
||||||
int oldtype = LIBC_CANCEL_ASYNC (); \
|
int oldtype = LIBC_CANCEL_ASYNC (); \
|
||||||
|
@ -24,44 +24,14 @@
|
|||||||
#include <tls.h>
|
#include <tls.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
/* The two functions are in libc.so and not exported. */
|
|
||||||
extern int __libc_enable_asynccancel (void) attribute_hidden;
|
|
||||||
extern void __libc_disable_asynccancel (int oldtype) attribute_hidden;
|
|
||||||
|
|
||||||
/* The two functions are in librt.so and not exported. */
|
|
||||||
extern int __librt_enable_asynccancel (void) attribute_hidden;
|
|
||||||
extern void __librt_disable_asynccancel (int oldtype) attribute_hidden;
|
|
||||||
|
|
||||||
/* The two functions are in libpthread.so and not exported. */
|
|
||||||
extern int __pthread_enable_asynccancel (void) attribute_hidden;
|
|
||||||
extern void __pthread_disable_asynccancel (int oldtype) attribute_hidden;
|
|
||||||
|
|
||||||
/* Set cancellation mode to asynchronous. */
|
/* Set cancellation mode to asynchronous. */
|
||||||
#define CANCEL_ASYNC() \
|
extern int __pthread_enable_asynccancel (void);
|
||||||
__pthread_enable_asynccancel ()
|
libc_hidden_proto (__pthread_enable_asynccancel)
|
||||||
|
#define LIBC_CANCEL_ASYNC() __pthread_enable_asynccancel ()
|
||||||
|
|
||||||
/* Reset to previous cancellation mode. */
|
/* Reset to previous cancellation mode. */
|
||||||
#define CANCEL_RESET(oldtype) \
|
extern void __pthread_disable_asynccancel (int oldtype);
|
||||||
__pthread_disable_asynccancel (oldtype)
|
libc_hidden_proto (__pthread_disable_asynccancel)
|
||||||
|
#define LIBC_CANCEL_RESET(oldtype) __pthread_disable_asynccancel (oldtype)
|
||||||
#if IS_IN (libc)
|
|
||||||
/* Same as CANCEL_ASYNC, but for use in libc.so. */
|
|
||||||
# define LIBC_CANCEL_ASYNC() \
|
|
||||||
__libc_enable_asynccancel ()
|
|
||||||
/* Same as CANCEL_RESET, but for use in libc.so. */
|
|
||||||
# define LIBC_CANCEL_RESET(oldtype) \
|
|
||||||
__libc_disable_asynccancel (oldtype)
|
|
||||||
#elif IS_IN (libpthread)
|
|
||||||
# define LIBC_CANCEL_ASYNC() CANCEL_ASYNC ()
|
|
||||||
# define LIBC_CANCEL_RESET(val) CANCEL_RESET (val)
|
|
||||||
#elif IS_IN (librt)
|
|
||||||
# define LIBC_CANCEL_ASYNC() \
|
|
||||||
__librt_enable_asynccancel ()
|
|
||||||
# define LIBC_CANCEL_RESET(val) \
|
|
||||||
__librt_disable_asynccancel (val)
|
|
||||||
#else
|
|
||||||
# define LIBC_CANCEL_ASYNC() 0 /* Just a dummy value. */
|
|
||||||
# define LIBC_CANCEL_RESET(val) ((void)(val)) /* Nothing, but evaluate it. */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user