1 /* Copyright (C) 2002-2022 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3 
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
8 
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
13 
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library; if not, see
16    <https://www.gnu.org/licenses/>.  */
17 
18 #include <errno.h>
19 #include <pthread.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <time.h>
24 
25 
26 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
27 
28 
29 static void *
tf(void * arg)30 tf (void *arg)
31 {
32   if (pthread_mutex_lock (&lock) != 0)
33     {
34       puts ("child: mutex_lock failed");
35       return NULL;
36     }
37 
38   return (void *) 42l;
39 }
40 
41 
42 static int
do_test(void)43 do_test (void)
44 {
45   pthread_t th;
46 
47   if (pthread_mutex_lock (&lock) != 0)
48     {
49       puts ("mutex_lock failed");
50       exit (1);
51     }
52 
53   if (pthread_create (&th, NULL, tf, NULL) != 0)
54     {
55       puts ("mutex_create failed");
56       exit (1);
57     }
58 
59   void *status;
60   int val = pthread_tryjoin_np (th, &status);
61   if (val == 0)
62     {
63       puts ("1st tryjoin succeeded");
64       exit (1);
65     }
66   else if (val != EBUSY)
67     {
68       puts ("1st tryjoin didn't return EBUSY");
69       exit (1);
70     }
71 
72   if (pthread_mutex_unlock (&lock) != 0)
73     {
74       puts ("mutex_unlock failed");
75       exit (1);
76     }
77 
78   while ((val = pthread_tryjoin_np (th, &status)) != 0)
79     {
80       if (val != EBUSY)
81 	{
82 	  printf ("tryjoin returned %s (%d), expected only 0 or EBUSY\n",
83 		  strerror (val), val);
84 	  exit (1);
85 	}
86 
87       /* Delay minimally.  */
88       struct timespec ts = { .tv_sec = 0, .tv_nsec = 10000000 };
89       nanosleep (&ts, NULL);
90     }
91 
92   if (status != (void *) 42l)
93     {
94       printf ("return value %p, expected %p\n", status, (void *) 42l);
95       exit (1);
96     }
97 
98   return 0;
99 }
100 
101 #define TEST_FUNCTION do_test ()
102 #include "../test-skeleton.c"
103