Subject: Re: syslog_r (Re: CVS commit: src/lib/libc)
To: None <tech-userlevel@NetBSD.org>
From: der Mouse <mouse@Rodents.Montreal.QC.CA>
List: tech-userlevel
Date: 10/28/2006 01:36:41
>>>> I believe we should avoid the word "reentrant",
>> Well, unless we really mean it.
> Well, I have one question.
> Do you think POSIX "_r" functions (e.g. readdir_r()) are reentrant?
I don't know.
> You said the word "reentrant" is stronger than async-signal-safe.
> That implys POSIX "_r" functions are not reentrant in your sense.
Not necessarily reentrant. While it is a stronger condition, it is
fairly unlikely that any _r implementation would not actually be
reentrant by my definition.
Unless async-signal-safe includes signals interrupting other signals'
handlers, in which case the difference becomes even less (not quite
zero, since there is a finite and fairly small list of signals, and
thus a fairly small limit on the reentrancy depth possible due to
signal handlers).
> But POSIX uses the word "reentrant" for the "_r" functions. i.e. What
> you mean in "reentrant" and what POSIX means in "reentrant" seems to
> be different.
Possibly. I'd have to read their definition of "reentrant", and
probably think about it a bit, to be sure.
Also, if POSIX calls them reentrant, what reason do you have for
thinking they're only async-signal-safe rather than really being
reentrant?
>>>> [Wikipedia]
>>>> To be reentrant, a function must hold no static data, must not
>>>> return a pointer to static data, must work only on the data
>>>> provided to it by the caller, and must not call non-reentrant
>>>> functions.
>> I think the Wikipedia is wrong. There is nothing wrong with
>> returning pointers to static data in some cases. [example]
> Yeah, that's right.
> Probably the author of the Wikipedia page intended to say "static
> data which may be modified".
I don't think I'd agree even then. If your "may be modified" means
"may be modified by the caller", it's pretty trivial to write
struct context *k_ctx(int code)
{
switch (code) {
case K_FOO: return(&ctx_foo); break;
case K_BAR: return(&ctx_bar); break;
case K_BAZ: return(&ctx_baz); break;
default: return(0); break;
}
}
If you mean "may be modified by the function itself", it's still easy:
struct context *k_ctx(int code)
{
struct context *c;
switch (code) {
case K_FOO: c = &ctx_foo; break;
case K_BAR: c = &ctx_bar; break;
case K_BAZ: c = &ctx_baz; break;
default: return(0); break;
}
c->ever_used = 1;
return(c);
}
(this is OK because the modifications done by k_ctx are idempotent;
while non-idempotent changes can be OK too, the mutexes[%] get complex
enough I don't want to try to construct an example here).
[%] Not referring to any particular standard's mutexes, but rather the
generic CS concept.
/~\ The ASCII der Mouse
\ / Ribbon Campaign
X Against HTML mouse@rodents.montreal.qc.ca
/ \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B