forked from enlightenment/efl
giant patch refactoring ecore-con-url from bluezery <opowel@gmail.com>
will it blend?! SVN revision: 65888
This commit is contained in:
parent
32808c9760
commit
39467c29b6
|
@ -187,14 +187,8 @@ struct _Ecore_Con_Url
|
|||
double timestamp;
|
||||
void *data;
|
||||
|
||||
Ecore_Fd_Handler *fd_handler;
|
||||
int fd;
|
||||
int flags;
|
||||
|
||||
int received;
|
||||
int write_fd;
|
||||
|
||||
Eina_Bool active : 1;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
|
@ -35,8 +35,6 @@ int ECORE_CON_EVENT_URL_COMPLETE = 0;
|
|||
int ECORE_CON_EVENT_URL_PROGRESS = 0;
|
||||
|
||||
#ifdef HAVE_CURL
|
||||
static Eina_Bool _ecore_con_url_fd_handler(void *data,
|
||||
Ecore_Fd_Handler *fd_handler);
|
||||
static Eina_Bool _ecore_con_url_perform(Ecore_Con_Url *url_con);
|
||||
static size_t _ecore_con_url_header_cb(void *ptr,
|
||||
size_t size,
|
||||
|
@ -57,50 +55,17 @@ static size_t _ecore_con_url_read_cb(void *ptr,
|
|||
void *stream);
|
||||
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 Eina_Bool _ecore_con_url_idler_handler(void *data);
|
||||
static Eina_Bool _ecore_con_url_fd_handler(void *data __UNUSED__, Ecore_Fd_Handler *fd_handler __UNUSED__);
|
||||
|
||||
static Ecore_Idler *_fd_idler_handler = NULL;
|
||||
static Eina_List *_url_con_list = NULL;
|
||||
static Eina_List *_fd_hd_list = NULL;
|
||||
static CURLM *_curlm = NULL;
|
||||
static fd_set _current_fd_set;
|
||||
static int _init_count = 0;
|
||||
static Ecore_Timer *_curl_timeout = NULL;
|
||||
static Eina_Bool pipelining = EINA_FALSE;
|
||||
|
||||
typedef struct _Ecore_Con_Url_Event Ecore_Con_Url_Event;
|
||||
struct _Ecore_Con_Url_Event
|
||||
{
|
||||
int type;
|
||||
void *ev;
|
||||
};
|
||||
|
||||
static Eina_Bool
|
||||
_url_complete_idler_cb(void *data)
|
||||
{
|
||||
Ecore_Con_Url_Event *lev;
|
||||
|
||||
lev = data;
|
||||
ecore_event_add(lev->type, lev->ev, _ecore_con_event_url_free, NULL);
|
||||
free(lev);
|
||||
|
||||
return ECORE_CALLBACK_CANCEL;
|
||||
}
|
||||
|
||||
static void
|
||||
_url_complete_push_event(int type,
|
||||
void *ev)
|
||||
{
|
||||
Ecore_Con_Url_Event *lev;
|
||||
|
||||
lev = malloc(sizeof(Ecore_Con_Url_Event));
|
||||
lev->type = type;
|
||||
lev->ev = ev;
|
||||
|
||||
ecore_idler_add(_url_complete_idler_cb, lev);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -113,51 +78,30 @@ EAPI int
|
|||
ecore_con_url_init(void)
|
||||
{
|
||||
#ifdef HAVE_CURL
|
||||
_init_count++;
|
||||
if (++_init_count > 1) return _init_count;
|
||||
|
||||
if (_init_count > 1)
|
||||
return _init_count;
|
||||
|
||||
if (!ECORE_CON_EVENT_URL_DATA)
|
||||
{
|
||||
ECORE_CON_EVENT_URL_DATA = ecore_event_type_new();
|
||||
ECORE_CON_EVENT_URL_COMPLETE = ecore_event_type_new();
|
||||
ECORE_CON_EVENT_URL_PROGRESS = ecore_event_type_new();
|
||||
}
|
||||
if (!ECORE_CON_EVENT_URL_DATA) ECORE_CON_EVENT_URL_DATA = ecore_event_type_new();
|
||||
if (!ECORE_CON_EVENT_URL_COMPLETE) ECORE_CON_EVENT_URL_COMPLETE = ecore_event_type_new();
|
||||
if (!ECORE_CON_EVENT_URL_PROGRESS) ECORE_CON_EVENT_URL_PROGRESS = ecore_event_type_new();
|
||||
|
||||
if (!_curlm)
|
||||
{
|
||||
long ms;
|
||||
|
||||
FD_ZERO(&_current_fd_set);
|
||||
if (curl_global_init(CURL_GLOBAL_ALL))
|
||||
{
|
||||
while (_url_con_list)
|
||||
ecore_con_url_free(eina_list_data_get(_url_con_list));
|
||||
return 0;
|
||||
}
|
||||
// curl_global_init() is not thread safe!
|
||||
if (curl_global_init(CURL_GLOBAL_ALL)) return --_init_count;
|
||||
|
||||
_curlm = curl_multi_init();
|
||||
if (!_curlm)
|
||||
{
|
||||
while (_url_con_list)
|
||||
ecore_con_url_free(eina_list_data_get(_url_con_list));
|
||||
|
||||
_init_count--;
|
||||
return 0;
|
||||
}
|
||||
if (!_curlm) return --_init_count;
|
||||
|
||||
curl_multi_timeout(_curlm, &ms);
|
||||
if (ms <= 0)
|
||||
ms = 1000;
|
||||
if (ms <= 0) ms = 100;
|
||||
|
||||
_curl_timeout =
|
||||
ecore_timer_add((double)ms / 1000, _ecore_con_url_idler_handler,
|
||||
(void *)0xACE);
|
||||
_curl_timeout = ecore_timer_add((double)ms / 1000, _ecore_con_url_idler_handler, (void *)0xACE);
|
||||
ecore_timer_freeze(_curl_timeout);
|
||||
}
|
||||
|
||||
return 1;
|
||||
return _init_count;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
|
@ -167,34 +111,31 @@ EAPI int
|
|||
ecore_con_url_shutdown(void)
|
||||
{
|
||||
#ifdef HAVE_CURL
|
||||
if (!_init_count)
|
||||
return 0;
|
||||
if (_init_count == 0) return 0;
|
||||
|
||||
_init_count--;
|
||||
|
||||
if (_init_count != 0)
|
||||
return _init_count;
|
||||
|
||||
if (_fd_idler_handler)
|
||||
ecore_idler_del(_fd_idler_handler);
|
||||
|
||||
_fd_idler_handler = NULL;
|
||||
if (--_init_count == 0)
|
||||
{
|
||||
Ecore_Con_Url *con_url;
|
||||
Ecore_Fd_Handler *fd_handler;
|
||||
|
||||
if (_curl_timeout)
|
||||
{
|
||||
ecore_timer_del(_curl_timeout);
|
||||
|
||||
_curl_timeout = NULL;
|
||||
}
|
||||
|
||||
while (_url_con_list)
|
||||
ecore_con_url_free(eina_list_data_get(_url_con_list));
|
||||
FD_ZERO(&_current_fd_set);
|
||||
EINA_LIST_FREE(_url_con_list, con_url) ecore_con_url_free(con_url);
|
||||
EINA_LIST_FREE(_fd_hd_list, fd_handler) ecore_main_fd_handler_del(fd_handler);
|
||||
|
||||
if (_curlm)
|
||||
{
|
||||
curl_multi_cleanup(_curlm);
|
||||
_curlm = NULL;
|
||||
}
|
||||
|
||||
curl_global_cleanup();
|
||||
}
|
||||
return _init_count;
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
@ -237,7 +178,6 @@ ecore_con_url_new(const char *url)
|
|||
if (!url_con)
|
||||
return NULL;
|
||||
|
||||
url_con->fd = -1;
|
||||
url_con->write_fd = -1;
|
||||
|
||||
url_con->curl_easy = curl_easy_init();
|
||||
|
@ -344,31 +284,16 @@ ecore_con_url_free(Ecore_Con_Url *url_con)
|
|||
}
|
||||
|
||||
ECORE_MAGIC_SET(url_con, ECORE_MAGIC_NONE);
|
||||
if(url_con->fd != -1)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
if (url_con->curl_easy)
|
||||
{
|
||||
// FIXME: For an unknown reason, progress continue to arrive after destruction
|
||||
// this prevent any further call to the callback.
|
||||
curl_easy_setopt(url_con->curl_easy, CURLOPT_PROGRESSFUNCTION, NULL);
|
||||
curl_easy_setopt(url_con->curl_easy, CURLOPT_NOPROGRESS, EINA_TRUE);
|
||||
|
||||
if (url_con->active)
|
||||
if (eina_list_data_find(_url_con_list, url_con))
|
||||
{
|
||||
url_con->active = EINA_FALSE;
|
||||
|
||||
ret = curl_multi_remove_handle(_curlm, url_con->curl_easy);
|
||||
if (ret != CURLM_OK)
|
||||
ERR("curl_multi_remove_handle failed: %s",
|
||||
curl_multi_strerror(ret));
|
||||
if (ret != CURLM_OK) ERR("curl_multi_remove_handle failed: %s", curl_multi_strerror(ret));
|
||||
}
|
||||
|
||||
curl_easy_cleanup(url_con->curl_easy);
|
||||
|
@ -415,8 +340,7 @@ ecore_con_url_url_set(Ecore_Con_Url *url_con,
|
|||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
if (url_con->active)
|
||||
return EINA_FALSE;
|
||||
if (eina_list_data_find(_url_con_list, url_con)) return EINA_FALSE;
|
||||
|
||||
eina_stringshare_replace(&url_con->url, url);
|
||||
|
||||
|
@ -668,8 +592,7 @@ _ecore_con_url_send(Ecore_Con_Url *url_con,
|
|||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
if (url_con->active)
|
||||
return EINA_FALSE;
|
||||
if (eina_list_data_find(_url_con_list, url_con)) return EINA_FALSE;
|
||||
|
||||
if (!url_con->url)
|
||||
return EINA_FALSE;
|
||||
|
@ -787,8 +710,7 @@ ecore_con_url_ftp_upload(Ecore_Con_Url *url_con,
|
|||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
if (url_con->active)
|
||||
return EINA_FALSE;
|
||||
if (eina_list_data_find(_url_con_list, url_con)) return EINA_FALSE;
|
||||
|
||||
if (!url_con->url)
|
||||
return EINA_FALSE;
|
||||
|
@ -1021,8 +943,7 @@ ecore_con_url_verbose_set(Ecore_Con_Url *url_con,
|
|||
return;
|
||||
}
|
||||
|
||||
if (url_con->active)
|
||||
return;
|
||||
if (eina_list_data_find(_url_con_list, url_con)) return;
|
||||
|
||||
if (!url_con->url)
|
||||
return;
|
||||
|
@ -1047,8 +968,7 @@ ecore_con_url_ftp_use_epsv_set(Ecore_Con_Url *url_con,
|
|||
return;
|
||||
}
|
||||
|
||||
if (url_con->active)
|
||||
return;
|
||||
if (eina_list_data_find(_url_con_list, url_con)) return;
|
||||
|
||||
if (!url_con->url)
|
||||
return;
|
||||
|
@ -1085,8 +1005,7 @@ ecore_con_url_ssl_verify_peer_set(Ecore_Con_Url *url_con,
|
|||
return;
|
||||
}
|
||||
|
||||
if (url_con->active)
|
||||
return;
|
||||
if (eina_list_data_find(_url_con_list, url_con)) return;
|
||||
|
||||
if (!url_con->url)
|
||||
return;
|
||||
|
@ -1129,7 +1048,7 @@ ecore_con_url_ssl_ca_set(Ecore_Con_Url *url_con, const char *ca_path)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (url_con->active) return -1;
|
||||
if (eina_list_data_find(_url_con_list, url_con)) return -1;
|
||||
if (!url_con->url) return -1;
|
||||
if (ca_path == NULL)
|
||||
res = curl_easy_setopt(url_con->curl_easy, CURLOPT_SSL_VERIFYPEER, 0);
|
||||
|
@ -1154,54 +1073,6 @@ ecore_con_url_ssl_ca_set(Ecore_Con_Url *url_con, const char *ca_path)
|
|||
*/
|
||||
|
||||
#ifdef HAVE_CURL
|
||||
static int
|
||||
_ecore_con_url_suspend_fd_handler(void)
|
||||
{
|
||||
Eina_List *l;
|
||||
Ecore_Con_Url *url_con;
|
||||
int deleted = 0;
|
||||
|
||||
if (!_url_con_list)
|
||||
return 0;
|
||||
|
||||
EINA_LIST_FOREACH(_url_con_list, l, url_con)
|
||||
{
|
||||
if (url_con->active && url_con->fd_handler)
|
||||
{
|
||||
ecore_main_fd_handler_del(url_con->fd_handler);
|
||||
url_con->fd_handler = NULL;
|
||||
deleted++;
|
||||
}
|
||||
}
|
||||
|
||||
return deleted;
|
||||
}
|
||||
|
||||
static int
|
||||
_ecore_con_url_restart_fd_handler(void)
|
||||
{
|
||||
Eina_List *l;
|
||||
Ecore_Con_Url *url_con;
|
||||
int activated = 0;
|
||||
|
||||
if (!_url_con_list)
|
||||
return 0;
|
||||
|
||||
EINA_LIST_FOREACH(_url_con_list, l, url_con)
|
||||
{
|
||||
if (!url_con->fd_handler && 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++;
|
||||
}
|
||||
}
|
||||
|
||||
return activated;
|
||||
}
|
||||
|
||||
static size_t
|
||||
_ecore_con_url_data_cb(void *buffer,
|
||||
size_t size,
|
||||
|
@ -1235,8 +1106,7 @@ _ecore_con_url_data_cb(void *buffer,
|
|||
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_event_add(ECORE_CON_EVENT_URL_DATA, e, _ecore_con_event_url_free, NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1266,22 +1136,6 @@ _ecore_con_url_data_cb(void *buffer,
|
|||
return real_size;
|
||||
}
|
||||
|
||||
#define ECORE_CON_URL_TRANSMISSION(Transmit, Event, Url_con, Total, Now) \
|
||||
{ \
|
||||
Ecore_Con_Event_Url_Progress *e; \
|
||||
if ((Total != 0) || (Now != 0)) \
|
||||
{ \
|
||||
e = calloc(1, sizeof(Ecore_Con_Event_Url_Progress)); \
|
||||
if (e) \
|
||||
{ \
|
||||
e->url_con = url_con; \
|
||||
e->total = Total; \
|
||||
e->now = Now; \
|
||||
ecore_event_add(Event, e, _ecore_con_event_url_free, NULL); \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
static size_t
|
||||
_ecore_con_url_header_cb(void *ptr,
|
||||
size_t size,
|
||||
|
@ -1324,8 +1178,7 @@ _ecore_con_url_progress_cb(void *clientp,
|
|||
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);
|
||||
ecore_event_add(ECORE_CON_EVENT_URL_PROGRESS, e, _ecore_con_event_url_free, NULL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1358,178 +1211,26 @@ _ecore_con_url_read_cb(void *ptr,
|
|||
return retcode;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_ecore_con_url_perform(Ecore_Con_Url *url_con)
|
||||
static void
|
||||
_ecore_con_url_info_read(void)
|
||||
{
|
||||
fd_set read_set, write_set, exc_set;
|
||||
int fd_max, fd;
|
||||
int flags, still_running;
|
||||
int completed_immediately = 0;
|
||||
CURLMcode ret;
|
||||
|
||||
_url_con_list = eina_list_append(_url_con_list, url_con);
|
||||
|
||||
url_con->active = EINA_TRUE;
|
||||
curl_multi_add_handle(_curlm, url_con->curl_easy);
|
||||
curl_multi_perform(_curlm, &still_running);
|
||||
|
||||
completed_immediately = _ecore_con_url_process_completed_jobs(url_con);
|
||||
|
||||
if (!completed_immediately)
|
||||
{
|
||||
if (url_con->fd_handler)
|
||||
ecore_main_fd_handler_del(url_con->fd_handler);
|
||||
|
||||
url_con->fd_handler = NULL;
|
||||
|
||||
/* url_con still active -- set up an fd_handler */
|
||||
FD_ZERO(&read_set);
|
||||
FD_ZERO(&write_set);
|
||||
FD_ZERO(&exc_set);
|
||||
|
||||
/* Stupid curl, why can't I get the fd to the current added job? */
|
||||
ret = curl_multi_fdset(_curlm, &read_set, &write_set, &exc_set,
|
||||
&fd_max);
|
||||
if (ret != CURLM_OK)
|
||||
{
|
||||
ERR("curl_multi_fdset failed: %s", curl_multi_strerror(ret));
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
for (fd = 0; fd <= fd_max; fd++)
|
||||
{
|
||||
if (!FD_ISSET(fd, &_current_fd_set))
|
||||
{
|
||||
flags = 0;
|
||||
if (FD_ISSET(fd, &read_set))
|
||||
flags |= ECORE_FD_READ;
|
||||
|
||||
if (FD_ISSET(fd, &write_set))
|
||||
flags |= ECORE_FD_WRITE;
|
||||
|
||||
if (FD_ISSET(fd, &exc_set))
|
||||
flags |= ECORE_FD_ERROR;
|
||||
|
||||
if (flags)
|
||||
{
|
||||
long ms = 0;
|
||||
|
||||
ret = curl_multi_timeout(_curlm, &ms);
|
||||
if (ret != CURLM_OK)
|
||||
ERR("curl_multi_timeout failed: %s",
|
||||
curl_multi_strerror(ret));
|
||||
|
||||
if (ms == 0)
|
||||
ms = 1000;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!url_con->fd_handler)
|
||||
{
|
||||
/* Failed to set up an fd_handler */
|
||||
ecore_timer_freeze(_curl_timeout);
|
||||
|
||||
ret = curl_multi_remove_handle(_curlm, url_con->curl_easy);
|
||||
if (ret != CURLM_OK)
|
||||
ERR("curl_multi_remove_handle failed: %s",
|
||||
curl_multi_strerror(ret));
|
||||
|
||||
url_con->active = EINA_FALSE;
|
||||
url_con->fd = -1;
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
ecore_timer_thaw(_curl_timeout);
|
||||
}
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_ecore_con_url_idler_handler(void *data)
|
||||
{
|
||||
int done, still_running;
|
||||
|
||||
done = (curl_multi_perform(_curlm, &still_running) != CURLM_CALL_MULTI_PERFORM);
|
||||
|
||||
_ecore_con_url_process_completed_jobs(NULL);
|
||||
|
||||
if (done)
|
||||
{
|
||||
_ecore_con_url_restart_fd_handler();
|
||||
_fd_idler_handler = NULL;
|
||||
|
||||
if (!_url_con_list)
|
||||
ecore_timer_freeze(_curl_timeout);
|
||||
|
||||
return data ==
|
||||
(void *)0xACE ? ECORE_CALLBACK_RENEW : ECORE_CALLBACK_CANCEL;
|
||||
}
|
||||
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_ecore_con_url_fd_handler(void *data __UNUSED__,
|
||||
Ecore_Fd_Handler *fd_handler __UNUSED__)
|
||||
{
|
||||
_ecore_con_url_suspend_fd_handler();
|
||||
|
||||
if (!_fd_idler_handler)
|
||||
_fd_idler_handler = ecore_idler_add(
|
||||
_ecore_con_url_idler_handler, NULL);
|
||||
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
}
|
||||
|
||||
static int
|
||||
_ecore_con_url_process_completed_jobs(Ecore_Con_Url *url_con_to_match)
|
||||
{
|
||||
Eina_List *l;
|
||||
Ecore_Con_Url *url_con;
|
||||
Ecore_Con_Event_Url_Complete *e;
|
||||
CURLMsg *curlmsg;
|
||||
CURLMcode ret;
|
||||
int n_remaining;
|
||||
int job_matched = 0;
|
||||
|
||||
/* Loop jobs and check if any are done */
|
||||
while ((curlmsg = curl_multi_info_read(_curlm, &n_remaining)))
|
||||
{
|
||||
if (curlmsg->msg != CURLMSG_DONE)
|
||||
continue;
|
||||
if (curlmsg->msg == CURLMSG_DONE)
|
||||
{
|
||||
Eina_List *l, *ll;
|
||||
Ecore_Con_Url *url_con;
|
||||
|
||||
/* find the job which is done */
|
||||
EINA_LIST_FOREACH(_url_con_list, l, url_con)
|
||||
EINA_LIST_FOREACH_SAFE(_url_con_list, l, ll, url_con)
|
||||
{
|
||||
if (curlmsg->easy_handle == url_con->curl_easy)
|
||||
{
|
||||
if (url_con_to_match &&
|
||||
(url_con == url_con_to_match))
|
||||
job_matched = 1;
|
||||
CURLMcode ret;
|
||||
Ecore_Con_Event_Url_Complete *e;
|
||||
|
||||
if(url_con->fd != -1)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
_url_con_list = eina_list_remove(_url_con_list, url_con);
|
||||
url_con->active = EINA_FALSE;
|
||||
e = calloc(1, sizeof(Ecore_Con_Event_Url_Complete));
|
||||
if (e)
|
||||
{
|
||||
|
@ -1538,28 +1239,168 @@ _ecore_con_url_process_completed_jobs(Ecore_Con_Url *url_con_to_match)
|
|||
if (curlmsg->data.result == CURLE_OK)
|
||||
{
|
||||
long status; /* curl API uses long, not int */
|
||||
|
||||
status = 0;
|
||||
curl_easy_getinfo(curlmsg->easy_handle,
|
||||
CURLINFO_RESPONSE_CODE,
|
||||
&status);
|
||||
curl_easy_getinfo(curlmsg->easy_handle, CURLINFO_RESPONSE_CODE, &status);
|
||||
e->status = status;
|
||||
}
|
||||
|
||||
_url_complete_push_event(ECORE_CON_EVENT_URL_COMPLETE, e);
|
||||
ecore_event_add(ECORE_CON_EVENT_URL_COMPLETE, e, _ecore_con_event_url_free, NULL);
|
||||
}
|
||||
|
||||
ret = curl_multi_remove_handle(_curlm, url_con->curl_easy);
|
||||
if (ret != CURLM_OK)
|
||||
ERR("curl_multi_remove_handle failed: %s",
|
||||
curl_multi_strerror(ret));
|
||||
|
||||
if (ret != CURLM_OK) ERR("curl_multi_remove_handle failed: %s", curl_multi_strerror(ret));
|
||||
_url_con_list = eina_list_remove(_url_con_list, url_con);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return job_matched;
|
||||
static void
|
||||
_ecore_con_url_curl_clear(void)
|
||||
{
|
||||
Ecore_Con_Url *url_con;
|
||||
|
||||
FD_ZERO(&_current_fd_set);
|
||||
if (_fd_hd_list)
|
||||
{
|
||||
Ecore_Fd_Handler *fd_handler;
|
||||
EINA_LIST_FREE(_fd_hd_list, fd_handler)
|
||||
{
|
||||
int fd = ecore_main_fd_handler_fd_get(fd_handler);
|
||||
FD_CLR(fd, &_current_fd_set);
|
||||
// FIXME: ecore_main_fd_handler_del() sometimes give errors
|
||||
// because curl do not make fd itself controlled by users, but it can be ignored.
|
||||
ecore_main_fd_handler_del(fd_handler);
|
||||
}
|
||||
}
|
||||
|
||||
EINA_LIST_FREE(_url_con_list, url_con)
|
||||
{
|
||||
CURLMcode ret;
|
||||
Ecore_Con_Event_Url_Complete *e;
|
||||
|
||||
e = calloc(1, sizeof(Ecore_Con_Event_Url_Complete));
|
||||
if (e)
|
||||
{
|
||||
e->url_con = url_con;
|
||||
e->status = 0;
|
||||
ecore_event_add(ECORE_CON_EVENT_URL_COMPLETE, e, _ecore_con_event_url_free, NULL);
|
||||
}
|
||||
ret = curl_multi_remove_handle(_curlm, url_con->curl_easy);
|
||||
if (ret != CURLM_OK) ERR("curl_multi_remove_handle failed: %s", curl_multi_strerror(ret));
|
||||
}
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_ecore_con_url_fd_handler(void *data __UNUSED__, Ecore_Fd_Handler *fd_handler __UNUSED__)
|
||||
{
|
||||
if (_fd_hd_list)
|
||||
{
|
||||
Ecore_Fd_Handler *fd_handler;
|
||||
EINA_LIST_FREE(_fd_hd_list, fd_handler)
|
||||
{
|
||||
int fd = ecore_main_fd_handler_fd_get(fd_handler);
|
||||
FD_CLR(fd, &_current_fd_set);
|
||||
// FIXME: ecore_main_fd_handler_del() sometimes give errors
|
||||
// because curl do not make fd itself controlled by users, but it can be ignored.
|
||||
ecore_main_fd_handler_del(fd_handler);
|
||||
}
|
||||
}
|
||||
ecore_timer_thaw(_curl_timeout);
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
}
|
||||
|
||||
static void
|
||||
_ecore_con_url_fdset(void)
|
||||
{
|
||||
CURLMcode ret;
|
||||
fd_set read_set, write_set, exc_set;
|
||||
int fd, fd_max;
|
||||
Ecore_Fd_Handler *fd_handler;
|
||||
|
||||
FD_ZERO(&read_set);
|
||||
FD_ZERO(&write_set);
|
||||
FD_ZERO(&exc_set);
|
||||
|
||||
ret = curl_multi_fdset(_curlm, &read_set, &write_set, &exc_set, &fd_max);
|
||||
if (ret != CURLM_OK)
|
||||
{
|
||||
ERR("curl_multi_fdset failed: %s", curl_multi_strerror(ret));
|
||||
return;
|
||||
}
|
||||
|
||||
for (fd = 0; fd <= fd_max; fd++)
|
||||
{
|
||||
int flags = 0;
|
||||
if (FD_ISSET(fd, &read_set)) flags |= ECORE_FD_READ;
|
||||
if (FD_ISSET(fd, &write_set)) flags |= ECORE_FD_WRITE;
|
||||
if (FD_ISSET(fd, &exc_set)) flags |= ECORE_FD_ERROR;
|
||||
if (flags)
|
||||
{
|
||||
if (!FD_ISSET(fd, &_current_fd_set))
|
||||
{
|
||||
FD_SET(fd, &_current_fd_set);
|
||||
fd_handler = ecore_main_fd_handler_add(fd, flags, _ecore_con_url_fd_handler, NULL, NULL, NULL);
|
||||
if (fd_handler) _fd_hd_list = eina_list_append(_fd_hd_list, fd_handler);
|
||||
ecore_timer_freeze(_curl_timeout);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_ecore_con_url_idler_handler(void *data __UNUSED__)
|
||||
{
|
||||
int still_running;
|
||||
CURLMcode ret;
|
||||
|
||||
ret = curl_multi_perform(_curlm, &still_running);
|
||||
if (ret != CURLM_OK)
|
||||
{
|
||||
ERR("curl_multi_perform() failed: %s", curl_multi_strerror(ret));
|
||||
_ecore_con_url_curl_clear();
|
||||
ecore_timer_freeze(_curl_timeout);
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
}
|
||||
if (ret == CURLM_CALL_MULTI_PERFORM)
|
||||
{
|
||||
DBG("Call multiperform again");
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
}
|
||||
|
||||
_ecore_con_url_info_read();
|
||||
if (still_running)
|
||||
{
|
||||
DBG("multiperform is still_running");
|
||||
_ecore_con_url_fdset();
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG("multiperform ended");
|
||||
_ecore_con_url_curl_clear();
|
||||
ecore_timer_freeze(_curl_timeout);
|
||||
}
|
||||
|
||||
return ECORE_CALLBACK_RENEW;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_ecore_con_url_perform(Ecore_Con_Url *url_con)
|
||||
{
|
||||
CURLMcode ret;
|
||||
|
||||
ret = curl_multi_add_handle(_curlm, url_con->curl_easy);
|
||||
if (ret != CURLM_OK)
|
||||
{
|
||||
ERR("curl_multi_add_handle() failed: %s", curl_multi_strerror(ret));
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
_url_con_list = eina_list_append(_url_con_list, url_con);
|
||||
ecore_timer_thaw(_curl_timeout);
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
Loading…
Reference in New Issue