- add sources.
[platform/framework/web/crosswalk.git] / src / native_client_sdk / src / libraries / third_party / pthreads-win32 / signal.c
1 /*
2  * signal.c
3  *
4  * Description:
5  * Thread-aware signal functions.
6  *
7  * --------------------------------------------------------------------------
8  *
9  *      Pthreads-win32 - POSIX Threads Library for Win32
10  *      Copyright(C) 1998 John E. Bossom
11  *      Copyright(C) 1999,2005 Pthreads-win32 contributors
12  * 
13  *      Contact Email: rpj@callisto.canberra.edu.au
14  * 
15  *      The current list of contributors is contained
16  *      in the file CONTRIBUTORS included with the source
17  *      code distribution. The list can also be seen at the
18  *      following World Wide Web location:
19  *      http://sources.redhat.com/pthreads-win32/contributors.html
20  * 
21  *      This library is free software; you can redistribute it and/or
22  *      modify it under the terms of the GNU Lesser General Public
23  *      License as published by the Free Software Foundation; either
24  *      version 2 of the License, or (at your option) any later version.
25  * 
26  *      This library is distributed in the hope that it will be useful,
27  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
28  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
29  *      Lesser General Public License for more details.
30  * 
31  *      You should have received a copy of the GNU Lesser General Public
32  *      License along with this library in the file COPYING.LIB;
33  *      if not, write to the Free Software Foundation, Inc.,
34  *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
35  */
36
37 /*
38  * Possible future strategy for implementing pthread_kill()
39  * ========================================================
40  *
41  * Win32 does not implement signals.
42  * Signals are simply software interrupts.
43  * pthread_kill() asks the system to deliver a specified
44  * signal (interrupt) to a specified thread in the same
45  * process.
46  * Signals are always asynchronous (no deferred signals).
47  * Pthread-win32 has an async cancelation mechanism.
48  * A similar system can be written to deliver signals
49  * within the same process (on ix86 processors at least).
50  *
51  * Each thread maintains information about which
52  * signals it will respond to. Handler routines
53  * are set on a per-process basis - not per-thread.
54  * When signalled, a thread will check it's sigmask
55  * and, if the signal is not being ignored, call the
56  * handler routine associated with the signal. The
57  * thread must then (except for some signals) return to
58  * the point where it was interrupted.
59  *
60  * Ideally the system itself would check the target thread's
61  * mask before possibly needlessly bothering the thread
62  * itself. This could be done by pthread_kill(), that is,
63  * in the signaling thread since it has access to
64  * all pthread_t structures. It could also retrieve
65  * the handler routine address to minimise the target
66  * threads response overhead. This may also simplify
67  * serialisation of the access to the per-thread signal
68  * structures.
69  *
70  * pthread_kill() eventually calls a routine similar to
71  * ptw32_cancel_thread() which manipulates the target
72  * threads processor context to cause the thread to
73  * run the handler launcher routine. pthread_kill() must
74  * save the target threads current context so that the
75  * handler launcher routine can restore the context after
76  * the signal handler has returned. Some handlers will not
77  * return, eg. the default SIGKILL handler may simply
78  * call pthread_exit().
79  *
80  * The current context is saved in the target threads
81  * pthread_t structure.
82  */
83
84 #include "pthread.h"
85 #include "implement.h"
86
87 #if defined(HAVE_SIGSET_T)
88
89 static void
90 ptw32_signal_thread ()
91 {
92 }
93
94 static void
95 ptw32_signal_callhandler ()
96 {
97 }
98
99 int
100 pthread_sigmask (int how, sigset_t const *set, sigset_t * oset)
101 {
102   pthread_t thread = pthread_self ();
103
104   if (thread.p == NULL)
105     {
106       return ENOENT;
107     }
108
109   /* Validate the `how' argument. */
110   if (set != NULL)
111     {
112       switch (how)
113         {
114         case SIG_BLOCK:
115           break;
116         case SIG_UNBLOCK:
117           break;
118         case SIG_SETMASK:
119           break;
120         default:
121           /* Invalid `how' argument. */
122           return EINVAL;
123         }
124     }
125
126   /* Copy the old mask before modifying it. */
127   if (oset != NULL)
128     {
129       memcpy (oset, &(thread.p->sigmask), sizeof (sigset_t));
130     }
131
132   if (set != NULL)
133     {
134       unsigned int i;
135
136       /* FIXME: this code assumes that sigmask is an even multiple of
137          the size of a long integer. */
138
139       unsigned long *src = (unsigned long const *) set;
140       unsigned long *dest = (unsigned long *) &(thread.p->sigmask);
141
142       switch (how)
143         {
144         case SIG_BLOCK:
145           for (i = 0; i < (sizeof (sigset_t) / sizeof (unsigned long)); i++)
146             {
147               /* OR the bit field longword-wise. */
148               *dest++ |= *src++;
149             }
150           break;
151         case SIG_UNBLOCK:
152           for (i = 0; i < (sizeof (sigset_t) / sizeof (unsigned long)); i++)
153             {
154               /* XOR the bitfield longword-wise. */
155               *dest++ ^= *src++;
156             }
157         case SIG_SETMASK:
158           /* Replace the whole sigmask. */
159           memcpy (&(thread.p->sigmask), set, sizeof (sigset_t));
160           break;
161         }
162     }
163
164   return 0;
165 }
166
167 int
168 sigwait (const sigset_t * set, int *sig)
169 {
170   /* This routine is a cancellation point */
171   pthread_test_cancel();
172 }
173
174 int
175 sigaction (int signum, const struct sigaction *act, struct sigaction *oldact)
176 {
177 }
178
179 #endif /* HAVE_SIGSET_T */