cURL / Mailing Lists / curl-library / Single Mail

curl-library

mutli interface weird callstack

From: Vincent Chen <silence.vincent_at_gmail.com>
Date: Thu, 11 Jun 2015 10:02:32 +0800

Hi,

I have developed a HTTP client with multi interface with boost ASIO library
and uses "CURLMOPT_SOCKETFUNCTION", "CURLMOPT_TIMERFUNCTION" to achieve
asynchronous request.

My timer callback is implemented like this:

/* a static function */
int AsyncCURLMgr::curlTimerCB(CURLM*, long timeout_ms, AsyncCURLMgr* mgr)
{
    // call it immediately
    if(timeout_ms == 0 )
    {
        boost::system::error_code e;
        mgr->whenTimerTimeout(e, timeout_ms);
    }
    else if(timeout_ms > 0)
    {
        /* update timer */
        boost::system::error_code e;

mgr->timer_.expires_from_now(boost::posix_time::millisec(timeout_ms), e);
        mgr->timer_.async_wait(boost::bind(&AsyncCURLMgr::whenTimerTimeout,
mgr, boost::asio::placeholders::error, timeout_ms));
    }

    return 0;
}

void AsyncCURLMgr::whenTimerTimeout(const boost::system::error_code& e,
long)
{
    if(!e)
    {
        int still_running = 0;
        CURLMcode rc = curl_multi_socket_action(curl_multi_,
CURL_SOCKET_TIMEOUT, 0, &still_running);
        if(rc!= CURLM_OK)
           LOG_ERR("[whenTimerTimeout] curl_multi_socket_action return %d
%s\n", rc, curl_multi_strerror(rc));

        checkMultiInfo(); // using curl_multi_info_read() to check
complete requests
    }
}

Recently, I am debugging my program and found a weird call stack.
In the call stack you can see curlTimerCB( ) is called again and again with
timeout value 0.
-------------------------------------------------------------------------------------
#0 LIBPROXY::AsyncCURLMgr::curlSocketCB (easy_handle=0x19c8c240, s=44,
action=2, mgr=0x19c23f50) at ../AsyncCURLMgr.cpp:153
#1 0x00002ba9cf986ee6 in singlesocket () from /usr/tmcss/lib/libcurl.so.4
#2 0x00002ba9cf988974 in multi_socket () from /usr/tmcss/lib/libcurl.so.4
#3 0x00002ba9cf988a2f in curl_multi_socket_action () from
/usr/tmcss/lib/libcurl.so.4
#4 0x00002ba9cf71eb27 in LIBPROXY::AsyncCURLMgr::whenTimerTimeout
(this=0x19c23f50, e=@0x2ba9d243f5b0) at ../AsyncCURLMgr.cpp:478
#5 0x00002ba9cf7200c1 in LIBPROXY::AsyncCURLMgr::curlTimerCB
(timeout_ms=0, mgr=0x19c23f50) at ../AsyncCURLMgr.cpp:177
#6 0x00002ba9cf9869c4 in update_timer () from /usr/tmcss/lib/libcurl.so.4
#7 0x00002ba9cf988a4e in curl_multi_socket_action () from
/usr/tmcss/lib/libcurl.so.4
#8 0x00002ba9cf71eb27 in LIBPROXY::AsyncCURLMgr::whenTimerTimeout
(this=0x19c23f50, e=@0x2ba9d243f710) at ../AsyncCURLMgr.cpp:478
#9 0x00002ba9cf7200c1 in LIBPROXY::AsyncCURLMgr::curlTimerCB
(timeout_ms=0, mgr=0x19c23f50) at ../AsyncCURLMgr.cpp:177
#10 0x00002ba9cf9869c4 in update_timer () from /usr/tmcss/lib/libcurl.so.4
#11 0x00002ba9cf988a4e in curl_multi_socket_action () from
/usr/tmcss/lib/libcurl.so.4
#12 0x00002ba9cf71eb27 in LIBPROXY::AsyncCURLMgr::whenTimerTimeout
(this=0x19c23f50, e=@0x2ba9d243f870) at ../AsyncCURLMgr.cpp:478
#13 0x00002ba9cf7200c1 in LIBPROXY::AsyncCURLMgr::curlTimerCB
(timeout_ms=0, mgr=0x19c23f50) at ../AsyncCURLMgr.cpp:177
#14 0x00002ba9cf9869c4 in update_timer () from /usr/tmcss/lib/libcurl.so.4
#15 0x00002ba9cf988a4e in curl_multi_socket_action () from
/usr/tmcss/lib/libcurl.so.4
#16 0x00002ba9cf71eb27 in LIBPROXY::AsyncCURLMgr::whenTimerTimeout
(this=0x19c23f50, e=@0x2ba9d243f9d0) at ../AsyncCURLMgr.cpp:478
#17 0x00002ba9cf7200c1 in LIBPROXY::AsyncCURLMgr::curlTimerCB
(timeout_ms=0, mgr=0x19c23f50) at ../AsyncCURLMgr.cpp:177
#18 0x00002ba9cf9869c4 in update_timer () from /usr/tmcss/lib/libcurl.so.4
#19 0x00002ba9cf989083 in curl_multi_add_handle () from
/usr/tmcss/lib/libcurl.so.4
-------------------------------------------------------------------------------------

According to the API document, when timeout is 0, I should call
curl_multi_socket_action() immediately.
so in my example code above, I call whenTimerTimeout( ) immediately when
timeout is 0.
so that it can call curl_multi_socket_action() quickly without timer.

I am just curious if this behavior correct?

In addition, I checked the example
http://curl.haxx.se/libcurl/c/multi-uv.html

--------------
void start_timeout(CURLM *multi, long timeout_ms, void *userp)
{
  if(timeout_ms <= 0)
      timeout_ms = 1; /* 0 means directly call socket_action, but
we'll do it in a bit */

  uv_timer_start(&timeout, on_timeout, timeout_ms, 0);
}
--------------

I found it doesn't call on_timeout() when timeout value is 0.

Could you advice the correct calling sequence when timeout value is 0?

thanks!
Vincent

-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
Received on 2015-06-11