]> git.ipfire.org Git - thirdparty/glibc.git/blame - nptl/cancellation.c
INSTALL, install.texi: minor updates, regenerate
[thirdparty/glibc.git] / nptl / cancellation.c
CommitLineData
dff8da6b 1/* Copyright (C) 2002-2024 Free Software Foundation, Inc.
76a50749 2 This file is part of the GNU C Library.
76a50749
UD
3
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
59ba27a6 15 License along with the GNU C Library; if not, see
5a82c748 16 <https://www.gnu.org/licenses/>. */
76a50749
UD
17
18#include <setjmp.h>
19#include <stdlib.h>
20#include "pthreadP.h"
a2f0363f 21#include <futex-internal.h>
76a50749
UD
22
23
bdb04f92
UD
24/* The next two functions are similar to pthread_setcanceltype() but
25 more specialized for the use in the cancelable functions like write().
676b2f20
CD
26 They do not need to check parameters etc. These functions must be
27 AS-safe, with the exception of the actual cancellation, because they
28 are called by wrappers around AS-safe functions like write().*/
bdb04f92 29int
bdb04f92
UD
30__pthread_enable_asynccancel (void)
31{
32 struct pthread *self = THREAD_SELF;
40465600 33 int oldval = atomic_load_relaxed (&self->cancelhandling);
bdb04f92 34
40465600
AZ
35 while (1)
36 {
37 int newval = oldval | CANCELTYPE_BITMASK;
bdb04f92 38
40465600
AZ
39 if (newval == oldval)
40 break;
b22d701b 41
40465600
AZ
42 if (atomic_compare_exchange_weak_acquire (&self->cancelhandling,
43 &oldval, newval))
44 {
45 if (cancel_enabled_and_canceled_and_async (newval))
46 {
47 self->result = PTHREAD_CANCELED;
48 __do_cancel ();
49 }
50
51 break;
52 }
bdb04f92
UD
53 }
54
55 return oldval;
56}
ce0b7961 57libc_hidden_def (__pthread_enable_asynccancel)
bdb04f92 58
676b2f20
CD
59/* See the comment for __pthread_enable_asynccancel regarding
60 the AS-safety of this function. */
bdb04f92 61void
bdb04f92
UD
62__pthread_disable_asynccancel (int oldtype)
63{
64 /* If asynchronous cancellation was enabled before we do not have
65 anything to do. */
40465600 66 if (oldtype & CANCELTYPE_BITMASK)
bdb04f92
UD
67 return;
68
69 struct pthread *self = THREAD_SELF;
40465600
AZ
70 int newval;
71 int oldval = atomic_load_relaxed (&self->cancelhandling);
72 do
73 {
74 newval = oldval & ~CANCELTYPE_BITMASK;
75 }
76 while (!atomic_compare_exchange_weak_acquire (&self->cancelhandling,
77 &oldval, newval));
78
79 /* We cannot return when we are being canceled. Upon return the
80 thread might be things which would have to be undone. The
81 following loop should loop until the cancellation signal is
82 delivered. */
83 while (__glibc_unlikely ((newval & (CANCELING_BITMASK | CANCELED_BITMASK))
84 == CANCELING_BITMASK))
85 {
86 futex_wait_simple ((unsigned int *) &self->cancelhandling, newval,
87 FUTEX_PRIVATE);
88 newval = atomic_load_relaxed (&self->cancelhandling);
89 }
bdb04f92 90}
ce0b7961 91libc_hidden_def (__pthread_disable_asynccancel)