source: rtems/cpukit/posix/src/cancel.c @ 67d224a

4.104.114.84.95
Last change on this file since 67d224a was eb5a7e07, checked in by Joel Sherrill <joel.sherrill@…>, on 10/06/95 at 20:48:38

fixed missing CVS IDs

  • Property mode set to 100644
File size: 5.4 KB
Line 
1/*  cancel.c
2 *
3 *  $Id$
4 */
5
6#include <pthread.h>
7#include <errno.h>
8#include <rtems/score/chain.h>
9#include <rtems/score/isr.h>
10#include <rtems/score/thread.h>
11#include <rtems/score/wkspace.h>
12#include <rtems/posix/cancel.h>
13#include <rtems/posix/pthread.h>
14#include <rtems/posix/threadsup.h>
15
16/*PAGE
17 *
18 *  POSIX_Thread_cancel_run
19 *
20 */
21
22void POSIX_Thread_cancel_run(
23  Thread_Control *the_thread
24)
25{
26  int                                old_cancel_state;
27  POSIX_Cancel_Handler_control      *handler;
28  Chain_Control                     *handler_stack;
29  POSIX_API_Thread_Support_Control  *thread_support;
30  ISR_Level                          level;
31 
32  thread_support = the_thread->API_Extensions[ THREAD_API_POSIX ];
33 
34  handler_stack = &thread_support->Cancellation_Handlers;
35 
36  old_cancel_state = thread_support->cancelability_state;
37
38  thread_support->cancelability_state = PTHREAD_CANCEL_DISABLE;
39
40  while ( !_Chain_Is_empty( handler_stack ) ) {
41    _ISR_Disable( level );
42      handler = (POSIX_Cancel_Handler_control *) _Chain_Tail( handler_stack );
43      _Chain_Extract_unprotected( &handler->Node );
44    _ISR_Enable( level );
45 
46    (*handler->routine)( handler->arg );
47
48    _Workspace_Free( handler );
49  }
50
51  thread_support->cancelation_requested = 0;
52
53  thread_support->cancelability_state = old_cancel_state;
54}
55
56/*PAGE
57 *
58 *  18.2.1 Canceling Execution of a Thread, P1003.1c/Draft 10, p. 181
59 */
60
61int pthread_cancel(
62  pthread_t  thread
63)
64{
65  Thread_Control                    *the_thread;
66  POSIX_API_Thread_Support_Control  *thread_support;
67  Objects_Locations                  location;
68
69  the_thread = _POSIX_Threads_Get( &thread, &location );
70  switch ( location ) {
71    case OBJECTS_ERROR:
72      return EINVAL;
73    case OBJECTS_REMOTE:
74      return POSIX_MP_NOT_IMPLEMENTED();
75    case OBJECTS_LOCAL:
76      thread_support = the_thread->API_Extensions[ THREAD_API_POSIX ];
77
78      thread_support->cancelation_requested = 1;
79
80      _Thread_Enable_dispatch();
81      return 0;
82  }
83 
84  return POSIX_BOTTOM_REACHED();
85}
86
87/*PAGE
88 *
89 *  18.2.2 Setting Cancelability State, P1003.1c/Draft 10, p. 183
90 */
91
92int pthread_setcancelstate(
93  int  state,
94  int *oldstate
95)
96{
97  POSIX_API_Thread_Support_Control  *thread_support;
98
99  if ( !oldstate )
100    return EINVAL;
101
102  if ( state != PTHREAD_CANCEL_ENABLE && state != PTHREAD_CANCEL_DISABLE )
103    return EINVAL;
104
105  thread_support = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
106 
107  *oldstate = thread_support->cancelability_state;
108  thread_support->cancelability_state = state;
109 
110  if ( thread_support->cancelability_state == PTHREAD_CANCEL_ENABLE &&
111       thread_support->cancelability_type == PTHREAD_CANCEL_ASYNCHRONOUS &&
112       thread_support->cancelation_requested )
113    POSIX_Thread_cancel_run( _Thread_Executing );
114 
115  return 0;
116}
117
118/*PAGE
119 *
120 *  18.2.2 Setting Cancelability State, P1003.1c/Draft 10, p. 183
121 */
122
123int pthread_setcanceltype(
124  int  type,
125  int *oldtype
126)
127{
128  POSIX_API_Thread_Support_Control  *thread_support;
129 
130  if ( !oldtype )
131    return EINVAL;
132 
133  if ( type != PTHREAD_CANCEL_DEFERRED && type != PTHREAD_CANCEL_ASYNCHRONOUS )
134    return EINVAL;
135 
136  thread_support = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
137
138  *oldtype = thread_support->cancelability_type;
139  thread_support->cancelability_type = type;
140
141  if ( thread_support->cancelability_state == PTHREAD_CANCEL_ENABLE &&
142       thread_support->cancelability_type == PTHREAD_CANCEL_ASYNCHRONOUS &&
143       thread_support->cancelation_requested )
144    POSIX_Thread_cancel_run( _Thread_Executing );
145
146  return 0;
147}
148
149/*PAGE
150 *
151 *  18.2.2 Setting Cancelability State, P1003.1c/Draft 10, p. 183
152 */
153
154void pthread_testcancel( void )
155{
156  POSIX_API_Thread_Support_Control  *thread_support;
157
158  thread_support = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
159 
160  if ( thread_support->cancelability_state == PTHREAD_CANCEL_ENABLE &&
161       thread_support->cancelation_requested )
162    POSIX_Thread_cancel_run( _Thread_Executing );
163}
164
165/*PAGE
166 *
167 *  18.2.3.1 Establishing Cancellation Handlers, P1003.1c/Draft 10, p. 184
168 */
169
170void pthread_cleanup_push(
171  void   (*routine)( void * ),
172  void    *arg
173)
174{
175  POSIX_Cancel_Handler_control      *handler;
176  Chain_Control                     *handler_stack;
177  POSIX_API_Thread_Support_Control  *thread_support;
178 
179  if ( !routine )
180    return;          /* XXX what to do really? */
181
182  handler = _Workspace_Allocate( sizeof( POSIX_Cancel_Handler_control ) );
183
184  if ( !handler )
185    return;          /* XXX what to do really? */
186
187  thread_support = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
188
189  handler_stack = &thread_support->Cancellation_Handlers;
190
191  handler->routine = routine;
192  handler->arg = arg;
193
194  _Chain_Append( handler_stack, &handler->Node );
195}
196
197/*PAGE
198 *
199 *  18.2.3.1 Establishing Cancellation Handlers, P1003.1c/Draft 10, p. 184
200 */
201
202void pthread_cleanup_pop(
203  int    execute
204)
205{
206  POSIX_Cancel_Handler_control      *handler;
207  Chain_Control                     *handler_stack;
208  POSIX_API_Thread_Support_Control  *thread_support;
209  ISR_Level                          level;
210 
211  thread_support = _Thread_Executing->API_Extensions[ THREAD_API_POSIX ];
212 
213  handler_stack = &thread_support->Cancellation_Handlers;
214
215  if ( _Chain_Is_empty( handler_stack ) )
216    return;
217 
218  _ISR_Disable( level );
219    handler = (POSIX_Cancel_Handler_control *) _Chain_Tail( handler_stack );
220    _Chain_Extract_unprotected( &handler->Node );
221  _ISR_Enable( level );
222
223  if ( execute )
224    (*handler->routine)( handler->arg );
225 
226  _Workspace_Free( handler );
227}
Note: See TracBrowser for help on using the repository browser.