Subject: Re: Re-entrancy problems

Re: Re-entrancy problems

From: William Ahern <william_at_25thandclement.com>
Date: 2006-06-09

On Fri, Jun 09, 2006 at 10:02:55AM +0200, Daniel Stenberg wrote:
> On Thu, 8 Jun 2006, William Ahern wrote:
>
> >I'm not sure if "re-entrancy" is the right term, but there is a critical
> >issue in Ares. Maybe it's been discussed before.
> >
> >If a user calls ares_destroy() from a callback, then the library will
> >access invalid memory as it unwinds. One instance is in end_query in
> >ares_process.c.
>
> Why exactly is it a good idea to even allow this?
>

Say you're using a generic event loop, like libevent or liboop. The typical
usage scenario is some glue between the even library and ares. When the loop
churns you're client code only begins to execute as a consequence of ares
executing your callback function. In this scenario there's no point at which
you safely call ares_destroy() or ares_cancel(), because ares code is still
on the stack at that point. You need someway to delay the issue of those
functions till you're sure ares isn't on the stack anymore.

Granted, I released libevnet-0.3.3 with such a mechanism but I'd never be
able to support actual cancellations this way. And it also prevented me from
using memory arenas and pools because it simply wasn't feasible to delay the
destruction of those.

Just in general it's not intuitive that you can't call those from a
callback. I suppose another solution is just to document it ;)

I thought I found a case which made the whole library unsafe for re-entrant
ares_query() and/or ares_process() calls. I'm trying to retrace my
steps--ares_query()->ares_send()->ares__send_query()->next_server()--but I
can't find it so I might be wrong on that point. I suspect this is why so
many deallocations are put after issuance of the callbacks (e.g. in
end_query()).
Received on Fri Jun 9 10:25:20 2006