[RFC] Deprecate _REENTRANT and _THREAD_SAFE.

Message ID CALxWeYozGxUHi8wPhHd4fgx=DPtg4UG0UC2Znq7HfOd2JJxBmA@mail.gmail.com
State New, archived
Headers

Commit Message

Michael Kerrisk \(man-pages\) Dec. 8, 2016, 9:01 a.m. UTC
  On Tue, Dec 6, 2016 at 4:22 PM, Zack Weinberg <zackw@panix.com> wrote:
> For many years, the only effect of these macros has been to make
> unistd.h declare getlogin_r.  _POSIX_C_SOURCE >= 199506L also causes
> this function to be declared.  However, people who don't carefully
> read all the headers might be confused into thinking they need to
> define _REENTRANT for any threaded code (as was indeed the case a long
> time ago).
>
> Therefore, I propose to make _REENTRANT and _THREAD_SAFE into aliases
> for _POSIX_C_SOURCE=199506L, and issue a deprecation warning when a
> higher conformance level was not selected some other way.
> For instance, -std=c89 -D_REENTRANT will warn, but
> -std=c99 -D_POSIX_C_SOURCE=200809L -D_REENTRANT won't, and
> -D_REENTRANT all by itself also won't, because _DEFAULT_SOURCE implies
> _POSIX_C_SOURCE > 199506.  I could be persuaded to make that final
> case also warn.

On the assumption that this patch will be merged in some form, I've
queued the following change to feature_test_macros(7):

====

Cheers,

Michael
  

Comments

Zack Weinberg Dec. 8, 2016, 2:01 p.m. UTC | #1
On Thu, Dec 8, 2016 at 4:01 AM, Michael Kerrisk <mtk.manpages@gmail.com> wrote:
>
> On the assumption that this patch will be merged in some form, I've
> queued the following change to feature_test_macros(7):

I appreciate the vote of confidence, but please don't actually put
that into the manpages until the patch does get merged.  Also, some
corrections/clarifications:

> +Historically,
> +defining this macro exposed definitions of certain reentrant functions.

Historically, it was necessary to define this macro in all
multithreaded code.  Some C libraries may still require this.

> +However, already for many years this macro has had few effects,
> +and since glibc 2.3, no effects that were not also achieved by defining
> +.BR _POSIX_C_SOURCE
> +with a value of 199606L or greater.

However, glibc has been thread-safe by default for many years; since
glibc 2.3, the only effect of
.B _REENTRANT
has been to enable some of the same declarations enabled by defining
.B _POSIX_C_SOURCE
with a value of 199606L or later.

> +This macro is now deprecated; since glibc 2.25,
> +defining it has the same effect as defining
> +.BR _POSIX_C_SOURCE
> +with a value of 199606L or greater.

In glibc 2.25 and later,
.B _REENTRANT
is deprecated.  Defining it is equivalent to defining
.B _POSIX_C_SOURCE
with the value 199606L.  If a higher POSIX conformance level is
selected by any other means (such as
.B _POSIX_C_SOURCE
itself,
.BR _XOPEN_SOURCE ,
.BR _DEFAULT_SOURCE ,
or
.BR _GNU_SOURCE ),
then
.B _REENTRANT
has no effect.

(Perhaps there is a tighter way to write the markup?  Feel free to tweak.)

zw
  
Michael Kerrisk \(man-pages\) Dec. 9, 2016, 10:32 a.m. UTC | #2
Hello Zack,

On 12/08/2016 03:01 PM, Zack Weinberg wrote:
> On Thu, Dec 8, 2016 at 4:01 AM, Michael Kerrisk <mtk.manpages@gmail.com> wrote:
>>
>> On the assumption that this patch will be merged in some form, I've
>> queued the following change to feature_test_macros(7):
>
> I appreciate the vote of confidence, but please don't actually put
> that into the manpages until the patch does get merged.

I should perhaps have been clearer. By "queued" I meant the changes,
were not yet in "master"; just in a private branch.

And, by now, your patch has hit the repo, so I suppose we're good
for adding this documentation to nam-pages "master", right?

> Also, some
> corrections/clarifications:

There's nothing like queuing a bad patch to get someone to write a 
good patch 

>> +Historically,
>> +defining this macro exposed definitions of certain reentrant functions.
>
> Historically, it was necessary to define this macro in all
> multithreaded code.  

Okay. I did a little code spelunking and found the following:

1. In glibc 1.09 (tagged 1995-03-02 in the git history), __USE_REENTRANT,
   _THREAD_SAFE, and _REENTRANT do not appear.

2. In glibc-1.93 (tagged 1996-08-29 in the git history), __USE_REENTRANT
   governs the exposure of some "_r()" functions from about a dozen header 
   files. However, it is defined in <features.h> via

        #if defined (__USE_GNU) || defined (__USE_MISC)
        #define __USE_REENTRANT 1
        #endif
   
   _REENTRANT and _THREAD_SAFE solely govern declarations in <stdio.h>,
   where they expose declarations of a few "unlocked" stdio functions
   and use #define to redirect a few stdio function names
   to "locked" versions.

3. THREAD_SAFE and _REENTRANT first appear in the git logs
   1996-05-09.

4. About 9 months later, glibc 2.0.1 arrives on 1997-02-04
   (timestamp and tarball taken from https://ftp.gnu.org/gnu/libc/,
   since there is no tag in the git history; casual inspection of
   the logs suggests the glibc 2.0 release was about a week earlier.

   By now we have the following in <features.h>:

        #if defined _REENTRANT || defined _THREAD_SAFE
        #define __USE_REENTRANT 1
        #endif

  And _THREAD_SAFE, and _REENTRANT do not appear appear in other
  headers. However, by now, __USE_REENTRANT governs only the
  declarations of tmpnam_r() and getlogin_r()

In other words, the window of time where _REENTRANT and _THREAD_SAFE
did anything much in glibc was quite short, IIUC.

> Some C libraries may still require this.
>
>> +However, already for many years this macro has had few effects,
>> +and since glibc 2.3, no effects that were not also achieved by defining
>> +.BR _POSIX_C_SOURCE
>> +with a value of 199606L or greater.
>
> However, glibc has been thread-safe by default for many years; since
> glibc 2.3, the only effect of
> .B _REENTRANT
> has been to enable some of the same declarations enabled by defining
> .B _POSIX_C_SOURCE
> with a value of 199606L or later.
>
>> +This macro is now deprecated; since glibc 2.25,
>> +defining it has the same effect as defining
>> +.BR _POSIX_C_SOURCE
>> +with a value of 199606L or greater.
>
> In glibc 2.25 and later,
> .B _REENTRANT
> is deprecated.  Defining it is equivalent to defining
> .B _POSIX_C_SOURCE
> with the value 199606L.  If a higher POSIX conformance level is
> selected by any other means (such as
> .B _POSIX_C_SOURCE
> itself,
> .BR _XOPEN_SOURCE ,
> .BR _DEFAULT_SOURCE ,
> or
> .BR _GNU_SOURCE ),
> then
> .B _REENTRANT
> has no effect.
>
> (Perhaps there is a tighter way to write the markup?  Feel free to tweak.)

I'm fine with the markup as you gave it. I've taken the changes 
pretty much as you've given them here.

Cheers,

Michael
  
Zack Weinberg Dec. 9, 2016, 6:07 p.m. UTC | #3
On Fri, Dec 9, 2016 at 5:32 AM, Michael Kerrisk (man-pages)
<mtk.manpages@gmail.com> wrote:
>
> I should perhaps have been clearer. By "queued" I meant the changes,
> were not yet in "master"; just in a private branch.

Oh, OK.  Sorry for the misunderstanding.

> And, by now, your patch has hit the repo, so I suppose we're good
> for adding this documentation to nam-pages "master", right?

Yes, with two more notes ...

>>> +Historically,
>>> +defining this macro exposed definitions of certain reentrant functions.
>>
>> Historically, it was necessary to define this macro in all
>> multithreaded code.
>> Some C libraries may still require this.
>
> Okay. I did a little code spelunking and found the following:
...
> In other words, the window of time where _REENTRANT and _THREAD_SAFE
> did anything much in glibc was quite short, IIUC.

This is me not being clear enough.  I didn't mean to imply that this
was historically necessary _with glibc_, but that there did once exist
C libraries where it was necessary.  The ones I remember were
proprietary Unix vendor libcs from the mid-1990s.  You would get
completely unlocked stdio without _REENTRANT.

What I would like the text to indicate, is that this is not necessary
with current glibc but it might still be necessary for portable code,
and we don't know for sure which platforms are affected.  Maybe this
is clear enough as is? I'm not sure.

>>> +This macro is now deprecated; since glibc 2.25,
>>> +defining it has the same effect as defining
>>> +.BR _POSIX_C_SOURCE
>>> +with a value of 199606L or greater.
>>
>> In glibc 2.25 and later,
>> .B _REENTRANT
>> is deprecated.

And I've decided that glibc's not going to call these macros
"deprecated".  creature.texi says "obsolete", NEWS says "these
nonstandard feature selection macros are now compatibility synonyms
for _POSIX_C_SOURCE=199506L", and there are no warnings for their use.
Would you mind adjusting the wording so that it's consistent with
that?

Thanks,
zw
  
Michael Kerrisk \(man-pages\) Dec. 10, 2016, noon UTC | #4
Hello Zack

On 12/09/2016 07:07 PM, Zack Weinberg wrote:
> On Fri, Dec 9, 2016 at 5:32 AM, Michael Kerrisk (man-pages)
> <mtk.manpages@gmail.com> wrote:
>>
>> I should perhaps have been clearer. By "queued" I meant the changes,
>> were not yet in "master"; just in a private branch.
> 
> Oh, OK.  Sorry for the misunderstanding.
> 
>> And, by now, your patch has hit the repo, so I suppose we're good
>> for adding this documentation to nam-pages "master", right?
> 
> Yes, with two more notes ...
> 
>>>> +Historically,
>>>> +defining this macro exposed definitions of certain reentrant functions.
>>>
>>> Historically, it was necessary to define this macro in all
>>> multithreaded code.
>>> Some C libraries may still require this.
>>
>> Okay. I did a little code spelunking and found the following:
> ...
>> In other words, the window of time where _REENTRANT and _THREAD_SAFE
>> did anything much in glibc was quite short, IIUC.
> 
> This is me not being clear enough.  I didn't mean to imply that this
> was historically necessary _with glibc_, but that there did once exist
> C libraries where it was necessary.  The ones I remember were
> proprietary Unix vendor libcs from the mid-1990s.  You would get
> completely unlocked stdio without _REENTRANT.

Okay. I tweaked the wording here very slightly. See below.

> What I would like the text to indicate, is that this is not necessary
> with current glibc but it might still be necessary for portable code,
> and we don't know for sure which platforms are affected.  Maybe this
> is clear enough as is? I'm not sure.

I think the existing text probably is enough.

 
>>>> +This macro is now deprecated; since glibc 2.25,
>>>> +defining it has the same effect as defining
>>>> +.BR _POSIX_C_SOURCE
>>>> +with a value of 199606L or greater.
>>>
>>> In glibc 2.25 and later,
>>> .B _REENTRANT
>>> is deprecated.
> 
> And I've decided that glibc's not going to call these macros
> "deprecated".  creature.texi says "obsolete", NEWS says "these
> nonstandard feature selection macros are now compatibility synonyms
> for _POSIX_C_SOURCE=199506L", and there are no warnings for their use.
> Would you mind adjusting the wording so that it's consistent with
> that?

Done. 

By now, the text reads:

       _REENTRANT
               Historically, on various C libraries it was  necessary  to
               define  this  macro  in  all  multithreaded code.  (Some C
               libraries may still require this.)  In glibc,  this  macro
               also exposed definitions of certain reentrant functions.

               However,  glibc  has  been thread-safe by default for many
               years; since glibc 2.3, the only effect of defining _REEN‐
               TRANT  has  been to enable one or two of the same declara‐
               tions that are also enabled  by  defining  _POSIX_C_SOURCE
               with a value of 199606L or greater.

               _REENTRANT  is  now  obsolete.   In  glibc 2.25 and later,
               defining   _REENTRANT   is    equivalent    to    defining
               _POSIX_C_SOURCE with the value 199606L.  If a higher POSIX
               conformance level is selected by any other means (such  as
               _POSIX_C_SOURCE itself, _XOPEN_SOURCE, _DEFAULT_SOURCE, or
               _GNU_SOURCE), then defining _REENTRANT has no effect.

               This macro is automatically defined if one  compiles  with
               cc -pthread.

Seem okay?

Thanks,

Michael
  
Zack Weinberg Dec. 10, 2016, 1:56 p.m. UTC | #5
On Sat, Dec 10, 2016 at 7:00 AM, Michael Kerrisk (man-pages)
<mtk.manpages@gmail.com> wrote:
> By now, the text reads:
>
>        _REENTRANT
>                Historically, on various C libraries it was  necessary  to
>                define  this  macro  in  all  multithreaded code.  (Some C
>                libraries may still require this.)  In glibc,  this  macro
>                also exposed definitions of certain reentrant functions.
>
>                However,  glibc  has  been thread-safe by default for many
>                years; since glibc 2.3, the only effect of defining _REEN‐
>                TRANT  has  been to enable one or two of the same declara‐
>                tions that are also enabled  by  defining  _POSIX_C_SOURCE
>                with a value of 199606L or greater.
>
>                _REENTRANT  is  now  obsolete.   In  glibc 2.25 and later,
>                defining   _REENTRANT   is    equivalent    to    defining
>                _POSIX_C_SOURCE with the value 199606L.  If a higher POSIX
>                conformance level is selected by any other means (such  as
>                _POSIX_C_SOURCE itself, _XOPEN_SOURCE, _DEFAULT_SOURCE, or
>                _GNU_SOURCE), then defining _REENTRANT has no effect.
>
>                This macro is automatically defined if one  compiles  with
>                cc -pthread.
>
> Seem okay?

Looks good to me.

zw
  
Michael Kerrisk \(man-pages\) Dec. 10, 2016, 2:23 p.m. UTC | #6
On 12/10/2016 02:56 PM, Zack Weinberg wrote:
> On Sat, Dec 10, 2016 at 7:00 AM, Michael Kerrisk (man-pages)
> <mtk.manpages@gmail.com> wrote:
>> By now, the text reads:
>>
>>        _REENTRANT
>>                Historically, on various C libraries it was  necessary  to
>>                define  this  macro  in  all  multithreaded code.  (Some C
>>                libraries may still require this.)  In glibc,  this  macro
>>                also exposed definitions of certain reentrant functions.
>>
>>                However,  glibc  has  been thread-safe by default for many
>>                years; since glibc 2.3, the only effect of defining _REEN‐
>>                TRANT  has  been to enable one or two of the same declara‐
>>                tions that are also enabled  by  defining  _POSIX_C_SOURCE
>>                with a value of 199606L or greater.
>>
>>                _REENTRANT  is  now  obsolete.   In  glibc 2.25 and later,
>>                defining   _REENTRANT   is    equivalent    to    defining
>>                _POSIX_C_SOURCE with the value 199606L.  If a higher POSIX
>>                conformance level is selected by any other means (such  as
>>                _POSIX_C_SOURCE itself, _XOPEN_SOURCE, _DEFAULT_SOURCE, or
>>                _GNU_SOURCE), then defining _REENTRANT has no effect.
>>
>>                This macro is automatically defined if one  compiles  with
>>                cc -pthread.
>>
>> Seem okay?
> 
> Looks good to me.

Thanks, Zack. Merged to master and pushed to public Git now.

Cheers,

Michael
  

Patch

====
--- a/man7/feature_test_macros.7
+++ b/man7/feature_test_macros.7
@@ -529,13 +529,19 @@  and
 .BR _SVID_SOURCE .
 .TP
 .B _REENTRANT
-Defining this macro exposes definitions of certain reentrant functions.
-For multithreaded programs, use
-.I "cc\ \-pthread"
-instead.
+Historically,
+defining this macro exposed definitions of certain reentrant functions.
+However, already for many years this macro has had few effects,
+and since glibc 2.3, no effects that were not also achieved by defining
+.BR _POSIX_C_SOURCE
+with a value of 199606L or greater.
+This macro is now deprecated; since glibc 2.25,
+defining it has the same effect as defining
+.BR _POSIX_C_SOURCE
+with a value of 199606L or greater.
 .TP
 .B _THREAD_SAFE
-Synonym for
+Synonym for the (deprecated)
 .BR _REENTRANT ,
 provided for compatibility with some other implementations.
 .TP