6
6
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
7
7
* Portions Copyright (c) 1994, Regents of the University of California
8
8
*
9
- * $PostgreSQL: pgsql/src/tools/thread/thread_test.c,v 1.12 2004/04/05 02:22:14 momjian Exp $
9
+ * $PostgreSQL: pgsql/src/tools/thread/thread_test.c,v 1.13 2004/04/05 05:43:06 momjian Exp $
10
10
*
11
11
* This program tests to see if your standard libc functions use
12
12
* pthread_setspecific()/pthread_getspecific() to be thread-safe.
@@ -40,6 +40,9 @@ char myhostname[MAXHOSTNAMELEN];
40
40
volatile int errno1_set = 0 ;
41
41
volatile int errno2_set = 0 ;
42
42
43
+ volatile int thread1_done = 0 ;
44
+ volatile int thread2_done = 0 ;
45
+
43
46
char * strerror_p1 ;
44
47
char * strerror_p2 ;
45
48
@@ -49,9 +52,8 @@ struct passwd *passwd_p2;
49
52
struct hostent * hostent_p1 ;
50
53
struct hostent * hostent_p2 ;
51
54
52
- pthread_mutex_t singlethread_lock1 = PTHREAD_MUTEX_INITIALIZER ;
53
- pthread_mutex_t singlethread_lock2 = PTHREAD_MUTEX_INITIALIZER ;
54
-
55
+ pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER ;
56
+
55
57
int main (int argc , char * argv [])
56
58
{
57
59
pthread_t thread1 ,
@@ -73,10 +75,15 @@ int main(int argc, char *argv[])
73
75
Make sure you have added any needed 'THREAD_CPPFLAGS' and 'THREAD_LIBS'\n\
74
76
defines to your template/$port file before compiling this program.\n\n"
75
77
);
78
+
79
+ /* Hold lock until we are ready for the child threads to exit. */
80
+ pthread_mutex_lock (& init_mutex );
81
+
76
82
pthread_create (& thread1 , NULL , (void * (* )(void * )) func_call_1 , NULL );
77
83
pthread_create (& thread2 , NULL , (void * (* )(void * )) func_call_2 , NULL );
78
- pthread_join (thread1 , NULL );
79
- pthread_join (thread2 , NULL );
84
+
85
+ while (thread1_done == 0 || thread2_done == 0 )
86
+ getpid (); /* force system call */
80
87
81
88
printf ("Add this to your template/$port file:\n\n" );
82
89
@@ -94,7 +101,12 @@ defines to your template/$port file before compiling this program.\n\n"
94
101
printf ("GETHOSTBYNAME_THREADSAFE=yes\n" );
95
102
else
96
103
printf ("GETHOSTBYNAME_THREADSAFE=no\n" );
104
+
105
+ pthread_mutex_unlock (& init_mutex ); /* let children exit */
97
106
107
+ pthread_join (thread1 , NULL ); /* clean up children */
108
+ pthread_join (thread2 , NULL );
109
+
98
110
return 0 ;
99
111
}
100
112
@@ -110,7 +122,11 @@ void func_call_1(void) {
110
122
fprintf (stderr , "could not generate failure for create file in /tmp, exiting\n" );
111
123
exit (1 );
112
124
}
113
- /* wait for other thread to set errno */
125
+ /*
126
+ * Wait for other thread to set errno.
127
+ * We can't use thread-specific locking here because it might
128
+ * affect errno.
129
+ */
114
130
errno1_set = 1 ;
115
131
while (errno2_set == 0 )
116
132
getpid (); /* force system call */
@@ -144,6 +160,10 @@ void func_call_1(void) {
144
160
printf ("Your gethostbyname() changes the static memory area between calls\n" );
145
161
hostent_p1 = NULL ; /* force thread-safe failure report */
146
162
}
163
+
164
+ thread1_done = 1 ;
165
+ pthread_mutex_lock (& init_mutex ); /* wait for parent to test */
166
+ pthread_mutex_unlock (& init_mutex );
147
167
}
148
168
149
169
@@ -157,7 +177,11 @@ void func_call_2(void) {
157
177
fprintf (stderr , "Read-only open succeeded without create, exiting\n" );
158
178
exit (1 );
159
179
}
160
- /* wait for other thread to set errno */
180
+ /*
181
+ * Wait for other thread to set errno.
182
+ * We can't use thread-specific locking here because it might
183
+ * affect errno.
184
+ */
161
185
errno2_set = 1 ;
162
186
while (errno1_set == 0 )
163
187
getpid (); /* force system call */
@@ -191,4 +215,8 @@ void func_call_2(void) {
191
215
printf ("Your gethostbyname() changes the static memory area between calls\n" );
192
216
hostent_p2 = NULL ; /* force thread-safe failure report */
193
217
}
218
+
219
+ thread2_done = 1 ;
220
+ pthread_mutex_lock (& init_mutex ); /* wait for parent to test */
221
+ pthread_mutex_unlock (& init_mutex );
194
222
}
0 commit comments