]> git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/pthread/tst-join5.c
Update copyright dates with scripts/update-copyrights
[thirdparty/glibc.git] / sysdeps / pthread / tst-join5.c
1 /* Copyright (C) 2003-2021 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
18
19 #include <errno.h>
20 #include <pthread.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <time.h>
24 #include <unistd.h>
25
26 #include <support/check.h>
27 #include <support/timespec.h>
28 #include <support/xthread.h>
29 #include <support/xtime.h>
30
31 static void
32 wait_code (void)
33 {
34 struct timespec ts = { .tv_sec = 0, .tv_nsec = 200000000 };
35 while (nanosleep (&ts, &ts) < 0)
36 ;
37 }
38
39
40 #ifdef WAIT_IN_CHILD
41 static pthread_barrier_t b;
42 #endif
43
44 static int
45 thread_join (pthread_t thread, void **retval)
46 {
47 #if defined USE_PTHREAD_TIMEDJOIN_NP
48 const struct timespec ts = timespec_add (xclock_now (CLOCK_REALTIME),
49 make_timespec (1000, 0));
50 return pthread_timedjoin_np (thread, retval, &ts);
51 #elif defined USE_PTHREAD_CLOCKJOIN_NP_REALTIME
52 const struct timespec ts = timespec_add (xclock_now (CLOCK_REALTIME),
53 make_timespec (1000, 0));
54 return pthread_clockjoin_np (thread, retval, CLOCK_REALTIME, &ts);
55 #elif defined USE_PTHREAD_CLOCKJOIN_NP_MONOTONIC
56 const struct timespec ts = timespec_add (xclock_now (CLOCK_MONOTONIC),
57 make_timespec (1000, 0));
58 return pthread_clockjoin_np (thread, retval, CLOCK_MONOTONIC, &ts);
59 #else
60 return pthread_join (thread, retval);
61 #endif
62 }
63
64
65 static void *
66 tf1 (void *arg)
67 {
68 #ifdef WAIT_IN_CHILD
69 xpthread_barrier_wait (&b);
70
71 wait_code ();
72 #endif
73
74 thread_join ((pthread_t) arg, NULL);
75
76 exit (42);
77 }
78
79
80 static void *
81 tf2 (void *arg)
82 {
83 #ifdef WAIT_IN_CHILD
84 xpthread_barrier_wait (&b);
85
86 wait_code ();
87 #endif
88
89 thread_join ((pthread_t) arg, NULL);
90
91 exit (43);
92 }
93
94
95 static int
96 do_test (void)
97 {
98 #ifdef WAIT_IN_CHILD
99 xpthread_barrier_init (&b, NULL, 2);
100 #endif
101
102 pthread_t th;
103
104 int err = thread_join (pthread_self (), NULL);
105 if (err == 0)
106 {
107 puts ("1st circular join succeeded");
108 return 1;
109 }
110 if (err != EDEADLK)
111 {
112 printf ("1st circular join %d, not EDEADLK\n", err);
113 return 1;
114 }
115
116 th = xpthread_create (NULL, tf1, (void *) pthread_self ());
117
118 #ifndef WAIT_IN_CHILD
119 wait_code ();
120 #endif
121
122 xpthread_cancel (th);
123
124 #ifdef WAIT_IN_CHILD
125 xpthread_barrier_wait (&b);
126 #endif
127
128 void *r;
129 err = thread_join (th, &r);
130 if (err != 0)
131 {
132 printf ("cannot join 1st thread: %d\n", err);
133 return 1;
134 }
135 if (r != PTHREAD_CANCELED)
136 {
137 puts ("1st thread not canceled");
138 return 1;
139 }
140
141 err = thread_join (pthread_self (), NULL);
142 if (err == 0)
143 {
144 puts ("2nd circular join succeeded");
145 return 1;
146 }
147 if (err != EDEADLK)
148 {
149 printf ("2nd circular join %d, not EDEADLK\n", err);
150 return 1;
151 }
152
153 th = xpthread_create (NULL, tf2, (void *) pthread_self ());
154
155 #ifndef WAIT_IN_CHILD
156 wait_code ();
157 #endif
158
159 xpthread_cancel (th);
160
161 #ifdef WAIT_IN_CHILD
162 xpthread_barrier_wait (&b);
163 #endif
164
165 if (thread_join (th, &r) != 0)
166 {
167 puts ("cannot join 2nd thread");
168 return 1;
169 }
170 if (r != PTHREAD_CANCELED)
171 {
172 puts ("2nd thread not canceled");
173 return 1;
174 }
175
176 err = thread_join (pthread_self (), NULL);
177 if (err == 0)
178 {
179 puts ("3rd circular join succeeded");
180 return 1;
181 }
182 if (err != EDEADLK)
183 {
184 printf ("3rd circular join %d, not EDEADLK\n", err);
185 return 1;
186 }
187
188 return 0;
189 }
190
191 #include <support/test-driver.c>