• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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