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