1
0
mirror of https://github.com/postgres/postgres.git synced 2025-09-02 04:21:28 +03:00

Move thread_test directory from /tools to /test so source-only tarballs

have the directory for the configure test.
This commit is contained in:
Bruce Momjian
2006-02-04 01:00:02 +00:00
parent 0e04982e78
commit 9e66c3e6fe
6 changed files with 14 additions and 35 deletions

View File

@@ -1,24 +0,0 @@
#-------------------------------------------------------------------------
#
# Makefile for tools/thread
#
# Copyright (c) 2003-2005, PostgreSQL Global Development Group
#
# $PostgreSQL: pgsql/src/tools/thread/Makefile,v 1.8 2005/01/01 20:44:34 tgl Exp $
#
#-------------------------------------------------------------------------
subdir = src/tools/thread
top_builddir = ../../..
include $(top_builddir)/src/Makefile.global
override CFLAGS += $(PTHREAD_CFLAGS)
all: thread_test
thread_test: thread_test.o
# no need for $LIBS, might not be compiled yet
$(CC) $(CFLAGS) $(LDFLAGS) $^ $(PTHREAD_LIBS) -o $@
clean distclean maintainer-clean:
rm -f thread_test$(X) thread_test.o

View File

@@ -1,49 +0,0 @@
This program should be run by developers wishing to enable threading on
new platforms.
Run thread_test program to determine if your native libc functions are
thread-safe, or if we should use *_r functions or thread locking.
To use this program, you must:
o run "configure --enable-thread-safety"
o compile the main source tree
o compile and run this program
If your platform requires special thread flags that are not tested by
/config/acx_pthread.m4, add PTHREAD_CFLAGS and PTHREAD_LIBS defines to
your template/${port} file.
Windows Systems
===============
Windows systems do not vary in their thread-safeness in the same way that
other systems might, nor do they generally have pthreads installed, hence
on Windows this test is skipped by the configure program (pthreads is
required by the test program, but not PostgreSQL itself). If you do wish
to test your system however, you can do so as follows:
1) Install pthreads in you Mingw/Msys environment. You can download pthreads
from ftp://sources.redhat.com/pub/pthreads-win32/.
2) Build the test program:
gcc -o thread_test.exe \
-D_REENTRANT \
-D_THREAD_SAFE \
-D_POSIX_PTHREAD_SEMANTICS \
-I../../../src/include/port/win32 \
thread_test.c \
-lwsock32 \
-lpthreadgc2
3) Run thread_test.exe. You should see output like:
dpage@PC30:/cvs/pgsql/src/tools/thread$ ./thread_test
Your GetLastError() is thread-safe.
Your system uses strerror() which is thread-safe.
getpwuid_r()/getpwuid() are not applicable to Win32 platforms.
Your system uses gethostbyname which is thread-safe.
Your platform is thread-safe.

View File

@@ -1,469 +0,0 @@
/*-------------------------------------------------------------------------
*
* test_thread_funcs.c
* libc thread test program
*
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/tools/thread/thread_test.c,v 1.41 2005/10/15 02:49:52 momjian Exp $
*
* This program tests to see if your standard libc functions use
* pthread_setspecific()/pthread_getspecific() to be thread-safe.
* See src/port/thread.c for more details.
*
* This program first tests to see if each function returns a constant
* memory pointer within the same thread, then, assuming it does, tests
* to see if the pointers are different for different threads. If they
* are, the function is thread-safe.
*
*-------------------------------------------------------------------------
*/
#if !defined(IN_CONFIGURE) && !defined(WIN32)
#include "postgres.h"
#else
/* From src/include/c.h" */
#ifndef bool
typedef char bool;
#endif
#ifndef true
#define true ((bool) 1)
#endif
#ifndef false
#define false ((bool) 0)
#endif
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/types.h>
#include <pwd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
/******************************************************************
* Windows Hacks
*****************************************************************/
#ifdef WIN32
#define MAXHOSTNAMELEN 63
#include <winsock2.h>
int mkstemp(char *template);
int
mkstemp(char *template)
{
FILE *foo;
mktemp(template);
foo = fopen(template, "rw");
if (!foo)
return -1;
else
return (int) foo;
}
#endif
/******************************************************************
* End Windows Hacks
*****************************************************************/
/* Test for POSIX.1c 2-arg sigwait() and fail on single-arg version */
#include <signal.h>
int sigwait(const sigset_t *set, int *sig);
#if !defined(ENABLE_THREAD_SAFETY) && !defined(IN_CONFIGURE) && !(defined(WIN32))
int
main(int argc, char *argv[])
{
fprintf(stderr, "This PostgreSQL build does not support threads.\n");
fprintf(stderr, "Perhaps rerun 'configure' using '--enable-thread-safety'.\n");
return 1;
}
#else
/* This must be down here because this is the code that uses threads. */
#include <pthread.h>
static void func_call_1(void);
static void func_call_2(void);
#ifdef WIN32
#define TEMP_FILENAME_1 "thread_test.1.XXXXXX"
#define TEMP_FILENAME_2 "thread_test.2.XXXXXX"
#else
#define TEMP_FILENAME_1 "/tmp/thread_test.1.XXXXXX"
#define TEMP_FILENAME_2 "/tmp/thread_test.2.XXXXXX"
#endif
static char *temp_filename_1;
static char *temp_filename_2;
static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;
static volatile int thread1_done = 0;
static volatile int thread2_done = 0;
static volatile int errno1_set = 0;
static volatile int errno2_set = 0;
#ifndef HAVE_STRERROR_R
static char *strerror_p1;
static char *strerror_p2;
static bool strerror_threadsafe = false;
#endif
#ifndef WIN32
#ifndef HAVE_GETPWUID_R
static struct passwd *passwd_p1;
static struct passwd *passwd_p2;
static bool getpwuid_threadsafe = false;
#endif
#endif
#if !defined(HAVE_GETADDRINFO) && !defined(HAVE_GETHOSTBYNAME_R)
static struct hostent *hostent_p1;
static struct hostent *hostent_p2;
static char myhostname[MAXHOSTNAMELEN];
static bool gethostbyname_threadsafe = false;
#endif
static bool platform_is_threadsafe = true;
int
main(int argc, char *argv[])
{
pthread_t thread1,
thread2;
int fd;
#ifdef WIN32
WSADATA wsaData;
int err;
#endif
if (argc > 1)
{
fprintf(stderr, "Usage: %s\n", argv[0]);
return 1;
}
#ifdef IN_CONFIGURE
/* Send stdout to 'config.log' */
close(1);
dup(5);
#endif
#ifdef WIN32
err = WSAStartup(MAKEWORD(1, 1), &wsaData);
if (err != 0)
{
fprintf(stderr, "Cannot start the network subsystem - %d**\nexiting\n", err);
exit(1);
}
#endif
/* Make temp filenames, might not have strdup() */
temp_filename_1 = malloc(strlen(TEMP_FILENAME_1) + 1);
strcpy(temp_filename_1, TEMP_FILENAME_1);
fd = mkstemp(temp_filename_1);
close(fd);
temp_filename_2 = malloc(strlen(TEMP_FILENAME_2) + 1);
strcpy(temp_filename_2, TEMP_FILENAME_2);
fd = mkstemp(temp_filename_2);
close(fd);
#if !defined(HAVE_GETADDRINFO) && !defined(HAVE_GETHOSTBYNAME_R)
if (gethostname(myhostname, MAXHOSTNAMELEN) != 0)
{
fprintf(stderr, "Can not get local hostname **\nexiting\n");
exit(1);
}
#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);
while (thread1_done == 0 || thread2_done == 0)
sched_yield(); /* if this is a portability problem, remove it */
#ifdef WIN32
printf("Your GetLastError() is thread-safe.\n");
#else
printf("Your errno is thread-safe.\n");
#endif
#ifndef HAVE_STRERROR_R
if (strerror_p1 != strerror_p2)
strerror_threadsafe = true;
#endif
#ifndef WIN32
#ifndef HAVE_GETPWUID_R
if (passwd_p1 != passwd_p2)
getpwuid_threadsafe = true;
#endif
#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);
#ifdef HAVE_STRERROR_R
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
{
printf("not thread-safe. **\n");
platform_is_threadsafe = false;
}
#endif
#ifndef WIN32
#ifdef HAVE_GETPWUID_R
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
{
printf("not thread-safe. **\n");
platform_is_threadsafe = false;
}
#endif
#else
printf("getpwuid_r()/getpwuid() are not applicable to Win32 platforms.\n");
#endif
#ifdef HAVE_GETADDRINFO
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(); it does not need gethostbyname().\n");
#else
printf("Your system uses gethostbyname which is ");
if (gethostbyname_threadsafe)
printf("thread-safe.\n");
else
{
printf("not thread-safe. **\n");
platform_is_threadsafe = false;
}
#endif
#endif
if (platform_is_threadsafe)
{
printf("\nYour platform is thread-safe.\n");
return 0;
}
else
{
printf("\n** YOUR PLATFORM IS NOT THREAD-SAFE. **\n");
return 1;
}
}
static void
func_call_1(void)
{
#if !defined(HAVE_GETPWUID_R) || \
(!defined(HAVE_GETADDRINFO) && \
!defined(HAVE_GETHOSTBYNAME_R))
void *p;
#endif
#ifdef WIN32
HANDLE h1;
HANDLE h2;
#endif
unlink(temp_filename_1);
/* create, then try to fail on exclusive create open */
#ifdef WIN32
h1 = CreateFile(temp_filename_1, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, 0, NULL);
h2 = CreateFile(temp_filename_1, GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, NULL);
if (h1 == INVALID_HANDLE_VALUE || GetLastError() != ERROR_FILE_EXISTS)
#else
if (open(temp_filename_1, O_RDWR | O_CREAT, 0600) < 0 ||
open(temp_filename_1, O_RDWR | O_CREAT | O_EXCL, 0600) >= 0)
#endif
{
#ifdef WIN32
fprintf(stderr, "Could not create file in current directory or\n");
fprintf(stderr, "Could not generate failure for create file in current directory **\nexiting\n");
#else
fprintf(stderr, "Could not create file in /tmp or\n");
fprintf(stderr, "Could not generate failure for create file in /tmp **\nexiting\n");
#endif
exit(1);
}
/*
* 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();
#ifdef WIN32
if (GetLastError() != ERROR_FILE_EXISTS)
#else
if (errno != EEXIST)
#endif
{
#ifdef WIN32
fprintf(stderr, "GetLastError() not thread-safe **\nexiting\n");
#else
fprintf(stderr, "errno not thread-safe **\nexiting\n");
#endif
unlink(temp_filename_1);
exit(1);
}
unlink(temp_filename_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.
*/
#endif
#ifndef WIN32
#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 */
}
#endif
#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 */
}
#endif
thread1_done = 1;
pthread_mutex_lock(&init_mutex); /* wait for parent to test */
pthread_mutex_unlock(&init_mutex);
}
static void
func_call_2(void)
{
#if !defined(HAVE_GETPWUID_R) || \
(!defined(HAVE_GETADDRINFO) && \
!defined(HAVE_GETHOSTBYNAME_R))
void *p;
#endif
unlink(temp_filename_2);
/* open non-existant file */
#ifdef WIN32
CreateFile(temp_filename_2, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if (GetLastError() != ERROR_FILE_NOT_FOUND)
#else
if (open(temp_filename_2, O_RDONLY, 0600) >= 0)
#endif
{
fprintf(stderr, "Read-only open succeeded without create **\nexiting\n");
exit(1);
}
/*
* 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();
#ifdef WIN32
if (GetLastError() != ENOENT)
#else
if (errno != ENOENT)
#endif
{
#ifdef WIN32
fprintf(stderr, "GetLastError() not thread-safe **\nexiting\n");
#else
fprintf(stderr, "errno not thread-safe **\nexiting\n");
#endif
unlink(temp_filename_2);
exit(1);
}
unlink(temp_filename_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.
*/
#endif
#ifndef WIN32
#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 */
}
#endif
#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 */
}
#endif
thread2_done = 1;
pthread_mutex_lock(&init_mutex); /* wait for parent to test */
pthread_mutex_unlock(&init_mutex);
}
#endif /* !ENABLE_THREAD_SAFETY && !IN_CONFIGURE */