Skip to content
Snippets Groups Projects
Commit 66b42d30 authored by Bruce Momjian's avatar Bruce Momjian
Browse files

Improve thread test program. Test only functions that need testing.

parent fc7fd501
No related branches found
No related tags found
No related merge requests found
......@@ -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)
......
......@@ -6,7 +6,7 @@
* 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.
......@@ -36,31 +36,37 @@
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;
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;
bool getpwuid_threadsafe = false;
bool strerror_threadsafe = false;
bool platform_is_threadsafe = true;
#endif
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;
......@@ -71,16 +77,13 @@ int main(int argc, char *argv[])
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);
}
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);
......@@ -89,84 +92,95 @@ defines to your template/$port file before compiling this program.\n\n"
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"
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
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 */
......@@ -177,10 +191,10 @@ void func_call_1(void) {
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)
......@@ -193,12 +207,17 @@ void func_call_1(void) {
}
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)
......@@ -206,7 +225,9 @@ void func_call_1(void) {
printf("Your getpwuid() changes the static memory area between calls\n");
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");
......@@ -215,6 +236,7 @@ void func_call_1(void) {
printf("Your gethostbyname() changes the static memory area between calls\n");
hostent_p1 = NULL; /* force thread-safe failure report */
}
#endif
thread1_done = 1;
pthread_mutex_lock(&init_mutex); /* wait for parent to test */
......@@ -222,8 +244,14 @@ void func_call_1(void) {
}
void func_call_2(void) {
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 */
......@@ -232,10 +260,10 @@ void func_call_2(void) {
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)
......@@ -248,12 +276,17 @@ void func_call_2(void) {
}
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)
......@@ -261,7 +294,9 @@ void func_call_2(void) {
printf("Your getpwuid() changes the static memory area between calls\n");
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);
......@@ -270,6 +305,7 @@ void func_call_2(void) {
printf("Your gethostbyname() changes the static memory area between calls\n");
hostent_p2 = NULL; /* force thread-safe failure report */
}
#endif
thread2_done = 1;
pthread_mutex_lock(&init_mutex); /* wait for parent to test */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment