xref: /relibc/pthreads-emb/pthread_setcanceltype.c (revision a12978ccca4c576f02971f5cfc2cbefe23e4daba)
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