• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * File: cancel2.c
3  *
4  *
5  * --------------------------------------------------------------------------
6  *
7  *      Pthreads-win32 - POSIX Threads Library for Win32
8  *      Copyright(C) 1998 John E. Bossom
9  *      Copyright(C) 1999,2005 Pthreads-win32 contributors
10  *
11  *      Contact Email: rpj@callisto.canberra.edu.au
12  *
13  *      The current list of contributors is contained
14  *      in the file CONTRIBUTORS included with the source
15  *      code distribution. The list can also be seen at the
16  *      following World Wide Web location:
17  *      http://sources.redhat.com/pthreads-win32/contributors.html
18  *
19  *      This library is free software; you can redistribute it and/or
20  *      modify it under the terms of the GNU Lesser General Public
21  *      License as published by the Free Software Foundation; either
22  *      version 2 of the License, or (at your option) any later version.
23  *
24  *      This library is distributed in the hope that it will be useful,
25  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
26  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
27  *      Lesser General Public License for more details.
28  *
29  *      You should have received a copy of the GNU Lesser General Public
30  *      License along with this library in the file COPYING.LIB;
31  *      if not, write to the Free Software Foundation, Inc.,
32  *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
33  *
34  * --------------------------------------------------------------------------
35  *
36  * Test Synopsis: Test SEH or C++ cancel exception handling within
37  * application exception blocks.
38  *
39  * Test Method (Validation or Falsification):
40  * -
41  *
42  * Requirements Tested:
43  * -
44  *
45  * Features Tested:
46  * -
47  *
48  * Cases Tested:
49  * -
50  *
51  * Description:
52  * -
53  *
54  * Environment:
55  * -
56  *
57  * Input:
58  * - None.
59  *
60  * Output:
61  * - File name, Line number, and failed expression on failure.
62  * - No output on success.
63  *
64  * Assumptions:
65  * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
66  *   pthread_testcancel, pthread_cancel, pthread_join
67  *
68  * Pass Criteria:
69  * - Process returns zero exit status.
70  *
71  * Fail Criteria:
72  * - Process returns non-zero exit status.
73  */
74 
75 #if defined(_MSC_VER) || defined(__cplusplus)
76 
77 #include "test.h"
78 
79 /*
80  * Create NUMTHREADS threads in addition to the Main thread.
81  */
82 enum {
83   NUMTHREADS = 1
84 };
85 
86 typedef struct bag_t_ bag_t;
87 struct bag_t_ {
88   int threadnum;
89   int started;
90   /* Add more per-thread state variables here */
91 };
92 
93 static bag_t threadbag[NUMTHREADS + 1];
94 
95 static pthread_mutex_t waitLock = PTHREAD_MUTEX_INITIALIZER;
96 
97 void *
mythread(void * arg)98 mythread(void * arg)
99 {
100   intptr_t result = 0;
101   bag_t * bag = (bag_t *) arg;
102 
103   assert(bag == &threadbag[bag->threadnum]);
104   assert(bag->started == 0);
105   bag->started = 1;
106 
107   /* Set to known state and type */
108 
109   assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0);
110 
111   switch (bag->threadnum % 2)
112     {
113     case 0:
114       assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0);
115       result = 0;
116       break;
117     case 1:
118       assert(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) == 0);
119       result = 1;
120       break;
121     }
122 
123 #if defined(_MSC_VER) && !defined(__cplusplus)
124   __try
125 #else
126   try
127 #endif
128     {
129       /* Wait for go from main */
130       assert(pthread_mutex_lock(&waitLock) == 0);
131       assert(pthread_mutex_unlock(&waitLock) == 0);
132       sched_yield();
133 
134       for (;;)
135 	{
136 	  pthread_testcancel();
137 	}
138     }
139 #if defined(_MSC_VER) && !defined(__cplusplus)
140   __except(EXCEPTION_EXECUTE_HANDLER)
141 #else
142 #if defined(PtW32CatchAll)
143   PtW32CatchAll
144 #else
145   catch(...)
146 #endif
147 #endif
148     {
149       /*
150        * Should not get into here.
151        */
152       result += 100;
153     }
154 
155   /*
156    * Should not get to here either.
157    */
158   result += 1000;
159 
160   return (void *) result;
161 }
162 
163 int
main()164 main()
165 {
166   int failed = 0;
167   int i;
168   pthread_t t[NUMTHREADS + 1];
169 
170   assert((t[0] = pthread_self()).p != NULL);
171   assert(pthread_mutex_lock(&waitLock) == 0);
172 
173   for (i = 1; i <= NUMTHREADS; i++)
174     {
175       threadbag[i].started = 0;
176       threadbag[i].threadnum = i;
177       assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0);
178     }
179 
180   /*
181    * Code to control or munipulate child threads should probably go here.
182    */
183   Sleep(500);
184 
185   assert(pthread_mutex_unlock(&waitLock) == 0);
186 
187   Sleep(500);
188 
189   for (i = 1; i <= NUMTHREADS; i++)
190     {
191       assert(pthread_cancel(t[i]) == 0);
192     }
193 
194   /*
195    * Give threads time to run.
196    */
197   Sleep(NUMTHREADS * 100);
198 
199   /*
200    * Standard check that all threads started.
201    */
202   for (i = 1; i <= NUMTHREADS; i++)
203     {
204       if (!threadbag[i].started)
205 	{
206 	  failed |= !threadbag[i].started;
207 	  fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);
208 	}
209     }
210 
211   assert(!failed);
212 
213   /*
214    * Check any results here. Set "failed" and only print output on failure.
215    */
216   failed = 0;
217   for (i = 1; i <= NUMTHREADS; i++)
218     {
219       int fail = 0;
220       intptr_t result = 0;
221 
222       assert(pthread_join(t[i], (void **) &result) == 0);
223       fail = (result != (intptr_t) PTHREAD_CANCELED);
224       if (fail)
225 	{
226 	  fprintf(stderr, "Thread %d: started %d: location %d: cancel type %s\n",
227 		  i,
228 		  threadbag[i].started,
229 		  (int)result,
230 		  ((result % 2) == 0) ? "ASYNCHRONOUS" : "DEFERRED");
231 	}
232       failed |= fail;
233     }
234 
235   assert(!failed);
236 
237   /*
238    * Success.
239    */
240   return 0;
241 }
242 
243 #else /* defined(_MSC_VER) || defined(__cplusplus) */
244 
245 int
main()246 main()
247 {
248   return 0;
249 }
250 
251 #endif /* defined(_MSC_VER) || defined(__cplusplus) */
252