Rearrange a bit.
[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 innerok (int a)
69 {
70   pthread_cleanup_push (cleanup, (void *) (long int) a);
71   if (a)
72     return;
73   pthread_cleanup_pop (0);
74 }
75
76
77 static void *
78 t3 (void *arg)
79 {
80   pthread_cleanup_push (cleanupok, (void *) (long int) 4);
81   innerok ((int) (long int) arg);
82   pthread_exit (NULL);
83   pthread_cleanup_pop (0);
84 }
85
86
87 int
88 main (int argc, char *argv[])
89 {
90   pthread_t td;
91   int err;
92   char *tmp;
93   const char *path;
94   const char template[] = "thtstXXXXXX";
95   struct stat64 st;
96   int result = 0;
97
98   path = argc > 1 ? argv[1] : "";
99   tmp = (char *) alloca (strlen (path) + sizeof template);
100   strcpy (stpcpy (tmp, path), template);
101
102   fd = mkstemp (tmp);
103   if (fd == -1)
104     {
105       printf ("cannot create temporary file: %m");
106       exit (1);
107     }
108   unlink (tmp);
109
110   err = pthread_barrier_init (&bar, NULL, 2);
111   if (err != 0 )
112     {
113       printf ("cannot create barrier: %s\n", strerror (err));
114       exit (1);
115     }
116
117   err = pthread_create (&td, NULL, t1, NULL);
118   if (err != 0)
119     {
120       printf ("cannot create thread t1: %s\n", strerror (err));
121       exit (1);
122     }
123
124   err = pthread_join (td, NULL);
125   if (err != 0)
126     {
127       printf ("cannot join thread: %s\n", strerror (err));
128       exit (1);
129     }
130
131   err = pthread_create (&td, NULL, t2, (void *) 3);
132   if (err != 0)
133     {
134       printf ("cannot create thread t2: %s\n", strerror (err));
135       exit (1);
136     }
137
138   err = pthread_join (td, NULL);
139   if (err != 0)
140     {
141       printf ("cannot join thread: %s\n", strerror (err));
142       exit (1);
143     }
144
145   err = pthread_create (&td, NULL, t3, (void *) 5);
146   if (err != 0)
147     {
148       printf ("cannot create thread t3: %s\n", strerror (err));
149       exit (1);
150     }
151
152   err = pthread_join (td, NULL);
153   if (err != 0)
154     {
155       printf ("cannot join thread: %s\n", strerror (err));
156       exit (1);
157     }
158
159   if (fstat64 (fd, &st) < 0)
160     {
161       printf ("cannot stat temporary file: %m\n");
162       result = 1;
163     }
164   else if (st.st_size != 0)
165     {
166       char buf[512];
167       puts ("some cleanup handlers ran:");
168       fflush (stdout);
169       __lseek (fd, 0, SEEK_SET);
170       while (1)
171         {
172           ssize_t n = read (fd, buf, sizeof buf);
173           if (n <= 0)
174             break;
175           write (STDOUT_FILENO, buf, n);
176         }
177       result = 1;
178     }
179
180   if (cleanupokcnt != 1)
181     {
182       printf ("cleanupokcnt = %d\n", cleanupokcnt);
183       result = 1;
184     }
185
186   return result;
187 }