]> git.ipfire.org Git - thirdparty/glibc.git/blame - nptl/cancellation.c
Update copyright dates with scripts/update-copyrights.
[thirdparty/glibc.git] / nptl / cancellation.c
CommitLineData
b168057a 1/* Copyright (C) 2002-2015 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
PE
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
76a50749
UD
18
19#include <setjmp.h>
20#include <stdlib.h>
21#include "pthreadP.h"
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().
26 They do not need to check parameters etc. */
27int
28attribute_hidden
29__pthread_enable_asynccancel (void)
30{
31 struct pthread *self = THREAD_SELF;
b22d701b 32 int oldval = THREAD_GETMEM (self, cancelhandling);
bdb04f92
UD
33
34 while (1)
35 {
bdb04f92
UD
36 int newval = oldval | CANCELTYPE_BITMASK;
37
38 if (newval == oldval)
39 break;
40
b22d701b
UD
41 int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
42 oldval);
a1ffb40e 43 if (__glibc_likely (curval == oldval))
bdb04f92
UD
44 {
45 if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval))
46 {
47 THREAD_SETMEM (self, result, PTHREAD_CANCELED);
9ae0909b 48 __do_cancel ();
bdb04f92
UD
49 }
50
51 break;
52 }
b22d701b
UD
53
54 /* Prepare the next round. */
55 oldval = curval;
bdb04f92
UD
56 }
57
58 return oldval;
59}
60
61
62void
9ae0909b 63internal_function attribute_hidden
bdb04f92
UD
64__pthread_disable_asynccancel (int oldtype)
65{
66 /* If asynchronous cancellation was enabled before we do not have
67 anything to do. */
68 if (oldtype & CANCELTYPE_BITMASK)
69 return;
70
71 struct pthread *self = THREAD_SELF;
1a7f254b 72 int newval;
d5c157a9 73
b22d701b 74 int oldval = THREAD_GETMEM (self, cancelhandling);
bdb04f92
UD
75
76 while (1)
77 {
1a7f254b 78 newval = oldval & ~CANCELTYPE_BITMASK;
bdb04f92 79
b22d701b
UD
80 int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
81 oldval);
a1ffb40e 82 if (__glibc_likely (curval == oldval))
bdb04f92 83 break;
b22d701b
UD
84
85 /* Prepare the next round. */
86 oldval = curval;
bdb04f92 87 }
1a7f254b
UD
88
89 /* We cannot return when we are being canceled. Upon return the
90 thread might be things which would have to be undone. The
91 following loop should loop until the cancellation signal is
92 delivered. */
9437b427
UD
93 while (__builtin_expect ((newval & (CANCELING_BITMASK | CANCELED_BITMASK))
94 == CANCELING_BITMASK, 0))
1a7f254b
UD
95 {
96 lll_futex_wait (&self->cancelhandling, newval, LLL_PRIVATE);
97 newval = THREAD_GETMEM (self, cancelhandling);
98 }
bdb04f92 99}