cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: running_handles: less than zero ?

From: Daniel Stenberg <daniel_at_haxx.se>
Date: Sun, 8 Oct 2006 12:44:00 +0200 (CEST)

On Sun, 8 Oct 2006, Jeff Pohlmeyer wrote:

>> I believe you can fix this bug in hiperfifo.c like this:
>> ...
>> + break;
>> ...
>
>
> Ah, I see now - should this be clarified in the multi_info_read docs? Maybe
> something like:
>
> " After receiving a msg value of CURLMSG_DONE, subsequent calls
> to curl_multi_info_read may exhibit undefined behavior, at least
> until the completed easy handle is removed. "

No, that's not the right conclusion. Your program read and discarded all
messages from curl_multi_info_read() except the last one, in the cases where
more than one were available.

I believe the man page already explains that once you've extracted a message,
it won't be returned again.

>> When this happens, does it stall forever or just "a while" ?
>
> Well, I'm not sure about "forever", but safe to say it's a really long time.
> At least a couple hours, and my progress callback doesn't get updated,
> either. It usually only stalls out after several minutes, and it's not
> something that is easy to reproduce consistently, so trying to "tweak out"
> the problem can be a time-consuming task.

Okay, I was mostly curious on how to see if I manage to trigger the problem
myself. So far I haven't.

> One thing I noticed, in my update_timeout() function (which I copied from
> your hiper/hiperv.c) is that the function doesn't check the value returned
> in timeout_ms before passing it on to evtimer_add(), which can result in the
> timeval's tv_usec getting set to a negative value (-1000).

Ah, right. Not very good.

> I'm not sure how to deal with this, possibly either:
>
>
> if ( timeout_ms <= 0 ) { return; }
> -- or --
> if ( timeout_ms <= 0 ) { timeout_ms =0; }
>
> I tried both ways, and it looks like if I return immediately, without
> setting the timer, then I still get the stalling, but not the CPU hogging.

Yeah, -1 means there's no timeout set in libcurl so there shouldn't be any set
for libevent either. The question is rather how it ended up not existing any
timeouts...

> I didn't find anything in the docs about exactly when the call to
> curl_multi_timeout() is needed, the comment in "hipev.c" says "after every
> call to libcurl" which sounds a bit extreme.

Every call to libcurl can change what curl_multi_timeout() returns and it
isn't possible or even wanted that an app will be possible to tell which call
that will do that or won't. Not only because curl_multi_timeout() returns a
time-out (relative) value and not a fixed-time so that repeated calls will
always return different values, but because the multi handle can contain
numerous handles and when these handles change state and depending on what's
going on in the protocol level, the timeout value will change.

> This seems like a burden on the application programmer that might possibly
> be better handled internally, maybe using something like a
> CURLMOPT_TIMEOUT_FUNCTION that could be defined in the application, and
> invoked by the library whenever it sees fit. ( Just a thought. )

Possibly we could do that. You mean a function that would be called when the
nearest timeout "point" changes?

I'd say that currently we lack real-world usage of the curl_multi_socket() API
so things such as this haven't been tried for real very much.

> For what it's worth, I found that libevent can be replaced fairly easily
> with glib-2.x in the demo. Although have haven't found much difference in
> the performance, it does hint that curl-hiper might integrate nicely into
> GTK applications.
>
> I can post the code if you like ( keeping in mind that glib is LGPL ).

It would of course still make a nice demo app for the examples dir!

-- 
  Commercial curl and libcurl Technical Support: http://haxx.se/curl.html
Received on 2006-10-08