source: rtems/cpukit/posix/src/cancel.c @ 3afecf8

4.104.114.84.95
Last change on this file since 3afecf8 was 3afecf8, checked in by Joel Sherrill <joel.sherrill@…>, on 04/15/99 at 18:56:42

Now compiles and is included in normal build even though it is untested.

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