Add thread.c and linkage - Mailing list pgsql-patches

From Bruce Momjian
Subject Add thread.c and linkage
Date
Msg-id 200306141435.h5EEZHC12739@candle.pha.pa.us
Whole thread Raw
Responses Re: Add thread.c and linkage
List pgsql-patches
Here is a new file, threads.c, which implements the functions needed for
libpq threading.

One tricky part was to add the threading flags to the compile of just
thread.c.  I used:

    # compile this with thread flags
    thread.o: thread.c
          $(CC) $(CFLAGS) $(THREAD_CFLAGS) -c thread.c


I assume that is the correct way to do it.

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073
Index: configure
===================================================================
RCS file: /cvsroot/pgsql-server/configure,v
retrieving revision 1.270
diff -c -c -r1.270 configure
*** configure    13 Jun 2003 23:10:04 -0000    1.270
--- configure    14 Jun 2003 14:12:34 -0000
***************
*** 2824,2830 ****

    case $withval in
      yes)
!       :
        ;;
      no)
        :
--- 2824,2834 ----

    case $withval in
      yes)
!
! cat >>confdefs.h <<\_ACEOF
! #define USE_THREADS 1
! _ACEOF
!
        ;;
      no)
        :
***************
*** 2841,2846 ****
--- 2845,2851 ----

  fi;

+
  echo "$as_me:$LINENO: result: $with_threads" >&5
  echo "${ECHO_T}$with_threads" >&6

***************
*** 3899,3907 ****
              # these require no special flags or libraries
              ;;
          freebsd2*|freebsd3*|freebsd4*) THREAD_CFLAGS="-pthread" ;;
!         freebsd*) THREAD_LIBS="-lc_r" ;;
!         linux*) THREAD_LIBS="-lpthread"
!             THREAD_CFLAGS="-D_REENTRANT" ;;
          *)
              # other operating systems might fail because they have pthread.h but need
              # special libs we don't know about yet.
--- 3904,3915 ----
              # these require no special flags or libraries
              ;;
          freebsd2*|freebsd3*|freebsd4*) THREAD_CFLAGS="-pthread" ;;
!         freebsd*)
!             THREAD_LIBS="-lc_r"
!             ;;
!         linux*) THREAD_CFLAGS="-D_REENTRANT -D_THREAD_SAFE -D_POSIX_PTHREAD_SEMANTICS"
!             THREAD_LIBS="-lpthread"
!             ;;
          *)
              # other operating systems might fail because they have pthread.h but need
              # special libs we don't know about yet.
***************
*** 3918,3924 ****
  or libraries required for threading support.
  " >&2;}
     { (exit 1); exit 1; }; }
!     esac
  fi


--- 3926,3932 ----
  or libraries required for threading support.
  " >&2;}
     { (exit 1); exit 1; }; }
! esac
  fi


***************
*** 12818,12823 ****
--- 12826,12922 ----
  fi


+ #
+ # Check for re-entrant versions of certain functions
+ #
+ # Include special flags if required
+ #
+ _CFLAGS="$CFLAGS"
+ _LIB="$LIBS"
+ CFLAGS="$CFLAGS $TREAD_CFLAGS"
+ LIBS="$LIBS $THREAD_LIBS"
+
+
+
+ for ac_func in strerror_r getpwuid_r gethostbyname_r
+ do
+ as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ echo "$as_me:$LINENO: checking for $ac_func" >&5
+ echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
+ if eval "test \"\${$as_ac_var+set}\" = set"; then
+   echo $ECHO_N "(cached) $ECHO_C" >&6
+ else
+   cat >conftest.$ac_ext <<_ACEOF
+ #line $LINENO "configure"
+ #include "confdefs.h"
+ /* System header to define __stub macros and hopefully few prototypes,
+     which can conflict with char $ac_func (); below.  */
+ #include <assert.h>
+ /* Override any gcc2 internal prototype to avoid an error.  */
+ #ifdef __cplusplus
+ extern "C"
+ #endif
+ /* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+ char $ac_func ();
+ char (*f) ();
+
+ #ifdef F77_DUMMY_MAIN
+ #  ifdef __cplusplus
+      extern "C"
+ #  endif
+    int F77_DUMMY_MAIN() { return 1; }
+ #endif
+ int
+ main ()
+ {
+ /* The GNU C library defines this for functions which it implements
+     to always fail with ENOSYS.  Some functions are actually named
+     something starting with __ and the normal name is an alias.  */
+ #if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+ choke me
+ #else
+ f = $ac_func;
+ #endif
+
+   ;
+   return 0;
+ }
+ _ACEOF
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+   (eval $ac_link) 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); } &&
+          { ac_try='test -s conftest$ac_exeext'
+   { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+   (eval $ac_try) 2>&5
+   ac_status=$?
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
+   (exit $ac_status); }; }; then
+   eval "$as_ac_var=yes"
+ else
+   echo "$as_me: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ eval "$as_ac_var=no"
+ fi
+ rm -f conftest.$ac_objext conftest$ac_exeext conftest.$ac_ext
+ fi
+ echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
+ echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
+ if test `eval echo '${'$as_ac_var'}'` = yes; then
+   cat >>confdefs.h <<_ACEOF
+ #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+ _ACEOF
+
+ fi
+ done
+
+ CFLAGS="$_CFLAGS"
+ LIB="$_LIBS"
+
+

  # This test makes sure that run tests work at all.  Sometimes a shared
  # library is found by the linker, but the runtime linker can't find it.
***************
*** 17603,17610 ****
  s,@with_rendezvous@,$with_rendezvous,;t t
  s,@with_openssl@,$with_openssl,;t t
  s,@ELF_SYS@,$ELF_SYS,;t t
- s,@THREAD_LIBS@,$THREAD_LIBS,;t t
  s,@THREAD_CFLAGS@,$THREAD_CFLAGS,;t t
  s,@AWK@,$AWK,;t t
  s,@FLEX@,$FLEX,;t t
  s,@FLEXFLAGS@,$FLEXFLAGS,;t t
--- 17702,17709 ----
  s,@with_rendezvous@,$with_rendezvous,;t t
  s,@with_openssl@,$with_openssl,;t t
  s,@ELF_SYS@,$ELF_SYS,;t t
  s,@THREAD_CFLAGS@,$THREAD_CFLAGS,;t t
+ s,@THREAD_LIBS@,$THREAD_LIBS,;t t
  s,@AWK@,$AWK,;t t
  s,@FLEX@,$FLEX,;t t
  s,@FLEXFLAGS@,$FLEXFLAGS,;t t
Index: configure.in
===================================================================
RCS file: /cvsroot/pgsql-server/configure.in,v
retrieving revision 1.261
diff -c -c -r1.261 configure.in
*** configure.in    13 Jun 2003 23:10:07 -0000    1.261
--- configure.in    14 Jun 2003 14:12:36 -0000
***************
*** 323,329 ****
  # Enable libpq to be thread-safe
  #
  AC_MSG_CHECKING([allow threaded libpq])
! PGAC_ARG_BOOL(with, threads, no, [  --with-threads          allow libpq to be thread-safe])
  AC_MSG_RESULT([$with_threads])
  AC_SUBST(with_threads)

--- 323,331 ----
  # Enable libpq to be thread-safe
  #
  AC_MSG_CHECKING([allow threaded libpq])
! PGAC_ARG_BOOL(with, threads, no, [  --with-threads          allow libpq to be thread-safe],
!               [AC_DEFINE([USE_THREADS], 1, [Define to 1 to build libpq with threads. (--with-threads)])])
!
  AC_MSG_RESULT([$with_threads])
  AC_SUBST(with_threads)

***************
*** 559,567 ****
              # these require no special flags or libraries
              ;;
          freebsd2*|freebsd3*|freebsd4*) THREAD_CFLAGS="-pthread" ;;
!         freebsd*) THREAD_LIBS="-lc_r" ;;
!         linux*) THREAD_LIBS="-lpthread"
!             THREAD_CFLAGS="-D_REENTRANT" ;;
          *)
              # other operating systems might fail because they have pthread.h but need
              # special libs we don't know about yet.
--- 561,572 ----
              # these require no special flags or libraries
              ;;
          freebsd2*|freebsd3*|freebsd4*) THREAD_CFLAGS="-pthread" ;;
!         freebsd*)
!             THREAD_LIBS="-lc_r"
!             ;;
!         linux*) THREAD_CFLAGS="-D_REENTRANT -D_THREAD_SAFE -D_POSIX_PTHREAD_SEMANTICS"
!             THREAD_LIBS="-lpthread"
!             ;;
          *)
              # other operating systems might fail because they have pthread.h but need
              # special libs we don't know about yet.
***************
*** 571,580 ****
  so it can be added to the next release.  Report any compile or link flags,
  or libraries required for threading support.
  ])
!     esac
  fi
- AC_SUBST(THREAD_LIBS)
  AC_SUBST(THREAD_CFLAGS)

  #
  # Assignments
--- 576,585 ----
  so it can be added to the next release.  Report any compile or link flags,
  or libraries required for threading support.
  ])
! esac
  fi
  AC_SUBST(THREAD_CFLAGS)
+ AC_SUBST(THREAD_LIBS)

  #
  # Assignments
***************
*** 982,987 ****
--- 987,1006 ----
                 [AC_MSG_ERROR([neither atexit() nor on_exit() found])])])

  AC_FUNC_FSEEKO
+
+ #
+ # Check for re-entrant versions of certain functions
+ #
+ # Include special flags if required
+ #
+ _CFLAGS="$CFLAGS"
+ _LIB="$LIBS"
+ CFLAGS="$CFLAGS $TREAD_CFLAGS"
+ LIBS="$LIBS $THREAD_LIBS"
+ AC_CHECK_FUNCS([strerror_r getpwuid_r gethostbyname_r])
+ CFLAGS="$_CFLAGS"
+ LIB="$_LIBS"
+


  # This test makes sure that run tests work at all.  Sometimes a shared
Index: src/Makefile.global.in
===================================================================
RCS file: /cvsroot/pgsql-server/src/Makefile.global.in,v
retrieving revision 1.163
diff -c -c -r1.163 Makefile.global.in
*** src/Makefile.global.in    27 May 2003 16:36:50 -0000    1.163
--- src/Makefile.global.in    14 Jun 2003 14:12:43 -0000
***************
*** 121,126 ****
--- 121,127 ----
  #
  # Records the choice of the various --enable-xxx and --with-xxx options.

+ with_threads    = @with_threads@
  with_java    = @with_java@
  with_perl    = @with_perl@
  with_python    = @with_python@
***************
*** 340,346 ****
  #
  # substitute implementations of the C library

! LIBOBJS = @LIBOBJS@ path.o

  ifneq (,$(LIBOBJS))
  LIBS += -lpgport
--- 341,347 ----
  #
  # substitute implementations of the C library

! LIBOBJS = @LIBOBJS@ path.o threads.o

  ifneq (,$(LIBOBJS))
  LIBS += -lpgport
Index: src/include/pg_config.h.in
===================================================================
RCS file: /cvsroot/pgsql-server/src/include/pg_config.h.in,v
retrieving revision 1.51
diff -c -c -r1.51 pg_config.h.in
*** src/include/pg_config.h.in    13 Jun 2003 23:10:08 -0000    1.51
--- src/include/pg_config.h.in    14 Jun 2003 14:12:45 -0000
***************
*** 121,126 ****
--- 121,129 ----
  /* Define to 1 if you have the `getaddrinfo' function. */
  #undef HAVE_GETADDRINFO

+ /* Define to 1 if you have the `gethostbyname_r' function. */
+ #undef HAVE_GETHOSTBYNAME_R
+
  /* Define to 1 if you have the `gethostname' function. */
  #undef HAVE_GETHOSTNAME

***************
*** 136,141 ****
--- 139,147 ----
  /* Define to 1 if you have the `getpeereid' function. */
  #undef HAVE_GETPEEREID

+ /* Define to 1 if you have the `getpwuid_r' function. */
+ #undef HAVE_GETPWUID_R
+
  /* Define to 1 if you have the `getrusage' function. */
  #undef HAVE_GETRUSAGE

***************
*** 375,380 ****
--- 381,389 ----
  /* Define to 1 if you have the `strerror' function. */
  #undef HAVE_STRERROR

+ /* Define to 1 if you have the `strerror_r' function. */
+ #undef HAVE_STRERROR_R
+
  /* Define to 1 if cpp supports the ANSI # stringizing operator. */
  #undef HAVE_STRINGIZE

***************
*** 578,583 ****
--- 587,595 ----

  /* Define to select SysV-style shared memory. */
  #undef USE_SYSV_SHARED_MEMORY
+
+ /* Define to 1 to build libpq with threads. (--with-threads) */
+ #undef USE_THREADS

  /* Define to select unnamed POSIX semaphores. */
  #undef USE_UNNAMED_POSIX_SEMAPHORES
Index: src/include/port.h
===================================================================
RCS file: /cvsroot/pgsql-server/src/include/port.h,v
retrieving revision 1.6
diff -c -c -r1.6 port.h
*** src/include/port.h    12 Jun 2003 08:15:29 -0000    1.6
--- src/include/port.h    14 Jun 2003 14:12:45 -0000
***************
*** 11,16 ****
--- 11,20 ----
   *-------------------------------------------------------------------------
   */

+ /* for thread.c */
+ #include <pwd.h>
+ #include <netdb.h>
+
  /* Portable path handling for Unix/Win32 */
  bool is_absolute_path(const char *filename);
  char *first_path_separator(const char *filename);
***************
*** 98,100 ****
--- 102,116 ----
  #ifndef HAVE_SRANDOM
  extern void srandom(unsigned int seed);
  #endif
+
+ /* thread.h */
+ extern char *pqStrerror(int errnum, char *strerrbuf, size_t buflen);
+
+ extern int pqGetpwuid(uid_t uid, struct passwd *resultbuf, char *buffer,
+               size_t buflen, struct passwd **result);
+
+ extern int pqGethostbyname(const char *name,
+                struct hostent *resbuf,
+                char *buf, size_t buflen,
+                struct hostent **result,
+                int *herrno);
Index: src/interfaces/libpq/Makefile
===================================================================
RCS file: /cvsroot/pgsql-server/src/interfaces/libpq/Makefile,v
retrieving revision 1.81
diff -c -c -r1.81 Makefile
*** src/interfaces/libpq/Makefile    12 Jun 2003 17:31:50 -0000    1.81
--- src/interfaces/libpq/Makefile    14 Jun 2003 14:12:46 -0000
***************
*** 23,29 ****
  OBJS= fe-auth.o fe-connect.o fe-exec.o fe-misc.o fe-print.o fe-lobj.o \
        fe-protocol2.o fe-protocol3.o pqexpbuffer.o pqsignal.o fe-secure.o \
        dllist.o md5.o ip.o wchar.o encnames.o \
!       $(filter crypt.o getaddrinfo.o inet_aton.o snprintf.o strerror.o path.o, $(LIBOBJS))


  # Add libraries that libpq depends (or might depend) on into the
--- 23,29 ----
  OBJS= fe-auth.o fe-connect.o fe-exec.o fe-misc.o fe-print.o fe-lobj.o \
        fe-protocol2.o fe-protocol3.o pqexpbuffer.o pqsignal.o fe-secure.o \
        dllist.o md5.o ip.o wchar.o encnames.o \
!       $(filter crypt.o getaddrinfo.o inet_aton.o snprintf.o strerror.o path.o threads.o, $(LIBOBJS))


  # Add libraries that libpq depends (or might depend) on into the
***************
*** 46,53 ****
  # For port modules, this only happens if configure decides the module
  # is needed (see filter hack in OBJS, above).

! crypt.c getaddrinfo.c inet_aton.c snprintf.c strerror.c path.c: %.c : $(top_srcdir)/src/port/%.c
      rm -f $@ && $(LN_S) $< .

  dllist.c: $(backend_src)/lib/dllist.c
      rm -f $@ && $(LN_S) $< .
--- 46,57 ----
  # For port modules, this only happens if configure decides the module
  # is needed (see filter hack in OBJS, above).

! crypt.c getaddrinfo.c inet_aton.c snprintf.c strerror.c path.c threads.c: %.c : $(top_srcdir)/src/port/%.c
      rm -f $@ && $(LN_S) $< .
+
+ # compile this with thread flags
+ thread.o: thread.c
+     $(CC) $(CFLAGS) $(THREAD_CFLAGS) -c thread.c

  dllist.c: $(backend_src)/lib/dllist.c
      rm -f $@ && $(LN_S) $< .
Index: src/port/Makefile
===================================================================
RCS file: /cvsroot/pgsql-server/src/port/Makefile,v
retrieving revision 1.3
diff -c -c -r1.3 Makefile
*** src/port/Makefile    27 Jul 2002 20:10:05 -0000    1.3
--- src/port/Makefile    14 Jun 2003 14:12:47 -0000
***************
*** 22,26 ****
--- 22,29 ----
  libpgport.a: $(LIBOBJS)
      $(AR) crs $@ $^

+ thread.o: thread.c
+     $(CC) $(CFLAGS) $(THREAD_CFLAGS) -c thread.c
+
  clean distclean maintainer-clean:
      rm -f libpgport.a $(LIBOBJS)
/*-------------------------------------------------------------------------
 *
 * threads.c
 *
 *          Prototypes and macros around system calls, used to help make
 *          threaded libraries reentrant and safe to use from threaded applications.
 *
 * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
 *
 * $Id:$
 *
 *-------------------------------------------------------------------------
 */

#include "postgres.h"

/*
 * Wrapper around strerror and strerror_r to use the former if it is
 * available and also return a more useful value (the error string).
 */
char *
pqStrerror(int errnum, char *strerrbuf, size_t buflen)
{
#if defined(USE_THREADS) && defined(HAVE_STRERROR_R)
    /* reentrant strerror_r is available */
    /* some early standards had strerror_r returning char * */
    strerror_r(errnum, strerrbuf, buflen);
    return (strerrbuf);
#else
    /* no strerror_r() available, just use strerror */
    return strerror(errnum);
#endif
}

/*
 * Wrapper around getpwuid() or getpwuid_r() to mimic POSIX getpwuid_r()
 * behaviour, if it is not available.
 */
int
pqGetpwuid(uid_t uid, struct passwd * resultbuf, char *buffer,
           size_t buflen, struct passwd ** result)
{
#if defined(USE_THREADS) && defined(HAVE_GETPWUID_R)
    /*
     * broken (well early POSIX draft) getpwuid_r() which returns 'struct
     * passwd *'
     */
    *result = getpwuid_r(uid, resultbuf, buffer, buflen);
#else
    /* no getpwuid_r() available, just use getpwuid() */
    *result = getpwuid(uid);
#endif
    return (*result == NULL) ? -1 : 0;
}

/*
 * Wrapper around gethostbyname() or gethostbyname_r() to mimic
 * POSIX gethostbyname_r() behaviour, if it is not available.
 */
int
pqGethostbyname(const char *name,
                struct hostent * resbuf,
                char *buf, size_t buflen,
                struct hostent ** result,
                int *herrno)
{
#if defined(USE_THREADS) && defined(HAVE_GETHOSTBYNAME_R)
    /*
     * broken (well early POSIX draft) gethostbyname_r() which returns
     * 'struct hostent *'
     */
    *result = gethostbyname_r(name, resbuf, buf, buflen, herrno);
    return (*result == NULL) ? -1 : 0;
#else
    /* no gethostbyname_r(), just use gethostbyname() */
    *result = gethostbyname(name);
    if (*result != NULL)
        return 0;
    else
    {
        *herrno = h_errno;
        return -1;
    }
#endif
}

pgsql-patches by date:

Previous
From: Bruce Momjian
Date:
Subject: Re: [HACKERS] PostgreSQL libraries - PThread Support, but
Next
From: Bruce Momjian
Date:
Subject: Re: [HACKERS] PostgreSQL libraries - PThread Support, but