Subject: Re: [PATCH 1/4] ares_cancel(): ensure cancellation of all requests

Re: [PATCH 1/4] ares_cancel(): ensure cancellation of all requests

From: Alexander Klauer <Alexander.Klauer_at_itwm.fraunhofer.de>
Date: Thu, 21 Mar 2013 15:19:45 +0100

On 03/21/2013 02:56 PM, Tommie Gannert wrote:
> 2013/3/21 Alexander Klauer <Alexander.Klauer_at_itwm.fraunhofer.de>:
>> What happens if someone calls ares_cancel() while ares_cancel() is in
>> progress? With (1), that would mean that the topmost (most recent) instance
>> ares_cancel() has to cancel all those requests that appeared since the
>> next-to-topmost instance was invoked, right?
>
> Good corner case.
>
> I try to think of how I would expect it to work if it was just
> multiple threads doing
> requests and ares_cancel() would cancel them. And I think what you suggest
> makes a lot of sense. The second call would be responsible for cancelling all
> active requests though, so if you have three requests, A B C, and cancelling A
> causes a request D to be created, and then B calls cancel(), then you would
> have a request list like "C D" when entering that second cancel(). In that case
> both the first and second cancel() would be responsible for cancelling C, and
> it would have to be cancelled before the second cancel() returns (and implicitly
> thus also the first as they were recursive calls.)
>
> Might be tricky to get right without ref counting. If it requires a lot of code
> changes, maybe it's not worth enforcing such strict semantics, though.

Implementation-wise, I think I would just swap the list head in the ares
channel with an empty list head on the stack, and then start walking
through the list with the list head on the stack. Any new requests would
then be added to the now initially empty list in the ares channel.

In your example, the first ares_cancel() would cancel A, B, and C, while
the second ares_cancel() would cancel only D. This approach also works
with more than two ares_cancel()s and no reference counting is needed.

>> No real use case, my leaning towards (2) is just personal feeling. My actual
>> use case right now is to call ares_cancel() immediately prior to
>> ares_destroy(). With the implementation of (1), I would of course simply
>> call ares_destroy(). I also call ares_cancel() in an out of memory
>> condition.
>
> Then it sounds like the proposed functionality would actually benefit your code?

It would save one statement, yes.

Best regards,
Alexander
Received on 2013-03-21