source: rtems/cpukit/posix/src/cancel.c @ f4719d5a

4.104.114.84.95
Last change on this file since f4719d5a was f4719d5a, checked in by Joel Sherrill <joel.sherrill@…>, on 05/22/96 at 22:32:39

These files have been modified in the initial pass at getting the portion
of the POSIX API necessary to support the GNAT runtime to initially compile.
We now have verified that the specifications for the necessary routines
are correct per the POSIX standards we have.

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