OSDN Git Service

Enable to track git://github.com/monaka/binutils.git
[pf3gnuchains/pf3gnuchains3x.git] / winsup / testsuite / winsup.api / pthread / cancel3.c
1 /*
2  * File: cancel3.c
3  *
4  * Test Synopsis: Test asynchronous cancelation.
5  *
6  * Test Method (Validation or Falsification):
7  * - 
8  *
9  * Requirements Tested:
10  * -
11  *
12  * Features Tested:
13  * - 
14  *
15  * Cases Tested:
16  * - 
17  *
18  * Description:
19  * - 
20  *
21  * Environment:
22  * - 
23  *
24  * Input:
25  * - None.
26  *
27  * Output:
28  * - File name, Line number, and failed expression on failure.
29  * - No output on success.
30  *
31  * Assumptions:
32  * - have working pthread_create, pthread_self, pthread_mutex_lock/unlock
33  *   pthread_testcancel, pthread_cancel, pthread_join
34  *
35  * Pass Criteria:
36  * - Process returns zero exit status.
37  *
38  * Fail Criteria:
39  * - Process returns non-zero exit status.
40  */
41
42 #include "test.h"
43
44 /*
45  * Create NUMTHREADS threads in addition to the Main thread.
46  */
47 enum {
48   NUMTHREADS = 10
49 };
50
51 typedef struct bag_t_ bag_t;
52 struct bag_t_ {
53   int threadnum;
54   int started;
55   /* Add more per-thread state variables here */
56   int count;
57 };
58
59 static bag_t threadbag[NUMTHREADS + 1];
60
61 void *
62 mythread(void * arg)
63 {
64   int result = ((int)PTHREAD_CANCELED + 1);
65   bag_t * bag = (bag_t *) arg;
66
67   assert(bag == &threadbag[bag->threadnum]);
68   assert(bag->started == 0);
69   bag->started = 1;
70
71   /* Set to known state and type */
72
73   assert(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) == 0);
74
75   assert(pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) == 0);
76
77   /*
78    * We wait up to 10 seconds, waking every 0.1 seconds,
79    * for a cancelation to be applied to us.
80    */
81   for (bag->count = 0; bag->count < 100; bag->count++)
82     Sleep(100);
83
84   return (void *) result;
85 }
86
87 int
88 main()
89 {
90   int failed = 0;
91   int i;
92   pthread_t t[NUMTHREADS + 1];
93
94   assert((t[0] = pthread_self()) != NULL);
95
96   for (i = 1; i <= NUMTHREADS; i++)
97     {
98       threadbag[i].started = 0;
99       threadbag[i].threadnum = i;
100       assert(pthread_create(&t[i], NULL, mythread, (void *) &threadbag[i]) == 0);
101     }
102
103   /*
104    * Code to control or munipulate child threads should probably go here.
105    */
106   Sleep(500);
107
108   for (i = 1; i <= NUMTHREADS; i++)
109     {
110       assert(pthread_cancel(t[i]) == 0);
111     }
112
113   /*
114    * Give threads time to run.
115    */
116   Sleep(NUMTHREADS * 100);
117
118   /*
119    * Standard check that all threads started.
120    */
121   for (i = 1; i <= NUMTHREADS; i++)
122     { 
123       if (!threadbag[i].started)
124         {
125           failed |= !threadbag[i].started;
126           fprintf(stderr, "Thread %d: started %d\n", i, threadbag[i].started);
127         }
128     }
129
130   assert(!failed);
131
132   /*
133    * Check any results here. Set "failed" and only print output on failure.
134    */
135   failed = 0;
136   for (i = 1; i <= NUMTHREADS; i++)
137     {
138       int fail = 0;
139       int result = 0;
140
141       /*
142        * The thread does not contain any cancelation points, so
143        * a return value of PTHREAD_CANCELED confirms that async
144        * cancelation succeeded.
145        */
146       assert(pthread_join(t[i], (void **) &result) == 0);
147
148       fail = (result != (int) PTHREAD_CANCELED);
149
150       if (fail)
151         {
152           fprintf(stderr, "Thread %d: started %d: count %d\n",
153                   i,
154                   threadbag[i].started,
155                   threadbag[i].count);
156         }
157       failed = (failed || fail);
158     }
159
160   assert(!failed);
161
162   /*
163    * Success.
164    */
165   return 0;
166 }