1 /*
2 * pthread_setcanceltype.c
3 *
4 * Description:
5 * POSIX thread functions related to thread cancellation.
6 *
7 * --------------------------------------------------------------------------
8 *
9 * Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
10 * Copyright(C) 2008 Jason Schmidlapp
11 *
12 * Contact Email: jschmidlapp@users.sourceforge.net
13 *
14 *
15 * Based upon Pthreads-win32 - POSIX Threads Library for Win32
16 * Copyright(C) 1998 John E. Bossom
17 * Copyright(C) 1999,2005 Pthreads-win32 contributors
18 *
19 * Contact Email: rpj@callisto.canberra.edu.au
20 *
21 * The original list of contributors to the Pthreads-win32 project
22 * is contained in the file CONTRIBUTORS.ptw32 included with the
23 * source code distribution. The list can also be seen at the
24 * following World Wide Web location:
25 * http://sources.redhat.com/pthreads-win32/contributors.html
26 *
27 * This library is free software; you can redistribute it and/or
28 * modify it under the terms of the GNU Lesser General Public
29 * License as published by the Free Software Foundation; either
30 * version 2 of the License, or (at your option) any later version.
31 *
32 * This library is distributed in the hope that it will be useful,
33 * but WITHOUT ANY WARRANTY; without even the implied warranty of
34 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
35 * Lesser General Public License for more details.
36 *
37 * You should have received a copy of the GNU Lesser General Public
38 * License along with this library in the file COPYING.LIB;
39 * if not, write to the Free Software Foundation, Inc.,
40 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
41 */
42
43 #include "pthread.h"
44 #include "implement.h"
45
46
47 int
pthread_setcanceltype(int type,int * oldtype)48 pthread_setcanceltype (int type, int *oldtype)
49 /*
50 * ------------------------------------------------------
51 * DOCPUBLIC
52 * This function atomically sets the calling thread's
53 * cancelability type to 'type' and returns the previous
54 * cancelability type at the location referenced by
55 * 'oldtype'
56 *
57 * PARAMETERS
58 * type,
59 * oldtype
60 * PTHREAD_CANCEL_DEFERRED
61 * only deferred cancelation is allowed,
62 *
63 * PTHREAD_CANCEL_ASYNCHRONOUS
64 * Asynchronous cancellation is allowed
65 *
66 *
67 * DESCRIPTION
68 * This function atomically sets the calling thread's
69 * cancelability type to 'type' and returns the previous
70 * cancelability type at the location referenced by
71 * 'oldtype'
72 *
73 * NOTES:
74 * 1) Use with caution; most code is not safe for use
75 * with asynchronous cancelability.
76 *
77 * COMPATIBILITY ADDITIONS
78 * If 'oldtype' is NULL then the previous type is not returned
79 * but the function still succeeds. (Solaris)
80 *
81 * RESULTS
82 * 0 successfully set cancelability type,
83 * EINVAL 'type' is invalid
84 * EPERM Async cancellation is not supported.
85 *
86 * ------------------------------------------------------
87 */
88 {
89 int result = 0;
90 pthread_t self = pthread_self ();
91 pte_thread_t * sp = (pte_thread_t *) self;
92
93 #ifndef PTE_SUPPORT_ASYNC_CANCEL
94 if (type == PTHREAD_CANCEL_ASYNCHRONOUS)
95 {
96 /* Async cancellation is not supported at this time. See notes in
97 * pthread_cancel.
98 */
99 return EPERM;
100 }
101 #endif /* PTE_SUPPORT_ASYNC_CANCEL */
102
103 if (sp == NULL
104 || (type != PTHREAD_CANCEL_DEFERRED
105 && type != PTHREAD_CANCEL_ASYNCHRONOUS))
106 {
107 return EINVAL;
108 }
109
110 /*
111 * Lock for async-cancel safety.
112 */
113 (void) pthread_mutex_lock (&sp->cancelLock);
114
115 if (oldtype != NULL)
116 {
117 *oldtype = sp->cancelType;
118 }
119
120 sp->cancelType = type;
121
122 /*
123 * Check if there is a pending asynchronous cancel
124 */
125
126 if (sp->cancelState == PTHREAD_CANCEL_ENABLE
127 && (type == PTHREAD_CANCEL_ASYNCHRONOUS)
128 && (pte_osThreadCheckCancel(sp->threadId) == PTE_OS_INTERRUPTED) )
129 {
130 sp->state = PThreadStateCanceling;
131 sp->cancelState = PTHREAD_CANCEL_DISABLE;
132 (void) pthread_mutex_unlock (&sp->cancelLock);
133 pte_throw (PTE_EPS_CANCEL);
134
135 /* Never reached */
136 }
137
138 (void) pthread_mutex_unlock (&sp->cancelLock);
139
140 return (result);
141
142 } /* pthread_setcanceltype */
143