From 66b42d3028d9fc6c95b9ca00ae7136e0af0274f1 Mon Sep 17 00:00:00 2001
From: Bruce Momjian <bruce@momjian.us>
Date: Fri, 23 Apr 2004 20:35:50 +0000
Subject: [PATCH] Improve thread test program.  Test only functions that need
 testing.

---
 src/tools/thread/Makefile      |   9 +-
 src/tools/thread/thread_test.c | 202 +++++++++++++++++++--------------
 2 files changed, 120 insertions(+), 91 deletions(-)

diff --git a/src/tools/thread/Makefile b/src/tools/thread/Makefile
index 3334d41e248..22d5d09f684 100644
--- a/src/tools/thread/Makefile
+++ b/src/tools/thread/Makefile
@@ -4,7 +4,7 @@
 #
 # Copyright (C) 2003 by PostgreSQL Global Development Team
 #
-# $PostgreSQL: pgsql/src/tools/thread/Makefile,v 1.4 2004/04/23 18:15:55 momjian Exp $
+# $PostgreSQL: pgsql/src/tools/thread/Makefile,v 1.5 2004/04/23 20:35:50 momjian Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -12,13 +12,6 @@ subdir = tools/thread
 top_builddir = ../../..
 include $(top_builddir)/src/Makefile.global
 
-ifeq ($(THREAD_SUPPORT), no)
-$(error Your platform does not support threads)
-endif
-ifeq ($(THREAD_SUPPORT), )
-$(error You have not configured your template/$$port file.  See the README)
-endif
-
 override CFLAGS += $(PTHREAD_CFLAGS)
 
 LDFLAGS += $(PTHREAD_LIBS)
diff --git a/src/tools/thread/thread_test.c b/src/tools/thread/thread_test.c
index d866f21dbd1..0edf55226b9 100644
--- a/src/tools/thread/thread_test.c
+++ b/src/tools/thread/thread_test.c
@@ -1,12 +1,12 @@
 /*-------------------------------------------------------------------------
  *
  * test_thread_funcs.c
- *      libc thread test program
+ *		libc thread test program
  *
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- *	$PostgreSQL: pgsql/src/tools/thread/thread_test.c,v 1.20 2004/04/23 18:15:55 momjian Exp $
+ *	$PostgreSQL: pgsql/src/tools/thread/thread_test.c,v 1.21 2004/04/23 20:35:50 momjian Exp $
  *
  *	This program tests to see if your standard libc functions use
  *	pthread_setspecific()/pthread_getspecific() to be thread-safe.
@@ -33,188 +33,210 @@
 
 #include "postgres.h"
 
-void func_call_1(void);
-void func_call_2(void);
+void		func_call_1(void);
+void		func_call_2(void);
 
-char myhostname[MAXHOSTNAMELEN];
-
-volatile int errno1_set = 0;
-volatile int errno2_set = 0;
+pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 volatile int thread1_done = 0;
 volatile int thread2_done = 0;
 
-char *strerror_p1;
-char *strerror_p2;
+volatile int errno1_set = 0;
+volatile int errno2_set = 0;
 
+#ifndef HAVE_STRERROR_R
+char	   *strerror_p1;
+char	   *strerror_p2;
+bool		strerror_threadsafe = false;
+#endif
+
+#ifndef HAVE_GETPWUID_R
 struct passwd *passwd_p1;
 struct passwd *passwd_p2;
+bool		getpwuid_threadsafe = false;
+#endif
 
+#if !defined(HAVE_GETADDRINFO) && !defined(HAVE_GETHOSTBYNAME_R)
 struct hostent *hostent_p1;
 struct hostent *hostent_p2;
+char		myhostname[MAXHOSTNAMELEN];
+bool		gethostbyname_threadsafe = false;
+#endif
 
-bool gethostbyname_threadsafe = false;
-bool getpwuid_threadsafe = false;
-bool strerror_threadsafe = false;
-bool platform_is_threadsafe = true;
-
-pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;
+bool		platform_is_threadsafe = true;
 
-int main(int argc, char *argv[])
+int
+main(int argc, char *argv[])
 {
-	pthread_t		thread1,
-					thread2;
+	pthread_t	thread1,
+				thread2;
 
 	if (argc > 1)
 	{
-			fprintf(stderr, "Usage: %s\n", argv[0]);
-			return 1;
+		fprintf(stderr, "Usage: %s\n", argv[0]);
+		return 1;
 	}
 
+#if !defined(HAVE_GETADDRINFO) && !defined(HAVE_GETHOSTBYNAME_R)
 	if (gethostname(myhostname, MAXHOSTNAMELEN) != 0)
 	{
-			fprintf(stderr, "can not get local hostname, exiting\n");
-			exit(1);
+		fprintf(stderr, "can not get local hostname, exiting\n");
+		exit(1);
 	}
-
-	printf("\
-Make sure you have added any needed 'PTHREAD_CFLAGS' and 'PTHREAD_LIBS'\n\
-defines to your template/$port file before compiling this program.\n\n"
-);
+#endif
 
 	/* Hold lock until we are ready for the child threads to exit. */
-	pthread_mutex_lock(&init_mutex);	
-	    
-	pthread_create(&thread1, NULL, (void * (*)(void *)) func_call_1, NULL);
-	pthread_create(&thread2, NULL, (void * (*)(void *)) func_call_2, NULL);
+	pthread_mutex_lock(&init_mutex);
+
+	pthread_create(&thread1, NULL, (void *(*) (void *)) func_call_1, NULL);
+	pthread_create(&thread2, NULL, (void *(*) (void *)) func_call_2, NULL);
 
 	while (thread1_done == 0 || thread2_done == 0)
-		sched_yield();	/* if this is a portability problem, remove it */
+		sched_yield();			/* if this is a portability problem,
+								 * remove it */
 
-	fprintf(stderr, "errno is thread-safe\n");
-	
+	fprintf(stderr, "Your errno is thread-safe.\n");
+
+#ifndef HAVE_STRERROR_R
 	if (strerror_p1 != strerror_p2)
 		strerror_threadsafe = true;
+#endif
 
+#ifndef HAVE_GETPWUID_R
 	if (passwd_p1 != passwd_p2)
 		getpwuid_threadsafe = true;
+#endif
 
+#if !defined(HAVE_GETADDRINFO) && !defined(HAVE_GETHOSTBYNAME_R)
 	if (hostent_p1 != hostent_p2)
 		gethostbyname_threadsafe = true;
+#endif
 
 	pthread_mutex_unlock(&init_mutex);	/* let children exit  */
-	
+
 	pthread_join(thread1, NULL);	/* clean up children */
 	pthread_join(thread2, NULL);
 
-	printf("\n");
-
 #ifdef HAVE_STRERROR_R
-	printf("Your system has sterror_r(), so it doesn't use strerror().\n");
+	printf("Your system has sterror_r();  it does not need strerror().\n");
 #else
 	printf("Your system uses strerror() which is ");
 	if (strerror_threadsafe)
 		printf("thread-safe.\n");
 	else
 	{
-		platform_is_threadsafe = false;
 		printf("not thread-safe.\n");
+		platform_is_threadsafe = false;
 	}
 #endif
 
 #ifdef HAVE_GETPWUID_R
-	printf("Your system has getpwuid_r(), so it doesn't use getpwuid().\n");
+	printf("Your system has getpwuid_r();  it does not need getpwuid().\n");
 #else
 	printf("Your system uses getpwuid() which is ");
 	if (getpwuid_threadsafe)
 		printf("thread-safe.\n");
 	else
 	{
-		platform_is_threadsafe = false;
 		printf("not thread-safe.\n");
+		platform_is_threadsafe = false;
 	}
 #endif
 
 #ifdef HAVE_GETADDRINFO
-	printf("Your system has getaddrinfo(), so it doesn't use gethostbyname()\n"
-			"  or gethostbyname_r().\n");
+	printf("Your system has getaddrinfo();  it does not need gethostbyname()\n"
+		   "  or gethostbyname_r().\n");
 #else
 #ifdef HAVE_GETHOSTBYNAME_R
-	printf("Your system has gethostbyname_r(), so it doesn't use gethostbyname().\n");
+	printf("Your system has gethostbyname_r();  it does not need gethostbyname().\n");
 #else
 	printf("Your system uses gethostbyname which is ");
 	if (gethostbyname_threadsafe)
 		printf("thread-safe.\n");
 	else
 	{
-		platform_is_threadsafe = false;
 		printf("not thread-safe.\n");
+		platform_is_threadsafe = false;
 	}
 #endif
 #endif
 
-	if (!platform_is_threadsafe)
+	if (platform_is_threadsafe)
 	{
-		printf("\n** YOUR PLATFORM IS NOT THREADSAFE **\n");
-		return 1;
+		printf("\nYour platform is thread-safe.\n");
+		return 0;
 	}
 	else
 	{
-		printf("\nYOUR PLATFORM IS THREADSAFE\n");
-		return 0;
+		printf("\n** YOUR PLATFORM IS NOT THREAD-SAFE. **\n");
+		return 1;
 	}
 }
 
-void func_call_1(void) {
-	void *p;
-	
+void
+func_call_1(void)
+{
+#if !defined(HAVE_GETPWUID_R) || \
+	(!defined(HAVE_GETADDRINFO) && \
+	 !defined(HAVE_GETHOSTBYNAME_R))
+	void	   *p;
+#endif
+
 	unlink("/tmp/thread_test.1");
 	/* create, then try to fail on exclusive create open */
 	if (open("/tmp/thread_test.1", O_RDWR | O_CREAT, 0600) < 0 ||
 		open("/tmp/thread_test.1", O_RDWR | O_CREAT | O_EXCL, 0600) >= 0)
 	{
-			fprintf(stderr, "Could not create file in /tmp or\n");
-			fprintf(stderr, "could not generate failure for create file in /tmp, exiting\n");
-			exit(1);
+		fprintf(stderr, "Could not create file in /tmp or\n");
+		fprintf(stderr, "could not generate failure for create file in /tmp, exiting\n");
+		exit(1);
 	}
+
 	/*
-	 *	Wait for other thread to set errno.
-	 *	We can't use thread-specific locking here because it might
-	 *	affect errno.
+	 * Wait for other thread to set errno. We can't use thread-specific
+	 * locking here because it might affect errno.
 	 */
 	errno1_set = 1;
 	while (errno2_set == 0)
 		sched_yield();
 	if (errno != EEXIST)
 	{
-			fprintf(stderr, "errno not thread-safe; exiting\n");
-			unlink("/tmp/thread_test.1");
-			exit(1);
+		fprintf(stderr, "errno not thread-safe; exiting\n");
+		unlink("/tmp/thread_test.1");
+		exit(1);
 	}
 	unlink("/tmp/thread_test.1");
-	
+
+#ifndef HAVE_STRERROR_R
 	strerror_p1 = strerror(EACCES);
+
 	/*
-	 *	If strerror() uses sys_errlist, the pointer might change for different
-	 *	errno values, so we don't check to see if it varies within the thread.
+	 * If strerror() uses sys_errlist, the pointer might change for
+	 * different errno values, so we don't check to see if it varies
+	 * within the thread.
 	 */
+#endif
 
+#ifndef HAVE_GETPWUID_R
 	passwd_p1 = getpwuid(0);
 	p = getpwuid(1);
 	if (passwd_p1 != p)
 	{
 		printf("Your getpwuid() changes the static memory area between calls\n");
-		passwd_p1 = NULL;	/* force thread-safe failure report */
+		passwd_p1 = NULL;		/* force thread-safe failure report */
 	}
+#endif
 
+#if !defined(HAVE_GETADDRINFO) && !defined(HAVE_GETHOSTBYNAME_R)
 	/* threads do this in opposite order */
 	hostent_p1 = gethostbyname(myhostname);
 	p = gethostbyname("localhost");
 	if (hostent_p1 != p)
 	{
 		printf("Your gethostbyname() changes the static memory area between calls\n");
-		hostent_p1 = NULL;	/* force thread-safe failure report */
+		hostent_p1 = NULL;		/* force thread-safe failure report */
 	}
+#endif
 
 	thread1_done = 1;
 	pthread_mutex_lock(&init_mutex);	/* wait for parent to test */
@@ -222,54 +244,68 @@ void func_call_1(void) {
 }
 
 
-void func_call_2(void) {
-	void *p;
+void
+func_call_2(void)
+{
+#if !defined(HAVE_GETPWUID_R) || \
+	(!defined(HAVE_GETADDRINFO) && \
+	 !defined(HAVE_GETHOSTBYNAME_R))
+	void	   *p;
+#endif
 
 	unlink("/tmp/thread_test.2");
 	/* open non-existant file */
 	if (open("/tmp/thread_test.2", O_RDONLY, 0600) >= 0)
 	{
-			fprintf(stderr, "Read-only open succeeded without create, exiting\n");
-			exit(1);
+		fprintf(stderr, "Read-only open succeeded without create, exiting\n");
+		exit(1);
 	}
+
 	/*
-	 *	Wait for other thread to set errno.
-	 *	We can't use thread-specific locking here because it might
-	 *	affect errno.
+	 * Wait for other thread to set errno. We can't use thread-specific
+	 * locking here because it might affect errno.
 	 */
 	errno2_set = 1;
 	while (errno1_set == 0)
 		sched_yield();
 	if (errno != ENOENT)
 	{
-			fprintf(stderr, "errno not thread-safe; exiting\n");
-			unlink("/tmp/thread_test.A");
-			exit(1);
+		fprintf(stderr, "errno not thread-safe; exiting\n");
+		unlink("/tmp/thread_test.A");
+		exit(1);
 	}
 	unlink("/tmp/thread_test.2");
-	
+
+#ifndef HAVE_STRERROR_R
 	strerror_p2 = strerror(EINVAL);
+
 	/*
-	 *	If strerror() uses sys_errlist, the pointer might change for different
-	 *	errno values, so we don't check to see if it varies within the thread.
+	 * If strerror() uses sys_errlist, the pointer might change for
+	 * different errno values, so we don't check to see if it varies
+	 * within the thread.
 	 */
+#endif
 
+#ifndef HAVE_GETPWUID_R
 	passwd_p2 = getpwuid(2);
 	p = getpwuid(3);
 	if (passwd_p2 != p)
 	{
 		printf("Your getpwuid() changes the static memory area between calls\n");
-		passwd_p2 = NULL;	/* force thread-safe failure report */
+		passwd_p2 = NULL;		/* force thread-safe failure report */
 	}
+#endif
 
+#if !defined(HAVE_GETADDRINFO) && !defined(HAVE_GETHOSTBYNAME_R)
 	/* threads do this in opposite order */
 	hostent_p2 = gethostbyname("localhost");
 	p = gethostbyname(myhostname);
 	if (hostent_p2 != p)
 	{
 		printf("Your gethostbyname() changes the static memory area between calls\n");
-		hostent_p2 = NULL;	/* force thread-safe failure report */
+		hostent_p2 = NULL;		/* force thread-safe failure report */
 	}
+#endif
 
 	thread2_done = 1;
 	pthread_mutex_lock(&init_mutex);	/* wait for parent to test */
-- 
GitLab