]> git.ipfire.org Git - thirdparty/glibc.git/blame - nptl/cancellation.c
Prefer https to http for gnu.org and fsf.org URLs
[thirdparty/glibc.git] / nptl / cancellation.c
CommitLineData
04277e02 1/* Copyright (C) 2002-2019 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().
27 They do not need to check parameters etc. */
28int
29attribute_hidden
30__pthread_enable_asynccancel (void)
31{
32 struct pthread *self = THREAD_SELF;
b22d701b 33 int oldval = THREAD_GETMEM (self, cancelhandling);
bdb04f92
UD
34
35 while (1)
36 {
bdb04f92
UD
37 int newval = oldval | CANCELTYPE_BITMASK;
38
39 if (newval == oldval)
40 break;
41
b22d701b
UD
42 int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
43 oldval);
a1ffb40e 44 if (__glibc_likely (curval == oldval))
bdb04f92
UD
45 {
46 if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval))
47 {
48 THREAD_SETMEM (self, result, PTHREAD_CANCELED);
9ae0909b 49 __do_cancel ();
bdb04f92
UD
50 }
51
52 break;
53 }
b22d701b
UD
54
55 /* Prepare the next round. */
56 oldval = curval;
bdb04f92
UD
57 }
58
59 return oldval;
60}
61
62
63void
83b09837 64attribute_hidden
bdb04f92
UD
65__pthread_disable_asynccancel (int oldtype)
66{
67 /* If asynchronous cancellation was enabled before we do not have
68 anything to do. */
69 if (oldtype & CANCELTYPE_BITMASK)
70 return;
71
72 struct pthread *self = THREAD_SELF;
1a7f254b 73 int newval;
d5c157a9 74
b22d701b 75 int oldval = THREAD_GETMEM (self, cancelhandling);
bdb04f92
UD
76
77 while (1)
78 {
1a7f254b 79 newval = oldval & ~CANCELTYPE_BITMASK;
bdb04f92 80
b22d701b
UD
81 int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
82 oldval);
a1ffb40e 83 if (__glibc_likely (curval == oldval))
bdb04f92 84 break;
b22d701b
UD
85
86 /* Prepare the next round. */
87 oldval = curval;
bdb04f92 88 }
1a7f254b
UD
89
90 /* We cannot return when we are being canceled. Upon return the
91 thread might be things which would have to be undone. The
92 following loop should loop until the cancellation signal is
93 delivered. */
9437b427
UD
94 while (__builtin_expect ((newval & (CANCELING_BITMASK | CANCELED_BITMASK))
95 == CANCELING_BITMASK, 0))
1a7f254b 96 {
a2f0363f
TR
97 futex_wait_simple ((unsigned int *) &self->cancelhandling, newval,
98 FUTEX_PRIVATE);
1a7f254b
UD
99 newval = THREAD_GETMEM (self, cancelhandling);
100 }
bdb04f92 101}