discomfitor pushed a commit to branch efl-1.12.

http://git.enlightenment.org/core/efl.git/commit/?id=e2386ff31cdae5ced36a72e759df880f777d59c2

commit e2386ff31cdae5ced36a72e759df880f777d59c2
Author: zmike <michael.blumenkra...@gmail.com>
Date:   Fri Jan 2 23:21:34 2015 -0500

    curl usage better accounts for timeouts
    
    curl is dumb. it needs to poll its own fd for data, it gets confused with 
its own timeouts, and sometimes it forgets that it's supposed to be doing 
anything.
    
    this fixes:
    
    * connection timeout processing
    * connection data processing order
    
    also curl_multi_timeout calls are now done from a single function to handle 
all of this stupidness in one place
    
    maybe backport after more testing...
---
 src/lib/ecore_con/ecore_con_url.c | 49 ++++++++++++++++++++++++++++++++++-----
 1 file changed, 43 insertions(+), 6 deletions(-)

diff --git a/src/lib/ecore_con/ecore_con_url.c 
b/src/lib/ecore_con/ecore_con_url.c
index 2c5dc0c..11a2abc 100644
--- a/src/lib/ecore_con/ecore_con_url.c
+++ b/src/lib/ecore_con/ecore_con_url.c
@@ -276,6 +276,7 @@ static Eina_List *_fd_hd_list = NULL;
 static int _init_count = 0;
 static Ecore_Timer *_curl_timer = NULL;
 static Eina_Bool pipelining = EINA_FALSE;
+static long last_ms = -1;
 
 static Ecore_Con_Curl *_c = NULL;
 static Eina_Bool _c_fail = EINA_FALSE;
@@ -343,7 +344,8 @@ _c_init(void)
         goto error;
      }
    _c->curl_multi_timeout(_c->_curlm, &ms);
-   if ((ms >= CURL_MIN_TIMEOUT) || (ms <= 0)) ms = CURL_MIN_TIMEOUT;
+   if ((ms >= CURL_MIN_TIMEOUT) || (ms < 0)) ms = CURL_MIN_TIMEOUT;
+   last_ms = ms;
    _curl_timer = ecore_timer_add((double)ms / 1000.0,
                                  _ecore_con_url_timer, NULL);
    ecore_timer_freeze(_curl_timer);
@@ -1519,20 +1521,53 @@ _ecore_con_url_curl_clear(void)
      ecore_main_fd_handler_del(fdh);
    EINA_LIST_FREE(_url_con_list, url_con)
      _ecore_con_url_multi_remove(url_con);
+   last_ms = -1;
+}
+
+static Eina_Bool
+_ecore_con_url_do_multi_timeout(long *retms)
+{
+   long ms = 0;
+   int ret;
+
+   while (!ms)
+     {
+        ret = _c->curl_multi_timeout(_c->_curlm, &ms);
+        *retms = ms;
+        if ((last_ms > 0) && (ms < 0))
+          ERR("curl_multi_perform() timeout");
+        else if (ms <= 0)
+          {
+             last_ms = ms;
+             _ecore_con_url_timer(NULL);
+             DBG("multiperform is still running: timeout: %ld", ms);
+             return EINA_TRUE;
+          }
+        else if ((ret <= 0) && (ms > 0)) break;
+        else
+          ERR("curl_multi_perform() failed: %s", _c->curl_multi_strerror(ret));
+        last_ms = ms;
+        _ecore_con_url_curl_clear();
+        ecore_timer_freeze(_curl_timer);
+        return EINA_FALSE;
+     }
+   return EINA_TRUE;
 }
 
 static Eina_Bool
 _ecore_con_url_fd_handler(void *data EINA_UNUSED, Ecore_Fd_Handler *fd_handler 
EINA_UNUSED)
 {
    Ecore_Fd_Handler *fdh;
-   long ms;
+   long ms = 0;
 
    if (!_c) return ECORE_CALLBACK_CANCEL;
    EINA_LIST_FREE(_fd_hd_list, fdh)
      ecore_main_fd_handler_del(fdh);
-   _c->curl_multi_timeout(_c->_curlm, &ms);
+   if (!_ecore_con_url_do_multi_timeout(&ms)) return EINA_FALSE;
+   last_ms = ms;
    if ((ms >= CURL_MIN_TIMEOUT) || (ms <= 0)) ms = CURL_MIN_TIMEOUT;
    ecore_timer_interval_set(_curl_timer, (double)ms / 1000.0);
+   ecore_timer_reset(_curl_timer);
    _ecore_con_url_timer(NULL);
    return ECORE_CALLBACK_CANCEL;
 }
@@ -1594,6 +1629,7 @@ _ecore_con_url_timer(void *data EINA_UNUSED)
    if (ret == CURLM_CALL_MULTI_PERFORM)
      {
         DBG("curl_multi_perform() again immediately");
+        ecore_timer_interval_set(_curl_timer, 0.000001);
         return ECORE_CALLBACK_RENEW;
      }
    else if (ret != CURLM_OK)
@@ -1604,13 +1640,14 @@ _ecore_con_url_timer(void *data EINA_UNUSED)
      }
    if (still_running)
      {
-        long ms;
+        long ms = 0;
 
         _ecore_con_url_fdset();
-        _c->curl_multi_timeout(_c->_curlm, &ms);
+        if (!_ecore_con_url_do_multi_timeout(&ms)) return EINA_FALSE;
+        last_ms = ms;
         DBG("multiperform is still running: %d, timeout: %ld",
             still_running, ms);
-        if ((ms >= CURL_MIN_TIMEOUT) || (ms <= 0)) ms = CURL_MIN_TIMEOUT;
+        if ((ms >= CURL_MIN_TIMEOUT) || (ms < 0)) ms = CURL_MIN_TIMEOUT;
         ecore_timer_interval_set(_curl_timer, (double)ms / 1000.0);
      }
    else

-- 


Reply via email to