mirror of
https://sourceware.org/git/glibc.git
synced 2025-08-08 17:42:12 +03:00
nptl: Use pthread_kill on pthread_cancel
It consolidates the tgkill call and it is the first step of making
pthread_cancel async-signal-safe. It also fix a possible issue
where the 'struct pthread' tid is not read atomically, which might
send an invalid cancellation signal (similar to what
db988e50a8
fixed for pthread_join).
Checked on x86_64-linux-gnu and aarch64-linux-gnu.
This commit is contained in:
@@ -515,6 +515,8 @@ libc_hidden_proto (__pthread_detach)
|
|||||||
extern int __pthread_kill (pthread_t threadid, int signo);
|
extern int __pthread_kill (pthread_t threadid, int signo);
|
||||||
libc_hidden_proto (__pthread_kill)
|
libc_hidden_proto (__pthread_kill)
|
||||||
extern int __pthread_cancel (pthread_t th);
|
extern int __pthread_cancel (pthread_t th);
|
||||||
|
extern int __pthread_kill_internal (pthread_t threadid, int signo)
|
||||||
|
attribute_hidden;
|
||||||
extern void __pthread_exit (void *value) __attribute__ ((__noreturn__));
|
extern void __pthread_exit (void *value) __attribute__ ((__noreturn__));
|
||||||
libc_hidden_proto (__pthread_exit)
|
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);
|
||||||
|
@@ -110,11 +110,7 @@ __pthread_cancel (pthread_t th)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pid_t pid = __getpid ();
|
return __pthread_kill_internal (th, SIGCANCEL);
|
||||||
int val = INTERNAL_SYSCALL_CALL (tgkill, pid, pd->tid, SIGCANCEL);
|
|
||||||
return INTERNAL_SYSCALL_ERROR_P (val)
|
|
||||||
? INTERNAL_SYSCALL_ERRNO (val)
|
|
||||||
: 0;
|
|
||||||
}
|
}
|
||||||
versioned_symbol (libc, __pthread_cancel, pthread_cancel, GLIBC_2_34);
|
versioned_symbol (libc, __pthread_cancel, pthread_cancel, GLIBC_2_34);
|
||||||
|
|
||||||
|
@@ -21,13 +21,8 @@
|
|||||||
#include <shlib-compat.h>
|
#include <shlib-compat.h>
|
||||||
|
|
||||||
int
|
int
|
||||||
__pthread_kill (pthread_t threadid, int signo)
|
__pthread_kill_internal (pthread_t threadid, int signo)
|
||||||
{
|
{
|
||||||
/* Disallow sending the signal we use for cancellation, timers,
|
|
||||||
for the setxid implementation. */
|
|
||||||
if (__is_internal_signal (signo))
|
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
pid_t tid;
|
pid_t tid;
|
||||||
struct pthread *pd = (struct pthread *) threadid;
|
struct pthread *pd = (struct pthread *) threadid;
|
||||||
|
|
||||||
@@ -55,6 +50,17 @@ __pthread_kill (pthread_t threadid, int signo)
|
|||||||
|
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
__pthread_kill (pthread_t threadid, int signo)
|
||||||
|
{
|
||||||
|
/* Disallow sending the signal we use for cancellation, timers,
|
||||||
|
for the setxid implementation. */
|
||||||
|
if (__is_internal_signal (signo))
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
return __pthread_kill_internal (threadid, signo);
|
||||||
|
}
|
||||||
/* Some architectures (for instance arm) might pull raise through libgcc, so
|
/* Some architectures (for instance arm) might pull raise through libgcc, so
|
||||||
avoid the symbol version if it ends up being used on ld.so. */
|
avoid the symbol version if it ends up being used on ld.so. */
|
||||||
#if !IS_IN(rtld)
|
#if !IS_IN(rtld)
|
||||||
|
Reference in New Issue
Block a user