Disable most tests. Add new test where all cleanup handlers must run.
[kopensolaris-gnu/glibc.git] / linuxthreads / tst-cancel.c
1 /* Tests for cancelation handling.  */
2
3 #include <pthread.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <unistd.h>
8 #include <sys/stat.h>
9
10 int fd;
11
12 pthread_barrier_t bar;
13
14
15 static void
16 cleanup (void *arg)
17 {
18   int nr = (int) (long int) arg;
19   char s[30];
20   char *cp = stpcpy (s, "cleanup ");
21   *cp++ = '0' + nr;
22   *cp++ = '\n';
23   __libc_lseek (fd, 0, SEEK_END);
24   __libc_write (fd, s, cp - s);
25 }
26
27
28 static void *
29 t1 (void *arg)
30 {
31   pthread_cleanup_push (cleanup, (void *) (long int) 1);
32   return NULL;
33   pthread_cleanup_pop (0);
34 }
35
36
37 static void
38 inner (int a)
39 {
40   pthread_cleanup_push (cleanup, (void *) (long int) a);
41   if (a)
42     return;
43   pthread_cleanup_pop (0);
44 }
45
46
47 static void *
48 t2 (void *arg)
49 {
50   pthread_cleanup_push (cleanup, (void *) (long int) 2);
51   inner ((int) (long int) arg);
52   return NULL;
53   pthread_cleanup_pop (0);
54 }
55
56
57 /* This does not work yet.  */
58 volatile int cleanupokcnt;
59
60 static void
61 cleanupok (void *arg)
62 {
63   ++cleanupokcnt;
64 }
65
66
67 static void *
68 t3 (void *arg)
69 {
70   pthread_cleanup_push (cleanupok, (void *) (long int) 4);
71   inner ((int) (long int) arg);
72   pthread_exit (NULL);
73   pthread_cleanup_pop (0);
74 }
75
76
77 static void
78 innerok (int a)
79 {
80   pthread_cleanup_push (cleanupok, (void *) (long int) a);
81   pthread_exit (NULL);
82   pthread_cleanup_pop (0);
83 }
84
85
86 static void *
87 t4 (void *arg)
88 {
89   pthread_cleanup_push (cleanupok, (void *) (long int) 6);
90   innerok ((int) (long int) arg);
91   pthread_cleanup_pop (0);
92   return NULL;
93 }
94
95
96 int
97 main (int argc, char *argv[])
98 {
99   pthread_t td;
100   int err;
101   char *tmp;
102   const char *prefix;
103   const char template[] = "thtstXXXXXX";
104   struct stat64 st;
105   int result = 0;
106
107   prefix = argc > 1 ? argv[1] : "";
108   tmp = (char *) alloca (strlen (prefix) + sizeof template);
109   strcpy (stpcpy (tmp, prefix), template);
110
111   fd = mkstemp (tmp);
112   if (fd == -1)
113     {
114       printf ("cannot create temporary file: %m");
115       exit (1);
116     }
117   unlink (tmp);
118
119   err = pthread_barrier_init (&bar, NULL, 2);
120   if (err != 0 )
121     {
122       printf ("cannot create barrier: %s\n", strerror (err));
123       exit (1);
124     }
125
126 #ifdef NOT_YET
127   err = pthread_create (&td, NULL, t1, NULL);
128   if (err != 0)
129     {
130       printf ("cannot create thread t1: %s\n", strerror (err));
131       exit (1);
132     }
133
134   err = pthread_join (td, NULL);
135   if (err != 0)
136     {
137       printf ("cannot join thread: %s\n", strerror (err));
138       exit (1);
139     }
140
141   err = pthread_create (&td, NULL, t2, (void *) 3);
142   if (err != 0)
143     {
144       printf ("cannot create thread t2: %s\n", strerror (err));
145       exit (1);
146     }
147
148   err = pthread_join (td, NULL);
149   if (err != 0)
150     {
151       printf ("cannot join thread: %s\n", strerror (err));
152       exit (1);
153     }
154
155   err = pthread_create (&td, NULL, t3, (void *) 5);
156   if (err != 0)
157     {
158       printf ("cannot create thread t3: %s\n", strerror (err));
159       exit (1);
160     }
161
162   err = pthread_join (td, NULL);
163   if (err != 0)
164     {
165       printf ("cannot join thread: %s\n", strerror (err));
166       exit (1);
167     }
168 #endif
169
170   err = pthread_create (&td, NULL, t4, (void *) 7);
171   if (err != 0)
172     {
173       printf ("cannot create thread t3: %s\n", strerror (err));
174       exit (1);
175     }
176
177   err = pthread_join (td, NULL);
178   if (err != 0)
179     {
180       printf ("cannot join thread: %s\n", strerror (err));
181       exit (1);
182     }
183
184   if (fstat64 (fd, &st) < 0)
185     {
186       printf ("cannot stat temporary file: %m\n");
187       result = 1;
188     }
189   else if (st.st_size != 0)
190     {
191       char buf[512];
192       puts ("some cleanup handlers ran:");
193       fflush (stdout);
194       __lseek (fd, 0, SEEK_SET);
195       while (1)
196         {
197           ssize_t n = read (fd, buf, sizeof buf);
198           if (n <= 0)
199             break;
200           write (STDOUT_FILENO, buf, n);
201         }
202       result = 1;
203     }
204
205   // if (cleanupokcnt != 3)  will be three once t3 runs
206   if (cleanupokcnt != 2)
207     {
208       printf ("cleanupokcnt = %d\n", cleanupokcnt);
209       result = 1;
210     }
211
212   return result;
213 }