Warning: That file was not part of the compilation database. It may have many parsing errors.

1/* Copyright (C) 2003-2019 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 <http://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/xthread.h>
28
29static void
30wait_code (void)
31{
32 struct timespec ts = { .tv_sec = 0, .tv_nsec = 200000000 };
33 while (nanosleep (&ts, &ts) < 0)
34 ;
35}
36
37
38#ifdef WAIT_IN_CHILD
39static pthread_barrier_t b;
40#endif
41
42static int
43thread_join (pthread_t thread, void **retval)
44{
45#ifdef USE_PTHREAD_TIMEDJOIN_NP
46 struct timespec tv;
47 TEST_COMPARE (clock_gettime (CLOCK_REALTIME, &tv), 0);
48 /* Arbitrary large timeout to make it act as pthread_join. */
49 tv.tv_sec += 1000;
50 return pthread_timedjoin_np ((pthread_t) thread, retval, &tv);
51#else
52 return pthread_join ((pthread_t) thread, retval);
53#endif
54}
55
56
57static void *
58tf1 (void *arg)
59{
60#ifdef WAIT_IN_CHILD
61 xpthread_barrier_wait (&b);
62
63 wait_code ();
64#endif
65
66 thread_join ((pthread_t) arg, NULL);
67
68 exit (42);
69}
70
71
72static void *
73tf2 (void *arg)
74{
75#ifdef WAIT_IN_CHILD
76 xpthread_barrier_wait (&b);
77
78 wait_code ();
79#endif
80
81 thread_join ((pthread_t) arg, NULL);
82
83 exit (43);
84}
85
86
87static int
88do_test (void)
89{
90#ifdef WAIT_IN_CHILD
91 xpthread_barrier_init (&b, NULL, 2);
92#endif
93
94 pthread_t th;
95
96 int err = thread_join (pthread_self (), NULL);
97 if (err == 0)
98 {
99 puts ("1st circular join succeeded");
100 return 1;
101 }
102 if (err != EDEADLK)
103 {
104 printf ("1st circular join %d, not EDEADLK\n", err);
105 return 1;
106 }
107
108 th = xpthread_create (NULL, tf1, (void *) pthread_self ());
109
110#ifndef WAIT_IN_CHILD
111 wait_code ();
112#endif
113
114 xpthread_cancel (th);
115
116#ifdef WAIT_IN_CHILD
117 xpthread_barrier_wait (&b);
118#endif
119
120 void *r;
121 err = thread_join (th, &r);
122 if (err != 0)
123 {
124 printf ("cannot join 1st thread: %d\n", err);
125 return 1;
126 }
127 if (r != PTHREAD_CANCELED)
128 {
129 puts ("1st thread not canceled");
130 return 1;
131 }
132
133 err = thread_join (pthread_self (), NULL);
134 if (err == 0)
135 {
136 puts ("2nd circular join succeeded");
137 return 1;
138 }
139 if (err != EDEADLK)
140 {
141 printf ("2nd circular join %d, not EDEADLK\n", err);
142 return 1;
143 }
144
145 th = xpthread_create (NULL, tf2, (void *) pthread_self ());
146
147#ifndef WAIT_IN_CHILD
148 wait_code ();
149#endif
150
151 xpthread_cancel (th);
152
153#ifdef WAIT_IN_CHILD
154 xpthread_barrier_wait (&b);
155#endif
156
157 if (thread_join (th, &r) != 0)
158 {
159 puts ("cannot join 2nd thread");
160 return 1;
161 }
162 if (r != PTHREAD_CANCELED)
163 {
164 puts ("2nd thread not canceled");
165 return 1;
166 }
167
168 err = thread_join (pthread_self (), NULL);
169 if (err == 0)
170 {
171 puts ("3rd circular join succeeded");
172 return 1;
173 }
174 if (err != EDEADLK)
175 {
176 printf ("3rd circular join %d, not EDEADLK\n", err);
177 return 1;
178 }
179
180 return 0;
181}
182
183#include <support/test-driver.c>
184

Warning: That file was not part of the compilation database. It may have many parsing errors.