Subject: bug#7073: threadlib vs. pthread modules

From: Bruno Haible <[email-masked]>
Date: Wed, 22 Sep 2010 17:18:43 +0200

Hi Paul,

> > You can do so by inserting
> >   gl_use_threads_default=no
> > in your configure.ac, before the invocations of gl_INIT_EARLY and gl_INIT.
> 
> Thanks, I didn't know that.  I tried it ...
> Also, it'd be helpful to document gl_use_threads_default.

Well, I did not know about it either, before you asked ;-) But it's more
future-proof to ask coreutils to define a particular macro, rather than to
set a specific variable to a specific value. The same approach as we
already use in m4/ansi-c++.m4. I'm changing threadlib.m4 as below.

> and found one minor glitch. 
> "configure" said "checking for multithread API to use... no"
> which might imply to the casual reader that the resulting coreutils
> would not use multiple threads anywhere.  How about appending
> "within threadlib" to that message?
> -  AC_MSG_CHECKING([for multithread API to use])
> +  AC_MSG_CHECKING([for multithread API to use within threadlib])

It's peculiar to coreutils that it uses both 'threadlib' and 'pthread'.
For other packages, like gettext, the change that you suggest would be
misleading. Therefore I think it should better be done in a local
override of m4/threadlib.m4 in coreutils (via a tiny .diff file).

> diff --git a/modules/gettext b/modules/gettext
> index cab538e..787f237 100644
> --- a/modules/gettext
> +++ b/modules/gettext
> @@ -38,6 +38,13 @@ gettext-h
>  havelib
>  
>  configure.ac:
> +# If your applications do not need gnulib to be multithread-safe,
> +# either because they don't use threads or because they carefully
> +# control which APIs are invoked while concurrent threads are running,
> +# then you can avoid some build-time hassles and run-time overhead by
> +# inserting:
> +#     gl_use_threads_default=no
> +# early in configure.ac, before the invocations of gl_INIT_EARLY and gl_INIT.
>  AM_GNU_GETTEXT([external])
>  AM_GNU_GETTEXT_VERSION([0.18.1])
>  

I don't see what this has to do with the gettext module. This belongs only
in the threadlib module.

A general throught about the 'threadlib' vs. 'pthread' modules:
  - The modules 'lock', 'tls', 'cond', 'thread', 'yield' attempt
    broad portability. They work well on MacOS X, mingw (even without
    pthreads-win32), Tru64, old Solaris, and others. But it does not
    provide the POSIX API.
  - The module 'pthread' provides the POSIX API, but don't work on older
    Unix systems nor mingw.

I imagine a way to get the best of both is to change the API of
'lock', 'tls', 'cond', 'thread', 'yield' so that it provides a nearly
POSIX API. I say "nearly", because for the locks, it will make things
much easier to have separate functions for recursive locks that for
normal locks/mutexes. And a similar difference will probably remain
with pthread_key_t - this type does not provide enough information
when threads are turned off.

Would you (in coreutils, sort) be willing to use such an API that is
slightly different from POSIX, but much closer to POSIX than
'lock', 'tls', 'cond', 'thread', 'yield' are now?

2010-09-22  Bruno Haible  <[email-masked]>

	threadlib: Allow the package to change the default to 'no'.
	* m4/threadlib.m4 (gl_THREADLIB_EARLY_BODY): When
	gl_THREADLIB_DEFAULT_NO is defined, change the default to 'no'.
	Reported by Paul Eggert.

--- m4/threadlib.m4.orig	Wed Sep 22 16:55:58 2010
+++ m4/threadlib.m4	Wed Sep 22 16:54:17 2010
@@ -1,4 +1,4 @@
-# threadlib.m4 serial 6 (gettext-0.18.2)
+# threadlib.m4 serial 7 (gettext-0.18.2)
 dnl Copyright (C) 2005-2010 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -9,6 +9,11 @@
 dnl gl_THREADLIB
 dnl ------------
 dnl Tests for a multithreading library to be used.
+dnl If the configure.ac contains a definition of the gl_THREADLIB_DEFAULT_NO
+dnl (it must be placed before the invocation of gl_THREADLIB_EARLY!), then the
+dnl default is 'no', otherwise it is system dependent. In both cases, the user
+dnl can change the choice through the options --enable-threads=choice or
+dnl --disable-threads.
 dnl Defines at most one of the macros USE_POSIX_THREADS, USE_SOLARIS_THREADS,
 dnl USE_PTH_THREADS, USE_WIN32_THREADS
 dnl Sets the variables LIBTHREAD and LTLIBTHREAD to the linker options for use
@@ -44,10 +49,12 @@
     [AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])],
     [AC_REQUIRE([AC_GNU_SOURCE])])
   dnl Check for multithreading.
-  m4_divert_text([DEFAULTS], [gl_use_threads_default=])
+  m4_ifdef([gl_THREADLIB_DEFAULT_NO],
+    [m4_divert_text([DEFAULTS], [gl_use_threads_default=no])],
+    [m4_divert_text([DEFAULTS], [gl_use_threads_default=])])
   AC_ARG_ENABLE([threads],
-AC_HELP_STRING([--enable-threads={posix|solaris|pth|win32}], [specify multithreading API])
-AC_HELP_STRING([--disable-threads], [build without multithread safety]),
+AC_HELP_STRING([--enable-threads={posix|solaris|pth|win32}], [specify multithreading API])m4_ifdef([gl_THREADLIB_DEFAULT_NO], [], [
+AC_HELP_STRING([--disable-threads], [build without multithread safety])]),
     [gl_use_threads=$enableval],
     [if test -n "$gl_use_threads_default"; then
        gl_use_threads="$gl_use_threads_default"