summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzmike <michael.blumenkrantz@gmail.com>2015-01-02 23:21:34 -0500
committerMike Blumenkrantz <zmike@osg.samsung.com>2015-01-19 23:21:14 -0500
commite2386ff31cdae5ced36a72e759df880f777d59c2 (patch)
treedf7a25994f4c5dea7199ebccfa5ec881ab04a643
parent8040d1f3c59ab9f0cac3b2aa850ad78ab7bd9ba1 (diff)
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...
-rw-r--r--src/lib/ecore_con/ecore_con_url.c49
1 files 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 2c5dc0ce5f..11a2abce12 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;
276static int _init_count = 0; 276static int _init_count = 0;
277static Ecore_Timer *_curl_timer = NULL; 277static Ecore_Timer *_curl_timer = NULL;
278static Eina_Bool pipelining = EINA_FALSE; 278static Eina_Bool pipelining = EINA_FALSE;
279static long last_ms = -1;
279 280
280static Ecore_Con_Curl *_c = NULL; 281static Ecore_Con_Curl *_c = NULL;
281static Eina_Bool _c_fail = EINA_FALSE; 282static Eina_Bool _c_fail = EINA_FALSE;
@@ -343,7 +344,8 @@ _c_init(void)
343 goto error; 344 goto error;
344 } 345 }
345 _c->curl_multi_timeout(_c->_curlm, &ms); 346 _c->curl_multi_timeout(_c->_curlm, &ms);
346 if ((ms >= CURL_MIN_TIMEOUT) || (ms <= 0)) ms = CURL_MIN_TIMEOUT; 347 if ((ms >= CURL_MIN_TIMEOUT) || (ms < 0)) ms = CURL_MIN_TIMEOUT;
348 last_ms = ms;
347 _curl_timer = ecore_timer_add((double)ms / 1000.0, 349 _curl_timer = ecore_timer_add((double)ms / 1000.0,
348 _ecore_con_url_timer, NULL); 350 _ecore_con_url_timer, NULL);
349 ecore_timer_freeze(_curl_timer); 351 ecore_timer_freeze(_curl_timer);
@@ -1519,20 +1521,53 @@ _ecore_con_url_curl_clear(void)
1519 ecore_main_fd_handler_del(fdh); 1521 ecore_main_fd_handler_del(fdh);
1520 EINA_LIST_FREE(_url_con_list, url_con) 1522 EINA_LIST_FREE(_url_con_list, url_con)
1521 _ecore_con_url_multi_remove(url_con); 1523 _ecore_con_url_multi_remove(url_con);
1524 last_ms = -1;
1525}
1526
1527static Eina_Bool
1528_ecore_con_url_do_multi_timeout(long *retms)
1529{
1530 long ms = 0;
1531 int ret;
1532
1533 while (!ms)
1534 {
1535 ret = _c->curl_multi_timeout(_c->_curlm, &ms);
1536 *retms = ms;
1537 if ((last_ms > 0) && (ms < 0))
1538 ERR("curl_multi_perform() timeout");
1539 else if (ms <= 0)
1540 {
1541 last_ms = ms;
1542 _ecore_con_url_timer(NULL);
1543 DBG("multiperform is still running: timeout: %ld", ms);
1544 return EINA_TRUE;
1545 }
1546 else if ((ret <= 0) && (ms > 0)) break;
1547 else
1548 ERR("curl_multi_perform() failed: %s", _c->curl_multi_strerror(ret));
1549 last_ms = ms;
1550 _ecore_con_url_curl_clear();
1551 ecore_timer_freeze(_curl_timer);
1552 return EINA_FALSE;
1553 }
1554 return EINA_TRUE;
1522} 1555}
1523 1556
1524static Eina_Bool 1557static Eina_Bool
1525_ecore_con_url_fd_handler(void *data EINA_UNUSED, Ecore_Fd_Handler *fd_handler EINA_UNUSED) 1558_ecore_con_url_fd_handler(void *data EINA_UNUSED, Ecore_Fd_Handler *fd_handler EINA_UNUSED)
1526{ 1559{
1527 Ecore_Fd_Handler *fdh; 1560 Ecore_Fd_Handler *fdh;
1528 long ms; 1561 long ms = 0;
1529 1562
1530 if (!_c) return ECORE_CALLBACK_CANCEL; 1563 if (!_c) return ECORE_CALLBACK_CANCEL;
1531 EINA_LIST_FREE(_fd_hd_list, fdh) 1564 EINA_LIST_FREE(_fd_hd_list, fdh)
1532 ecore_main_fd_handler_del(fdh); 1565 ecore_main_fd_handler_del(fdh);
1533 _c->curl_multi_timeout(_c->_curlm, &ms); 1566 if (!_ecore_con_url_do_multi_timeout(&ms)) return EINA_FALSE;
1567 last_ms = ms;
1534 if ((ms >= CURL_MIN_TIMEOUT) || (ms <= 0)) ms = CURL_MIN_TIMEOUT; 1568 if ((ms >= CURL_MIN_TIMEOUT) || (ms <= 0)) ms = CURL_MIN_TIMEOUT;
1535 ecore_timer_interval_set(_curl_timer, (double)ms / 1000.0); 1569 ecore_timer_interval_set(_curl_timer, (double)ms / 1000.0);
1570 ecore_timer_reset(_curl_timer);
1536 _ecore_con_url_timer(NULL); 1571 _ecore_con_url_timer(NULL);
1537 return ECORE_CALLBACK_CANCEL; 1572 return ECORE_CALLBACK_CANCEL;
1538} 1573}
@@ -1594,6 +1629,7 @@ _ecore_con_url_timer(void *data EINA_UNUSED)
1594 if (ret == CURLM_CALL_MULTI_PERFORM) 1629 if (ret == CURLM_CALL_MULTI_PERFORM)
1595 { 1630 {
1596 DBG("curl_multi_perform() again immediately"); 1631 DBG("curl_multi_perform() again immediately");
1632 ecore_timer_interval_set(_curl_timer, 0.000001);
1597 return ECORE_CALLBACK_RENEW; 1633 return ECORE_CALLBACK_RENEW;
1598 } 1634 }
1599 else if (ret != CURLM_OK) 1635 else if (ret != CURLM_OK)
@@ -1604,13 +1640,14 @@ _ecore_con_url_timer(void *data EINA_UNUSED)
1604 } 1640 }
1605 if (still_running) 1641 if (still_running)
1606 { 1642 {
1607 long ms; 1643 long ms = 0;
1608 1644
1609 _ecore_con_url_fdset(); 1645 _ecore_con_url_fdset();
1610 _c->curl_multi_timeout(_c->_curlm, &ms); 1646 if (!_ecore_con_url_do_multi_timeout(&ms)) return EINA_FALSE;
1647 last_ms = ms;
1611 DBG("multiperform is still running: %d, timeout: %ld", 1648 DBG("multiperform is still running: %d, timeout: %ld",
1612 still_running, ms); 1649 still_running, ms);
1613 if ((ms >= CURL_MIN_TIMEOUT) || (ms <= 0)) ms = CURL_MIN_TIMEOUT; 1650 if ((ms >= CURL_MIN_TIMEOUT) || (ms < 0)) ms = CURL_MIN_TIMEOUT;
1614 ecore_timer_interval_set(_curl_timer, (double)ms / 1000.0); 1651 ecore_timer_interval_set(_curl_timer, (double)ms / 1000.0);
1615 } 1652 }
1616 else 1653 else