[getdns-api] async comments (0.268)

Paul Hoffman paul.hoffman at vpnc.org
Sat Feb 9 18:28:24 MST 2013


Going back to your original message.

On Feb 4, 2013, at 7:04 AM, Dan Winship <dan.winship at gmail.com> wrote:

> Some comments from the point of view of thinking about reimplementing
> GLib's getaddrinfo()-in-threads-based resolver
> (http://developer.gnome.org/gio/stable/GResolver.html) with one based on
> getdns()...
> 
> 
>> The callback function might be called at any time, even before
>> getdns() has returned.
> 
> Our experience in GNOME has been that this tends to lead to bugs; the
> code after the getdns() call has to deal with two possible states of
> the world (eg, the userarg data may or may not have been freed), and
> so code like:
> 
>  status = getdns (context, name, GETDNS_RRTYPE_A, NULL,
>                   myuserdata, &transaction_id, mycallback);
>  myuserdata->id = transaction_id;
> 
> would be wrong, but not obviously so (and it might actually work 100%
> of the time with one getdns implementation, but fail sporadically with
> others).

I have thought more about this, and I believe you are wrong both in your example and in general about the the problem. If I'm wrong about this, I'm definitely interested in hearing more.

The only thing that the getdns() call changes in the outside world is the transaction_id. Your callback routine might do things in public memory, but getdns() only changes exactly one thing: it fills in transaction_id with a callback identifier or a NULL. The callback cannot be called until getdns() has filled in the transaction_id. This means that your code above is always fine. If the callback happens before getdns() returns, the transaction_id is already set; the same is true of the callback happens after getdns() returns.

So the only possible place for error is if the application changes userarg in the callback in a way that later code in main() is not expecting. But isn't that true of *any* async system? Assume your example was instead:
 status = getdns (context, name, GETDNS_RRTYPE_A, NULL,
                  myuserdata, &transaction_id, mycallback);
 . . .  // Some commands go here
 myuserdata->id = transaction_id;
Then if the callback arrived after getdns() returned but where the ellipsis is, you would be hosed in exactly the same way as if the callback had been called before getdns() returned. Even if that ellipsis is one line long, and your requested change was instituted, and the API implementation said "I returned from getdns(), I can fire off the callback", you're still hosed.

In other words, I don't think changing when the callback is called will help make the system more predictable. If I'm wrong here, I'm still all ears.

--Paul Hoffman


More information about the getdns-api mailing list