1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20: #include <stdlib.h>
21: #include "pthreadP.h"
22:
23:
24: void
25: __cleanup_fct_attribute
26: __pthread_register_cancel_defer (__pthread_unwind_buf_t *buf)
27: {
28: struct pthread_unwind_buf *ibuf = (struct pthread_unwind_buf *) buf;
29: struct pthread *self = THREAD_SELF;
30:
31:
32: ibuf->priv.data.prev = THREAD_GETMEM (self, cleanup_jmp_buf);
33: ibuf->priv.data.cleanup = THREAD_GETMEM (self, cleanup);
34:
35: int cancelhandling = THREAD_GETMEM (self, cancelhandling);
36:
37:
38: if (__builtin_expect (cancelhandling & CANCELTYPE_BITMASK, 0))
39: while (1)
40: {
41: int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling,
42: cancelhandling
43: & ~CANCELTYPE_BITMASK,
44: cancelhandling);
45: if (__builtin_expect (curval == cancelhandling, 1))
46:
47: break;
48:
49:
50: cancelhandling = curval;
51: }
52:
53: ibuf->priv.data.canceltype = (cancelhandling & CANCELTYPE_BITMASK
54: ? PTHREAD_CANCEL_ASYNCHRONOUS
55: : PTHREAD_CANCEL_DEFERRED);
56:
57:
58: THREAD_SETMEM (self, cleanup_jmp_buf, (struct pthread_unwind_buf *) buf);
59: }
60:
61:
62: void
63: __cleanup_fct_attribute
64: __pthread_unregister_cancel_restore (__pthread_unwind_buf_t *buf)
65: {
66: struct pthread *self = THREAD_SELF;
67: struct pthread_unwind_buf *ibuf = (struct pthread_unwind_buf *) buf;
68:
69: THREAD_SETMEM (self, cleanup_jmp_buf, ibuf->priv.data.prev);
70:
71: int cancelhandling;
72: if (ibuf->priv.data.canceltype != PTHREAD_CANCEL_DEFERRED
73: && ((cancelhandling = THREAD_GETMEM (self, cancelhandling))
74: & CANCELTYPE_BITMASK) == 0)
75: {
76: while (1)
77: {
78: int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling,
79: cancelhandling
80: | CANCELTYPE_BITMASK,
81: cancelhandling);
82: if (__builtin_expect (curval == cancelhandling, 1))
83:
84: break;
85:
86:
87: cancelhandling = curval;
88: }
89:
90: CANCELLATION_P (self);
91: }
92: }