Re: UPDATED UnixWare Threads Patch. - Mailing list pgsql-patches

From Bruce Momjian
Subject Re: UPDATED UnixWare Threads Patch.
Date
Msg-id 200308140525.h7E5Pmh18516@candle.pha.pa.us
Whole thread Raw
In response to Re: UPDATED UnixWare Threads Patch.  (Larry Rosenman <ler@lerctr.org>)
Responses Re: UPDATED UnixWare Threads Patch.  (Larry Rosenman <ler@lerctr.org>)
List pgsql-patches
OK, I have applied the attached patch.

Here is the comment I have added to the thread.c file:

/*
 *    Threading sometimes requires specially-named versions of functions
 *    that return data in static buffers, like strerror_r() instead of
 *    strerror().  Other operating systems use pthread_setspecific()
 *    and pthread_getspecific() internally to allow standard library
 *    functions to return static data to threaded applications.
 *
 *    Additional confusion exists because many operating systems that
 *    use pthread_setspecific/pthread_getspecific() also have *_r versions
 *    of standard library functions for compatibility with operating systems
 *    that require them.  However, internally, these *_r functions merely
 *    call the thread-safe standard library functions.
 *
 *    For example, BSD/OS 4.3 uses Bind 8.2.3 for getpwuid().  Internally,
 *    getpwuid() calls pthread_setspecific/pthread_getspecific() to return
 *    static data to the caller in a thread-safe manner.  However, BSD/OS
 *    also has getpwuid_r(), which merely calls getpwuid() and shifts
 *    around the arguments to match the getpwuid_r() function declaration.
 *    Therefore, while BSD/OS has getpwuid_r(), it isn't required.  It also
 *    doesn't have strerror_r(), so we can't fall back to only using *_r
 *    functions for threaded programs.
 *
 *    The current setup is to assume either all standard functions are
 *    thread-safe (NEED_REENTRANT_FUNC_NAMES=no), or the operating system
 *    requires reentrant function names (NEED_REENTRANT_FUNC_NAMES=yes).
 */

As an additional data point, here is a README comment from Bind 8.2.3:

  Thread Safety:

          It is possible for a thread safe program to be altered to call the
  underlying interface (rather than the standard getXbyY() stubs) and get some
  reentrance capabilities.  Note that the underlying libraries (which we call)
  are not all thread-safe, for example, the YP and DNS resolvers.  A lot more
  work will need to be done before we have full thread safety.  But we believe
  that the native API for this system does not impose any reentrancy problems.
  We don't use global or static variables anywhere except in the getXbyY() stubs.

Here is Bind's gethostbyname_r:

    HOST_R_RETURN
    gethostbyname_r(const char *name,  struct hostent *hptr, HOST_R_ARGS) {
        struct hostent *he = gethostbyname(name);

        HOST_R_ERRNO;

        if (he == NULL)
            return (HOST_R_BAD);

        return (copy_hostent(he, hptr, HOST_R_COPY));
    }

As you can see, it merely calls gethostbyname() and adjusts to return
the proper values.

I removed the pre-POSIX getpwuid_r function call and added the POSIX
one.  If we need the pre-POSIX one, we can add it with a configure
test, but I would rather find out if someone needs it first.  The
original thread patch that was posted had only the pre-POSIX version of
the function, and I am not sure why the didn't include the POSIX one
too, or use that instead of the pre-POSIX one.

There are also a few stylistic function declaration cleanups.

The unixware optimizer changes have already been applied.


---------------------------------------------------------------------------

Larry Rosenman wrote:
>
>
> --On Friday, August 08, 2003 18:56:45 -0500 Larry Rosenman <ler@lerctr.org>
> wrote:
>
> >
> >
> > Here is the updated UnixWare threads patch.  I need some help to set the
> > HAVE_POSIX_GETPWUID_R define from configure, but this will suffice for
> > now.
> >
> > This also includes my recommendation for the Compiler Bug issue.
> >
> > Please Apply, and if one of the configure guru's can help here, I'd be
> > most appreciative.
> Grr.  I'm an idiot, the following is a CORRECTED version, basically
> s/#elsif/#elif/
>
> Index: src/port/thread.c
> ===================================================================
> RCS file: /projects/cvsroot/pgsql-server/src/port/thread.c,v
> retrieving revision 1.2
> diff -u -r1.2 thread.c
> --- src/port/thread.c    8 Aug 2003 03:09:56 -0000    1.2
> +++ src/port/thread.c    9 Aug 2003 00:47:00 -0000
> @@ -40,13 +40,18 @@
>  pqGetpwuid(uid_t uid, struct passwd * resultbuf, char *buffer,
>             size_t buflen, struct passwd ** result)
>  {
> -#if defined(USE_THREADS) && defined(HAVE_GETPWUID_R)
> +#if defined(USE_THREADS) && defined(HAVE_GETPWUID_R) &&
> !defined(HAVE_POSIX_GETPWUID_R)
>
>      /*
>       * broken (well early POSIX draft) getpwuid_r() which returns 'struct
>       * passwd *'
>       */
>      *result = getpwuid_r(uid, resultbuf, buffer, buflen);
> +#elif defined(USE_THREADS) && defined(HAVE_GETPWUID_R) &&
> defined(HAVE_POSIX_GETPWUID_R)
> +    /*
> +     * SUSv2/POSIX getpwuid_r
> +     */
> +    return getpwuid_r(uid, resultbuf, buffer, buflen, result);
>  #else
>      /* no getpwuid_r() available, just use getpwuid() */
>      *result = getpwuid(uid);
> Index: src/template/unixware
> ===================================================================
> RCS file: /projects/cvsroot/pgsql-server/src/template/unixware,v
> retrieving revision 1.11
> diff -u -r1.11 unixware
> --- src/template/unixware    4 Sep 2002 22:54:18 -0000    1.11
> +++ src/template/unixware    9 Aug 2003 00:47:00 -0000
> @@ -1,5 +1,13 @@
> +SUPPORTS_THREADS=yes
>  if test "$GCC" = yes; then
> -  CFLAGS=-O2
> +  CFLAGS="-O2 -DHAVE_POSIX_GETPWUID_R"
> +  THREAD_CFLAGS="-pthread -D_REENTRANT"
> +  NEED_REENTRANT_FUNC_NAMES=yes
>  else
> -  CFLAGS='-O -K inline'
> +# the -Kno_host is temporary for a bug in the compiler.  See -hackers
> +# discussion on 7-8/Aug/2003.
> +# when the 7.1.3UP3 or later compiler is out, we can do a version check.
> +  CFLAGS='-O -Kinline,no_host  -DHAVE_POSIX_GETPWUID_R'
> +  THREAD_CFLAGS="-D_REENTRANT -K pthread -DHAVE_POSIX_GETPWUID_R"
> +  NEED_REENTRANT_FUNC_NAMES=yes
>  fi
>
> --
> Larry Rosenman                     http://www.lerctr.org/~ler
> Phone: +1 972-414-9812                 E-Mail: ler@lerctr.org
> US Mail: 1905 Steamboat Springs Drive, Garland, TX 75044-6749

[ Attachment, skipping... ]

>
> ---------------------------(end of broadcast)---------------------------
> TIP 4: Don't 'kill -9' the postmaster

--
  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: src/port/thread.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/port/thread.c,v
retrieving revision 1.2
diff -c -c -r1.2 thread.c
*** src/port/thread.c    8 Aug 2003 03:09:56 -0000    1.2
--- src/port/thread.c    14 Aug 2003 05:14:59 -0000
***************
*** 15,20 ****
--- 15,48 ----
  #include "postgres.h"

  /*
+  *    Threading sometimes requires specially-named versions of functions
+  *    that return data in static buffers, like strerror_r() instead of
+  *    strerror().  Other operating systems use pthread_setspecific()
+  *    and pthread_getspecific() internally to allow standard library
+  *    functions to return static data to threaded applications.
+  *
+  *    Additional confusion exists because many operating systems that
+  *    use pthread_setspecific/pthread_getspecific() also have *_r versions
+  *    of standard library functions for compatibility with operating systems
+  *    that require them.  However, internally, these *_r functions merely
+  *    call the thread-safe standard library functions.
+  *
+  *    For example, BSD/OS 4.3 uses Bind 8.2.3 for getpwuid().  Internally,
+  *    getpwuid() calls pthread_setspecific/pthread_getspecific() to return
+  *    static data to the caller in a thread-safe manner.  However, BSD/OS
+  *    also has getpwuid_r(), which merely calls getpwuid() and shifts
+  *    around the arguments to match the getpwuid_r() function declaration.
+  *    Therefore, while BSD/OS has getpwuid_r(), it isn't required.  It also
+  *    doesn't have strerror_r(), so we can't fall back to only using *_r
+  *    functions for threaded programs.
+  *
+  *    The current setup is to assume either all standard functions are
+  *    thread-safe (NEED_REENTRANT_FUNC_NAMES=no), or the operating system
+  *    requires reentrant function names (NEED_REENTRANT_FUNC_NAMES=yes).
+  */
+
+
+ /*
   * Wrapper around strerror and strerror_r to use the former if it is
   * available and also return a more useful value (the error string).
   */
***************
*** 34,52 ****

  /*
   * 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);
--- 62,81 ----

  /*
   * Wrapper around getpwuid() or getpwuid_r() to mimic POSIX getpwuid_r()
!  * behaviour, if it is not available or required.
   */
  int
! pqGetpwuid(uid_t uid, struct passwd *resultbuf, char *buffer,
!            size_t buflen, struct passwd **result)
  {
  #if defined(USE_THREADS) && defined(HAVE_GETPWUID_R)
      /*
!      * Early POSIX draft of getpwuid_r() returns 'struct passwd *'.
!      *    getpwuid_r(uid, resultbuf, buffer, buflen)
!      * Do we need to support it?  bjm 2003-08-14
       */
!     /* POSIX version */
!     getpwuid_r(uid, resultbuf, buffer, buflen, result);
  #else
      /* no getpwuid_r() available, just use getpwuid() */
      *result = getpwuid(uid);
***************
*** 56,68 ****

  /*
   * 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)
--- 85,97 ----

  /*
   * Wrapper around gethostbyname() or gethostbyname_r() to mimic
!  * POSIX gethostbyname_r() behaviour, if it is not available or required.
   */
  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)

pgsql-patches by date:

Previous
From: Bruce Momjian
Date:
Subject: Re: UPDATED UnixWare Threads Patch.
Next
From: Larry Rosenman
Date:
Subject: Re: UPDATED UnixWare Threads Patch.