1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20: #include "pthreadP.h"
21:
22:
23: void
24: _pthread_cleanup_push_defer (buffer, routine, arg)
25: struct _pthread_cleanup_buffer *buffer;
26: void (*routine) (void *);
27: void *arg;
28: {
29: struct pthread *self = THREAD_SELF;
30:
31: buffer->__routine = routine;
32: buffer->__arg = arg;
33: buffer->__prev = 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: buffer->__canceltype = (cancelhandling & CANCELTYPE_BITMASK
54: ? PTHREAD_CANCEL_ASYNCHRONOUS
55: : PTHREAD_CANCEL_DEFERRED);
56:
57: THREAD_SETMEM (self, cleanup, buffer);
58: }
59: strong_alias (_pthread_cleanup_push_defer, __pthread_cleanup_push_defer)
60:
61:
62: void
63: _pthread_cleanup_pop_restore (buffer, execute)
64: struct _pthread_cleanup_buffer *buffer;
65: int execute;
66: {
67: struct pthread *self = THREAD_SELF;
68:
69: THREAD_SETMEM (self, cleanup, buffer->__prev);
70:
71: int cancelhandling;
72: if (__builtin_expect (buffer->__canceltype != PTHREAD_CANCEL_DEFERRED, 0)
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:
93:
94:
95: if (execute)
96: buffer->__routine (buffer->__arg);
97: }
98: strong_alias (_pthread_cleanup_pop_restore, __pthread_cleanup_pop_restore)