• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * File: cancel4.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 cancelation does not occur in deferred
37  *                cancelation threads with no cancelation points.
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  * - pthread_create
66  *   pthread_self
67  *   pthread_cancel
68  *   pthread_join
69  *   pthread_setcancelstate
70  *   pthread_setcanceltype
71  *
72  * Pass Criteria:
73  * - Process returns zero exit status.
74  *
75  * Fail Criteria:
76  * - Process returns non-zero exit status.
77  */
78 
79 #include "test.h"
80 
81 /*
82  * Create NUMTHREADS threads in addition to the Main thread.
83  */
84 enum {
85   NUMTHREADS = 4
86 };
87 
88 typedef struct bag_t_ bag_t;
89 struct bag_t_ {
90   int threadnum;
91   int started;
92   /* Add more per-thread state variables here */
93   int count;
94 };
95 
96 static bag_t threadbag[NUMTHREADS + 1];
97 
98 void *
mythread(void * arg)99 mythread(void * arg)
100 {
101   intptr_t result = ((intptr_t)PTHREAD_CANCELED + 1);
102   bag_t * bag = (bag_t *) arg;
103 
104   assert(bag == &threadbag[bag->threadnum]);
105   assert(bag->started == 0);
106   bag->started = 1;
107 
108   /* Set to known state and type */
109 
110   assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0);
111 
112   assert(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) == 0);
113 
114   /*
115    * We wait up to 2 seconds, waking every 0.1 seconds,
116    * for a cancelation to be applied to us.
117    */
118   for (bag->count = 0; bag->count < 20; bag->count++)
119     Sleep(100);
120 
121   return (void *) (size_t) result;
122 }
123 
124 int
main()125 main()
126 {
127   int failed = 0;
128   int i;
129   pthread_t t[NUMTHREADS + 1];
130 
131   assert((t[0] = pthread_self()) != 0);
132   assert(pthread_gethandle (t[0]) != NULL);
133 
134   for (i = 1; i <= NUMTHREADS; i++)
135     {
136       threadbag[i].started = 0;
137       threadbag[i].threadnum = i;
138       assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0);
139     }
140 
141   /*
142    * Code to control or munipulate child threads should probably go here.
143    */
144   Sleep(500);
145 
146   for (i = 1; i <= NUMTHREADS; i++)
147     {
148       assert(pthread_cancel(t[i]) == 0);
149     }
150 
151   /*
152    * Give threads time to run.
153    */
154   Sleep(NUMTHREADS * 100);
155 
156   /*
157    * Standard check that all threads started.
158    */
159   for (i = 1; i <= NUMTHREADS; i++)
160     {
161       if (!threadbag[i].started)
162 	{
163 	  failed |= !threadbag[i].started;
164 	  fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);
165 	}
166     }
167 
168   assert(!failed);
169 
170   /*
171    * Check any results here. Set "failed" and only print output on failure.
172    */
173   failed = 0;
174   for (i = 1; i <= NUMTHREADS; i++)
175     {
176       int fail = 0;
177       intptr_t result = 0;
178 
179       /*
180        * The thread does not contain any cancelation points, so
181        * a return value of PTHREAD_CANCELED indicates that async
182        * cancelation occurred.
183        */
184       assert(pthread_join(t[i], (void **) &result) == 0);
185 
186       fail = (result == (intptr_t) PTHREAD_CANCELED);
187 
188       if (fail)
189 	{
190 	  fprintf(stderr, "Thread %d: started %d: count %d\n",
191 		  i,
192 		  threadbag[i].started,
193 		  threadbag[i].count);
194 	}
195       failed = (failed || fail);
196     }
197 
198   assert(!failed);
199 
200   /*
201    * Success.
202    */
203   return 0;
204 }
205