]> git.ipfire.org Git - thirdparty/glibc.git/blame - nptl/pthread_setcanceltype.c
Update copyright dates with scripts/update-copyrights
[thirdparty/glibc.git] / nptl / pthread_setcanceltype.c
CommitLineData
2b778ceb 1/* Copyright (C) 2002-2021 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 <errno.h>
20#include "pthreadP.h"
21#include <atomic.h>
22
23
24int
9d46370c 25__pthread_setcanceltype (int type, int *oldtype)
76a50749 26{
76a50749
UD
27 if (type < PTHREAD_CANCEL_DEFERRED || type > PTHREAD_CANCEL_ASYNCHRONOUS)
28 return EINVAL;
29
2f531bbb 30 volatile struct pthread *self = THREAD_SELF;
76a50749 31
b22d701b 32 int oldval = THREAD_GETMEM (self, cancelhandling);
76a50749
UD
33 while (1)
34 {
76a50749
UD
35 int newval = (type == PTHREAD_CANCEL_ASYNCHRONOUS
36 ? oldval | CANCELTYPE_BITMASK
37 : oldval & ~CANCELTYPE_BITMASK);
38
39 /* Store the old value. */
40 if (oldtype != NULL)
41 *oldtype = ((oldval & CANCELTYPE_BITMASK)
42 ? PTHREAD_CANCEL_ASYNCHRONOUS : PTHREAD_CANCEL_DEFERRED);
43
44 /* Avoid doing unnecessary work. The atomic operation can
3335502b 45 potentially be expensive if the memory has to be locked and
76a50749
UD
46 remote cache lines have to be invalidated. */
47 if (oldval == newval)
48 break;
49
50 /* Update the cancel handling word. This has to be done
51 atomically since other bits could be modified as well. */
b22d701b
UD
52 int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
53 oldval);
a1ffb40e 54 if (__glibc_likely (curval == oldval))
76a50749
UD
55 {
56 if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval))
57 {
58 THREAD_SETMEM (self, result, PTHREAD_CANCELED);
9ae0909b 59 __do_cancel ();
76a50749
UD
60 }
61
62 break;
63 }
b22d701b
UD
64
65 /* Prepare for the next round. */
66 oldval = curval;
76a50749
UD
67 }
68
69 return 0;
70}
09efc3ba 71strong_alias (__pthread_setcanceltype, pthread_setcanceltype)