1 /*
2 * File: cancel6a.c
3 *
4 *
5 * Pthreads-win32 - POSIX Threads Library for Win32
6 * Copyright (C) 1998 Ben Elliston and Ross Johnson
7 * Copyright (C) 1999,2000,2001 Ross Johnson
8 *
9 * Contact Email: rpj@ise.canberra.edu.au
10 *
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
15 *
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 * --------------------------------------------------------------------------
26 *
27 * Test Synopsis: Test double cancelation - asynchronous.
28 * Second attempt should fail (ESRCH).
29 *
30 * Test Method (Validation or Falsification):
31 * -
32 *
33 * Requirements Tested:
34 * -
35 *
36 * Features Tested:
37 * -
38 *
39 * Cases Tested:
40 * -
41 *
42 * Description:
43 * -
44 *
45 * Environment:
46 * -
47 *
48 * Input:
49 * - None.
50 *
51 * Output:
52 * - File name, Line number, and failed expression on failure.
53 * - No output on success.
54 *
55 * Assumptions:
56 * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
57 * pthread_testcancel, pthread_cancel, pthread_join
58 *
59 * Pass Criteria:
60 * - Process returns zero exit status.
61 *
62 * Fail Criteria:
63 * - Process returns non-zero exit status.
64 */
65
66 #include "test.h"
67
68 /*
69 * Create NUMTHREADS threads in addition to the Main thread.
70 */
71 enum {
72 NUMTHREADS = 4
73 };
74
75 typedef struct bag_t_ bag_t;
76 struct bag_t_ {
77 int threadnum;
78 int started;
79 /* Add more per-thread state variables here */
80 int count;
81 };
82
83 static bag_t threadbag[NUMTHREADS + 1];
84
85 void *
mythread(void * arg)86 mythread(void * arg)
87 {
88 int result = (((int) (size_t) PTHREAD_CANCELED) + 1);
89 bag_t * bag = (bag_t *) arg;
90
91 assert(bag == &threadbag[bag->threadnum]);
92 assert(bag->started == 0);
93 bag->started = 1;
94
95 /* Set to known state and type */
96
97 assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0);
98
99 assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0);
100
101 /*
102 * We wait up to 10 seconds, waking every 0.1 seconds,
103 * for a cancelation to be applied to us.
104 */
105 for (bag->count = 0; bag->count < 100; bag->count++)
106 Sleep(100);
107
108 return (void *) (size_t) result;
109 }
110
111 int
main()112 main()
113 {
114 int failed = 0;
115 int i;
116 pthread_t t[NUMTHREADS + 1];
117
118 assert((t[0] = pthread_self()) != 0);
119 assert(pthread_gethandle (t[0]) != NULL);
120
121 for (i = 1; i <= NUMTHREADS; i++)
122 {
123 threadbag[i].started = 0;
124 threadbag[i].threadnum = i;
125 assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0);
126 }
127
128 /*
129 * Code to control or munipulate child threads should probably go here.
130 */
131 Sleep(500);
132
133 for (i = 1; i <= NUMTHREADS; i++)
134 {
135 assert(pthread_cancel(t[i]) == 0);
136 assert(pthread_cancel(t[i]) == ESRCH);
137 }
138
139 /*
140 * Give threads time to run.
141 */
142 Sleep(NUMTHREADS * 100);
143
144 /*
145 * Standard check that all threads started.
146 */
147 for (i = 1; i <= NUMTHREADS; i++)
148 {
149 if (!threadbag[i].started)
150 {
151 failed |= !threadbag[i].started;
152 fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);
153 }
154 }
155
156 assert(!failed);
157
158 /*
159 * Check any results here. Set "failed" and only print output on failure.
160 */
161 failed = 0;
162 for (i = 1; i <= NUMTHREADS; i++)
163 {
164 int fail = 0;
165 intptr_t result = 0;
166
167 /*
168 * The thread does not contain any cancelation points, so
169 * a return value of PTHREAD_CANCELED confirms that async
170 * cancelation succeeded.
171 */
172 assert(pthread_join(t[i], (void **) &result) == 0);
173
174 fail = (result != (intptr_t) PTHREAD_CANCELED);
175
176 if (fail)
177 {
178 fprintf(stderr, "Thread %d: started %d: count %d\n",
179 i,
180 threadbag[i].started,
181 threadbag[i].count);
182 }
183 failed = (failed || fail);
184 }
185
186 assert(!failed);
187
188 /*
189 * Success.
190 */
191 return 0;
192 }
193