Date: Fri, 20 Feb 2004 20:08:14 -0500 (EST) From: Daniel Eischen <eischen@vigrid.com> To: "Brian F. Feldman" <green@FreeBSD.org> Cc: current@FreeBSD.org Subject: Re: Testers wanted: reentrant resolver Message-ID: <Pine.GSO.4.10.10402201952560.19828-100000@pcnet5.pcnet.com> In-Reply-To: <200402210048.i1L0mVGW014390@green.homeunix.org>
index | next in thread | previous in thread | raw e-mail
On Fri, 20 Feb 2004, Brian F. Feldman wrote:
> Daniel Eischen <eischen@vigrid.com> wrote:
> > On Fri, 20 Feb 2004, Brian F. Feldman wrote:
> >
> > > Daniel Eischen <eischen@vigrid.com> wrote:
> > > > Ugh, can you put h_errno inside the per-thread res stuff.
> > > > We shouldn't need to have to add special hooks in the
> > > > threads libraries for this.
> > >
> > > Please explain what you're saying further. On correctly-threaded operating
> > > systems, h_errno is just like errno -- and I made it act EXACTLY as errno
> > > acts, and is per-thread storage for everything but the first thread. It's
> > > absolutely necessary if we want to return the correct errors; even if
> > > everything else in the world is totally reentrant, if h_errno isn't, the
> > > wrong errors can be returned! What "special hooks" do you mean? There's no
> > > way to not change probably hundreds of lines of code without actually doing
> > > the work to make h_errno thread-safe. It's the only proper thing to do.
> >
> > The implementation of __h_errno() need not depend on something
> > special stuffed in struct pthread. Use thread-local storage
> > (pthread_getspecific()) like you did for the res_send_private
> > stuff. Especially since these interfaces should be deprecated
> > in favor of what looks to be BIND 8.2.2 interfaces (according
> > to the Solaris man pages).
>
> Other APIs have the option of failing. __h_errno() does not have the option
> of failing, so what do I do if pthread_key_create() fails? Also, if
> malloc() fails each time pthread_getspecific() returns NULL for the thread?
The API isn't thread-safe by design, so if malloc() fails,
just use the global errno. A better design would be to
add the thread-safe interfaces I mention above, and have
the non-thread-safe interfaces first do the pthread_once(),
pthread_[gs]etspecific() thing and then call the thread-safe
interfaces. Since the malloc() will be the first thing
in the entry point, you can fail right away:
/* MT-safe */
int
res_nsend(res_state statp, const u_char *msg, int msglen,
u_char *answer, int anslen)
{
...
}
/* Not MT-safe */
int
res_send(const u_char *msg, int msglen, u_char *answer,
int anslen)
{
res_state statp;
if (pthread_once(...)) {
...
}
statp = pthread_getspecific(res_key);
if (statp == NULL) {
/* Allocate statp. */
pthread_setspecific(res_key, statp);
}
return (res_nsend(statp, msg, msglen, answer, anslen));
}
--
Dan Eischen
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.GSO.4.10.10402201952560.19828-100000>
