source: rtems/c/src/exec/posix/src/cancel.c @ c62d36f

4.104.114.84.95
Last change on this file since c62d36f was 5e9b32b, checked in by Joel Sherrill <joel.sherrill@…>, on 09/26/95 at 19:27:15

posix support initially added

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