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