1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20: #include <setjmp.h>
21: #include <stdlib.h>
22: #include "pthreadP.h"
23: #include <atomic.h>
24: #include <bits/libc-lock.h>
25:
26:
27: #ifndef NOT_IN_libc
28:
29:
30:
31:
32: int
33: attribute_hidden
34: __libc_enable_asynccancel (void)
35: {
36: struct pthread *self = THREAD_SELF;
37: int oldval = THREAD_GETMEM (self, cancelhandling);
38:
39: while (1)
40: {
41: int newval = oldval | CANCELTYPE_BITMASK;
42:
43: if (__builtin_expect ((oldval & CANCELED_BITMASK) != 0, 0))
44: {
45:
46:
47: if ((oldval & (EXITING_BITMASK | CANCELSTATE_BITMASK)) != 0)
48: break;
49:
50: int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling,
51: newval, oldval);
52: if (__builtin_expect (curval != oldval, 0))
53: {
54:
55: oldval = curval;
56: continue;
57: }
58:
59: THREAD_SETMEM (self, result, PTHREAD_CANCELED);
60:
61: __do_cancel ();
62:
63:
64: }
65:
66: int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
67: oldval);
68: if (__builtin_expect (curval == oldval, 1))
69: break;
70:
71:
72: oldval = curval;
73: }
74:
75: return oldval;
76: }
77:
78:
79: void
80: internal_function attribute_hidden
81: __libc_disable_asynccancel (int oldtype)
82: {
83:
84:
85: if (oldtype & CANCELTYPE_BITMASK)
86: return;
87:
88: struct pthread *self = THREAD_SELF;
89: int oldval = THREAD_GETMEM (self, cancelhandling);
90:
91: while (1)
92: {
93: int newval = oldval & ~CANCELTYPE_BITMASK;
94:
95: if (newval == oldval)
96: break;
97:
98: int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
99: oldval);
100: if (__builtin_expect (curval == oldval, 1))
101: break;
102:
103:
104: oldval = curval;
105: }
106: }
107:
108:
109: void
110: __libc_cleanup_routine (struct __pthread_cleanup_frame *f)
111: {
112: if (f->__do_it)
113: f->__cancel_routine (f->__cancel_arg);
114: }
115:
116: #endif