Enlightenment CVS committal Author : raster Project : e17 Module : libs/ecore
Dir : e17/libs/ecore/src/lib/ecore_con Modified Files: Ecore_Con.h ecore_con_private.h ecore_con_url.c Log Message: cedrics ecore_cn_url stuff for file downloads =================================================================== RCS file: /cvs/e/e17/libs/ecore/src/lib/ecore_con/Ecore_Con.h,v retrieving revision 1.35 retrieving revision 1.36 diff -u -3 -r1.35 -r1.36 --- Ecore_Con.h 11 Feb 2008 23:24:11 -0000 1.35 +++ Ecore_Con.h 9 Mar 2008 16:43:32 -0000 1.36 @@ -149,8 +149,14 @@ struct _Ecore_Con_Event_Url_Progress { Ecore_Con_Url *url_con; - double total; - double now; + struct { + double total; + double now; + } down; + struct { + double total; + double now; + } up; }; EAPI extern int ECORE_CON_EVENT_CLIENT_ADD; @@ -161,8 +167,7 @@ EAPI extern int ECORE_CON_EVENT_SERVER_DATA; EAPI extern int ECORE_CON_EVENT_URL_DATA; EAPI extern int ECORE_CON_EVENT_URL_COMPLETE; - EAPI extern int ECORE_CON_EVENT_URL_PROGRESS_DOWNLOAD; - EAPI extern int ECORE_CON_EVENT_URL_PROGRESS_UPLOAD; + EAPI extern int ECORE_CON_EVENT_URL_PROGRESS; EAPI int ecore_con_init(void); EAPI int ecore_con_shutdown(void); @@ -196,6 +201,8 @@ EAPI void ecore_con_url_data_set(Ecore_Con_Url *url_con, void *data); EAPI void *ecore_con_url_data_get(Ecore_Con_Url *url_con); EAPI int ecore_con_url_url_set(Ecore_Con_Url *url_con, const char *url); + EAPI void ecore_con_url_fd_set(Ecore_Con_Url *url_con, int fd); + EAPI int ecore_con_url_received_bytes_get(Ecore_Con_Url *url_con); EAPI int ecore_con_url_send(Ecore_Con_Url *url_con, void *data, size_t length, char *content_type); EAPI void ecore_con_url_time(Ecore_Con_Url *url_con, Ecore_Con_Url_Time condition, time_t tm); =================================================================== RCS file: /cvs/e/e17/libs/ecore/src/lib/ecore_con/ecore_con_private.h,v retrieving revision 1.22 retrieving revision 1.23 diff -u -3 -r1.22 -r1.23 --- ecore_con_private.h 18 Feb 2008 06:27:26 -0000 1.22 +++ ecore_con_private.h 9 Mar 2008 16:43:32 -0000 1.23 @@ -78,6 +78,11 @@ void *data; Ecore_Fd_Handler *fd_handler; + int fd; + int flags; + + int received; + int write_fd; unsigned char active : 1; }; =================================================================== RCS file: /cvs/e/e17/libs/ecore/src/lib/ecore_con/ecore_con_url.c,v retrieving revision 1.18 retrieving revision 1.19 diff -u -3 -r1.18 -r1.19 --- ecore_con_url.c 5 Mar 2008 05:15:37 -0000 1.18 +++ ecore_con_url.c 9 Mar 2008 16:43:32 -0000 1.19 @@ -40,6 +40,8 @@ #include "Ecore_Con.h" #include "ecore_con_private.h" +#include <errno.h> + /** * @defgroup Ecore_Con_Url_Group Ecore URL Connection Functions * @@ -50,8 +52,7 @@ int ECORE_CON_EVENT_URL_DATA = 0; int ECORE_CON_EVENT_URL_COMPLETE = 0; -int ECORE_CON_EVENT_URL_PROGRESS_DOWNLOAD = 0; -int ECORE_CON_EVENT_URL_PROGRESS_UPLOAD = 0; +int ECORE_CON_EVENT_URL_PROGRESS = 0; #ifdef HAVE_CURL static int _ecore_con_url_fd_handler(void *data, Ecore_Fd_Handler *fd_handler); @@ -61,10 +62,11 @@ static void _ecore_con_event_url_free(void *data __UNUSED__, void *ev); static int _ecore_con_url_process_completed_jobs(Ecore_Con_Url *url_con_to_match); -static CURLM *curlm = NULL; -static Ecore_List *_url_con_list = NULL; -static fd_set _current_fd_set; -static int init_count = 0; +static Ecore_Idler *_fd_idler_handler = NULL; +static Ecore_List *_url_con_list = NULL; +static CURLM *curlm = NULL; +static fd_set _current_fd_set; +static int init_count = 0; struct _Ecore_Con_Url_Event { @@ -114,8 +116,7 @@ { ECORE_CON_EVENT_URL_DATA = ecore_event_type_new(); ECORE_CON_EVENT_URL_COMPLETE = ecore_event_type_new(); - ECORE_CON_EVENT_URL_PROGRESS_DOWNLOAD = ecore_event_type_new(); - ECORE_CON_EVENT_URL_PROGRESS_UPLOAD = ecore_event_type_new(); + ECORE_CON_EVENT_URL_PROGRESS = ecore_event_type_new(); } if (!_url_con_list) @@ -168,7 +169,7 @@ if (!ecore_list_empty_is(_url_con_list)) { Ecore_Con_Url *url_con; - while ((url_con = ecore_list_first_remove(_url_con_list))) + while ((url_con = ecore_list_first(_url_con_list))) { ecore_con_url_destroy(url_con); } @@ -230,6 +231,11 @@ curl_easy_setopt(url_con->curl_easy, CURLOPT_TIMEOUT, 300); curl_easy_setopt(url_con->curl_easy, CURLOPT_FOLLOWLOCATION, 1); + curl_easy_setopt(url_con->curl_easy, CURLOPT_ENCODING, "gzip,deflate"); + + url_con->fd = -1; + url_con->write_fd = -1; + return url_con; #else return NULL; @@ -237,6 +243,15 @@ #endif } +static int +_ecore_con_url_compare_cb(const void *data1, const void *data2) +{ + const void *url_con1 = data1; + const void *url_con2 = data2; + + return (url_con1 == url_con2) ? 0 : 1; +} + /** * Frees the Ecore_Con_Url. * @return FIXME: To be documented. @@ -255,11 +270,20 @@ ECORE_MAGIC_SET(url_con, ECORE_MAGIC_NONE); if (url_con->fd_handler) - ecore_main_fd_handler_del(url_con->fd_handler); + { + ecore_main_fd_handler_del(url_con->fd_handler); + url_con->fd = -1; + } if (url_con->curl_easy) { if (url_con->active) - curl_multi_remove_handle(curlm, url_con->curl_easy); + { + if (ecore_list_find(_url_con_list, _ecore_con_url_compare_cb, url_con) == url_con) + ecore_list_remove(_url_con_list); + url_con->active = 0; + + curl_multi_remove_handle(curlm, url_con->curl_easy); + } curl_easy_cleanup(url_con->curl_easy); } curl_slist_free_all(url_con->headers); @@ -376,6 +400,43 @@ * @return FIXME: To be documented. * @ingroup Ecore_Con_Url_Group */ +EAPI void +ecore_con_url_fd_set(Ecore_Con_Url *url_con, int fd) +{ +#ifdef HAVE_CURL + if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) + { + ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_set"); + return ; + } + url_con->write_fd = fd; +#endif +} + +/** + * FIXME: To be documented. + * @return FIXME: To be documented. + * @ingroup Ecore_Con_Url_Group + */ +EAPI int +ecore_con_url_received_bytes_get(Ecore_Con_Url *url_con) +{ +#ifdef HAVE_CURL + if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) + { + ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_received_bytes_get"); + return -1; + } + + return url_con->received; +#endif +} + +/** + * FIXME: To be documented. + * @return FIXME: To be documented. + * @ingroup Ecore_Con_Url_Group + */ EAPI int ecore_con_url_send(Ecore_Con_Url *url_con, void *data, size_t length, char *content_type) { @@ -440,6 +501,57 @@ } #ifdef HAVE_CURL +static int +_ecore_con_url_suspend_fd_handler(void) +{ + Ecore_Con_Url *url_con; + int deleted = 0; + + if (!_url_con_list) + return 0; + + ecore_list_first_goto(_url_con_list); + while ((url_con = ecore_list_current(_url_con_list))) + { + if (url_con->active && url_con->fd_handler) + { + ecore_main_fd_handler_del(url_con->fd_handler); + url_con->fd_handler = NULL; + deleted++; + } + ecore_list_next(_url_con_list); + } + + return deleted; +} + +static int +_ecore_con_url_restart_fd_handler(void) +{ + Ecore_Con_Url *url_con; + int activated = 0; + + if (!_url_con_list) + return 0; + + ecore_list_first_goto(_url_con_list); + while ((url_con = ecore_list_current(_url_con_list))) + { + if (url_con->fd_handler == NULL + && url_con->fd != -1) + { + url_con->fd_handler = ecore_main_fd_handler_add(url_con->fd, + url_con->flags, + _ecore_con_url_fd_handler, + NULL, NULL, NULL); + activated++; + } + ecore_list_next(_url_con_list); + } + + return activated; +} + static size_t _ecore_con_url_data_cb(void *buffer, size_t size, size_t nmemb, void *userp) { @@ -448,15 +560,50 @@ size_t real_size = size * nmemb; url_con = (Ecore_Con_Url *)userp; - e = malloc(sizeof(Ecore_Con_Event_Url_Data) + sizeof(unsigned char) * (real_size - 1)); - if (e) + + if (!url_con) return -1; + if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL)) { - e->url_con = url_con; - e->size = real_size; - memcpy(e->data, buffer, real_size); - ecore_event_add(ECORE_CON_EVENT_URL_DATA, e, - _ecore_con_event_url_free, NULL); + ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_data_cb"); + return -1; + } + + url_con->received += real_size; + + if (url_con->write_fd < 0) + { + e = malloc(sizeof(Ecore_Con_Event_Url_Data) + sizeof(unsigned char) * (real_size - 1)); + if (e) + { + e->url_con = url_con; + e->size = real_size; + memcpy(e->data, buffer, real_size); + ecore_event_add(ECORE_CON_EVENT_URL_DATA, e, + _ecore_con_event_url_free, NULL); + } + } + else + { + ssize_t count = 0; + size_t total_size = real_size; + size_t offset = 0; + + while (total_size > 0) + { + count = write(url_con->write_fd, (char*) buffer + offset, total_size); + if (count < 0) + { + if (errno != EAGAIN && errno != EINTR) + return -1; + } + else + { + total_size -= count; + offset += count; + } + } } + return real_size; } @@ -479,12 +626,21 @@ static int _ecore_con_url_progress_cb(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow) { - Ecore_Con_Url *url_con; + Ecore_Con_Event_Url_Progress *e; + Ecore_Con_Url *url_con; url_con = clientp; - ECORE_CON_URL_TRANSMISSION(Download, ECORE_CON_EVENT_URL_PROGRESS_DOWNLOAD, url_con, dltotal, dlnow); - ECORE_CON_URL_TRANSMISSION(Upload, ECORE_CON_EVENT_URL_PROGRESS_UPLOAD, url_con, ultotal, ulnow); + e = calloc(1, sizeof(Ecore_Con_Event_Url_Progress)); + if (e) + { + e->url_con = url_con; + e->down.total = dltotal; + e->down.now = dlnow; + e->up.total = ultotal; + e->up.now = ulnow; + ecore_event_add(ECORE_CON_EVENT_URL_PROGRESS, e, _ecore_con_event_url_free, NULL); + } return 0; } @@ -493,6 +649,7 @@ _ecore_con_url_perform(Ecore_Con_Url *url_con) { fd_set read_set, write_set, exc_set; + double start; int fd_max; int fd; int flags; @@ -501,8 +658,10 @@ ecore_list_append(_url_con_list, url_con); + start = ecore_time_get(); url_con->active = 1; curl_multi_add_handle(curlm, url_con->curl_easy); + /* This one can't be stopped, or the download never start. */ while (curl_multi_perform(curlm, &still_running) == CURLM_CALL_MULTI_PERFORM); completed_immediately = _ecore_con_url_process_completed_jobs(url_con); @@ -527,9 +686,12 @@ if (flags) { FD_SET(fd, &_current_fd_set); + url_con->fd = fd; + url_con->flags = flags; url_con->fd_handler = ecore_main_fd_handler_add(fd, flags, _ecore_con_url_fd_handler, NULL, NULL, NULL); + break; } } } @@ -538,6 +700,7 @@ /* Failed to set up an fd_handler */ curl_multi_remove_handle(curlm, url_con->curl_easy); url_con->active = 0; + url_con->fd = -1; return 0; } } @@ -546,14 +709,41 @@ } static int +_ecore_con_url_idler_handler(void *data) +{ + double start; + int done = 1; + int still_running; + + start = ecore_time_get(); + while (curl_multi_perform(curlm, &still_running) == CURLM_CALL_MULTI_PERFORM) + /* make this 1/20th of a second to keep interactivity high */ + if ((ecore_time_get() - start) > 0.2) + { + done = 0; + break; + } + + _ecore_con_url_process_completed_jobs(NULL); + + if (done) + { + _ecore_con_url_restart_fd_handler(); + _fd_idler_handler = NULL; + return 0; + } + + return 1; +} + +static int _ecore_con_url_fd_handler(void *data __UNUSED__, Ecore_Fd_Handler *fd_handler __UNUSED__) { - int still_running; + _ecore_con_url_suspend_fd_handler(); - /* FIXME: Can this run for a long time? Maybe limit how long it can run */ - while (curl_multi_perform(curlm, &still_running) == CURLM_CALL_MULTI_PERFORM); + if (_fd_idler_handler == NULL) + _fd_idler_handler = ecore_idler_add(_ecore_con_url_idler_handler, NULL); - _ecore_con_url_process_completed_jobs(NULL); return 1; } @@ -580,11 +770,12 @@ if (url_con_to_match && (url_con == url_con_to_match)) { job_matched = 1; } - if (url_con->fd_handler) + if (url_con->fd != -1) { - FD_CLR(ecore_main_fd_handler_fd_get(url_con->fd_handler), - &_current_fd_set); - ecore_main_fd_handler_del(url_con->fd_handler); + FD_CLR(url_con->fd, &_current_fd_set); + if (url_con->fd_handler) + ecore_main_fd_handler_del(url_con->fd_handler); + url_con->fd = -1; url_con->fd_handler = NULL; } ecore_list_remove(_url_con_list); ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2008. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ _______________________________________________ enlightenment-cvs mailing list enlightenment-cvs@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs