From patchwork Fri Dec 4 18:09:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 41312 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 9CF923982414; Fri, 4 Dec 2020 18:10:03 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9CF923982414 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1607105403; bh=CxnTxVrXvyW5+OuuSoxLEOyuQVB7gKIhYymWq8s8Ez0=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=cvc4HNvq6iKf9iXp0WTJ8aAIEZSrVjw8mXhVjnTKAQszuAcWjSWblVR8WHZHmfZAa Ht6TS94EqMFLCM/NtoO6BryzEf+cwFah+QlGVNAXCDLpsw4jOYzSWu4h2GHTuKm3ei +wZfRYqrLRfNZPTAvjH6n3DFLoHV9sgDUv/Yu9YU= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-qt1-x841.google.com (mail-qt1-x841.google.com [IPv6:2607:f8b0:4864:20::841]) by sourceware.org (Postfix) with ESMTPS id B5B803982415 for ; Fri, 4 Dec 2020 18:09:58 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org B5B803982415 Received: by mail-qt1-x841.google.com with SMTP id p12so4567670qtp.7 for ; Fri, 04 Dec 2020 10:09:58 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=CxnTxVrXvyW5+OuuSoxLEOyuQVB7gKIhYymWq8s8Ez0=; b=JmPI3AjZijBKZX21BXC4jJKaLmJs+/WCnsLfycYdJqdfucEGJPxZYrn5ZIzAy5feMt 7ZbDayoMs11fT1syENusJzfQoVvsMP4PuST7/BPbiXN/pGNXt4zHsbi4RG/CFUEZJMMN vp1sCLxtFZ2DDzAclbbLz/pPLaUD4Y8ZugXR1CEFng+5lkAN5CP3/H7l6E1vTaOTUJld lCMqjQgrurxOgEycH4vqy9KBupf+df6D+ibYFo8/vHdwIyyYHVSZLe9o4ooEHCDox7Uu /RxFhwEqMnXOE399n0SpFQsGl9Oh94E/4V+XtPvf5lDl1mzhXDociSJq6tGLUROdNXAu 8d4Q== X-Gm-Message-State: AOAM531Ph0LSWLm7kL7yPpZFgeZCG+4+r6RpxJwoZOfHlBvVqsSKMwX6 OWVeCuFunJhSIySjqaGz9NtY7Bg/r7gDcw== X-Google-Smtp-Source: ABdhPJxbSD0axGGp+DCQcy8OLU+VkQKCs++A9NYCUdn6ssIBSRF/6UtH/aBjEch+O40ssAryNmTsPA== X-Received: by 2002:ac8:668c:: with SMTP id d12mr10588867qtp.352.1607105397918; Fri, 04 Dec 2020 10:09:57 -0800 (PST) Received: from localhost.localdomain ([177.194.48.209]) by smtp.googlemail.com with ESMTPSA id b33sm6179827qta.62.2020.12.04.10.09.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 04 Dec 2020 10:09:57 -0800 (PST) To: libc-alpha@sourceware.org Subject: [PATCH 5/6] nptl: Implement raise with pthread_kill Date: Fri, 4 Dec 2020 15:09:43 -0300 Message-Id: <20201204180944.3774769-5-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20201204180944.3774769-1-adhemerval.zanella@linaro.org> References: <20201204180944.3774769-1-adhemerval.zanella@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-13.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Reply-To: Adhemerval Zanella Cc: Florian Weimer Errors-To: libc-alpha-bounces@sourceware.org Sender: "Libc-alpha" The internal __pthread_kill_internal symbol has an extra argument that specified if all signal or just application ones should be blocked (raise can not be used with SIGCANCEL or SIGTIMER, so there it no need to block them). Checked on x86_64-linux-gnu. --- nptl/Makefile | 1 + nptl/Versions | 1 + nptl/pt-raise.c | 11 +----- nptl/pthreadP.h | 3 ++ nptl/pthread_kill.c | 28 +-------------- nptl/pthread_kill_internal.c | 56 ++++++++++++++++++++++++++++++ sysdeps/posix/raise.c | 10 ++++-- sysdeps/unix/sysv/linux/pt-raise.c | 20 ----------- sysdeps/unix/sysv/linux/raise.c | 52 --------------------------- 9 files changed, 71 insertions(+), 111 deletions(-) create mode 100644 nptl/pthread_kill_internal.c delete mode 100644 sysdeps/unix/sysv/linux/pt-raise.c delete mode 100644 sysdeps/unix/sysv/linux/raise.c diff --git a/nptl/Makefile b/nptl/Makefile index 3f6e77f63f..424b96656a 100644 --- a/nptl/Makefile +++ b/nptl/Makefile @@ -66,6 +66,7 @@ routines = \ pthread_getattr_np \ pthread_getschedparam \ pthread_kill \ + pthread_kill_internal \ pthread_self \ pthread_setschedparam \ pthread_sigmask \ diff --git a/nptl/Versions b/nptl/Versions index 7cfe39a91c..39578ef4e6 100644 --- a/nptl/Versions +++ b/nptl/Versions @@ -66,6 +66,7 @@ libc { __pthread_attr_copy; __pthread_getattr_default_np; __pthread_attr_setsigmask_internal; + __pthread_kill_internal; } } diff --git a/nptl/pt-raise.c b/nptl/pt-raise.c index 069b33a86e..286a9f686a 100644 --- a/nptl/pt-raise.c +++ b/nptl/pt-raise.c @@ -17,13 +17,4 @@ License along with the GNU C Library; if not, see . */ -#include -#include - - -int -raise (int sig) -{ - /* This is what POSIX says must happen. */ - return pthread_kill (pthread_self (), sig); -} +#include "raise.c" diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h index a7510f9f63..2f34ac1ab9 100644 --- a/nptl/pthreadP.h +++ b/nptl/pthreadP.h @@ -526,6 +526,9 @@ extern int __pthread_equal (pthread_t thread1, pthread_t thread2); extern int __pthread_detach (pthread_t th); extern int __pthread_cancel (pthread_t th); extern int __pthread_kill (pthread_t threadid, int signo); +extern int __pthread_kill_internal (pthread_t threadif, int signo, + bool block_all); +libc_hidden_proto (__pthread_kill_internal) extern void __pthread_exit (void *value) __attribute__ ((__noreturn__)); extern int __pthread_join (pthread_t threadid, void **thread_return); extern int __pthread_setcanceltype (int type, int *oldtype); diff --git a/nptl/pthread_kill.c b/nptl/pthread_kill.c index c547c5fe58..d114cbfca6 100644 --- a/nptl/pthread_kill.c +++ b/nptl/pthread_kill.c @@ -16,37 +16,11 @@ License along with the GNU C Library; if not, see . */ -#include #include 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; - - /* Force load of pd->tid into local variable or register. Otherwise - if a thread exits between ESRCH test and tgkill, we might return - EINVAL, because pd->tid would be cleared by the kernel. */ - struct pthread *pd = (struct pthread *) threadid; - pid_t tid = atomic_forced_read (pd->tid); - if (__glibc_unlikely (tid <= 0)) - /* Not a valid thread handle. */ - return ESRCH; - - sigset_t set; - __libc_signal_block_all (&set); - - /* We have a special syscall to do the work. */ - pid_t pid = __getpid (); - - int val = INTERNAL_SYSCALL_CALL (tgkill, pid, tid, signo); - val = (INTERNAL_SYSCALL_ERROR_P (val) ? INTERNAL_SYSCALL_ERRNO (val) : 0); - - __libc_signal_restore_set (&set); - - return val; + return __pthread_kill_internal (threadid, signo, true); } strong_alias (__pthread_kill, pthread_kill) diff --git a/nptl/pthread_kill_internal.c b/nptl/pthread_kill_internal.c new file mode 100644 index 0000000000..46a47650a1 --- /dev/null +++ b/nptl/pthread_kill_internal.c @@ -0,0 +1,56 @@ +/* Common implementation for raise/pthread_kill. Linux version. + Copyright (C) 2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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 + . */ + +#include +#include + +int +__pthread_kill_internal (pthread_t threadid, int signo, bool block_all) +{ + /* Disallow sending the signal we use for cancellation, timers, + for the setxid implementation. */ + if (__is_internal_signal (signo)) + return EINVAL; + + /* Force load of pd->tid into local variable or register. Otherwise + if a thread exits between ESRCH test and tgkill, we might return + EINVAL, because pd->tid would be cleared by the kernel. */ + struct pthread *pd = (struct pthread *) threadid; + pid_t tid = atomic_forced_read (pd->tid); + if (__glibc_unlikely (tid <= 0)) + /* Not a valid thread handle. */ + return ESRCH; + + sigset_t set; + if (block_all) + __libc_signal_block_all (&set); + else + __libc_signal_block_app (&set); + + /* We have a special syscall to do the work. */ + pid_t pid = __getpid (); + + int val = INTERNAL_SYSCALL_CALL (tgkill, pid, tid, signo); + val = (INTERNAL_SYSCALL_ERROR_P (val) ? INTERNAL_SYSCALL_ERRNO (val) : 0); + + __libc_signal_restore_set (&set); + + return val; +} +libc_hidden_def (__pthread_kill_internal) + diff --git a/sysdeps/posix/raise.c b/sysdeps/posix/raise.c index 32cb108f0b..8a3ea95b3e 100644 --- a/sysdeps/posix/raise.c +++ b/sysdeps/posix/raise.c @@ -16,13 +16,19 @@ . */ #include -#include +#include /* Raise the signal SIG. */ int raise (int sig) { - return __kill (__getpid (), sig); + int r = __pthread_kill_internal ((pthread_t) THREAD_SELF, sig, false); + if (r != 0) + { + __set_errno (r); + r = -1; + } + return r; } libc_hidden_def (raise) weak_alias (raise, gsignal) diff --git a/sysdeps/unix/sysv/linux/pt-raise.c b/sysdeps/unix/sysv/linux/pt-raise.c deleted file mode 100644 index 0c8246b0cc..0000000000 --- a/sysdeps/unix/sysv/linux/pt-raise.c +++ /dev/null @@ -1,20 +0,0 @@ -/* ISO C raise function for libpthread. - Copyright (C) 2002-2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 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 - . */ - -#include diff --git a/sysdeps/unix/sysv/linux/raise.c b/sysdeps/unix/sysv/linux/raise.c deleted file mode 100644 index 3b90ae1d55..0000000000 --- a/sysdeps/unix/sysv/linux/raise.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright (C) 2002-2020 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 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 - . */ - -#include -#include -#include -#include -#include -#include - -int -raise (int sig) -{ - /* rt_sigprocmask may fail if: - - 1. sigsetsize != sizeof (sigset_t) (EINVAL) - 2. a failure in copy from/to user space (EFAULT) - 3. an invalid 'how' operation (EINVAL) - - The first case is already handle in glibc syscall call by using the arch - defined _NSIG. Second case is handled by using a stack allocated mask. - The last one should be handled by the block/unblock functions. */ - - sigset_t set; - __libc_signal_block_app (&set); - - pid_t pid = INTERNAL_SYSCALL_CALL (getpid); - pid_t tid = INTERNAL_SYSCALL_CALL (gettid); - - int ret = INLINE_SYSCALL_CALL (tgkill, pid, tid, sig); - - __libc_signal_restore_set (&set); - - return ret; -} -libc_hidden_def (raise) -weak_alias (raise, gsignal)