cedrics ecore_cn_url stuff for file downloads
SVN revision: 33970
This commit is contained in:
parent
fcf201dea7
commit
2f4173e229
|
@ -100,7 +100,6 @@ if test "x$want_curl" = "xyes"; then
|
||||||
PKG_CHECK_MODULES(CURL, libcurl,
|
PKG_CHECK_MODULES(CURL, libcurl,
|
||||||
[
|
[
|
||||||
AC_DEFINE(HAVE_CURL, 1, [ Downloading with CURL ])
|
AC_DEFINE(HAVE_CURL, 1, [ Downloading with CURL ])
|
||||||
requirements_ecore_file="$requirements_ecore_file libcurl"
|
|
||||||
requirements_ecore_con="$requirements_ecore_con libcurl"
|
requirements_ecore_con="$requirements_ecore_con libcurl"
|
||||||
have_curl="yes"
|
have_curl="yes"
|
||||||
],
|
],
|
||||||
|
@ -721,6 +720,7 @@ if test "x$have_ecore_file" = "xyes"; then
|
||||||
AC_DEFINE(HAVE_POLL, 1, [ File monitoring with polling ])
|
AC_DEFINE(HAVE_POLL, 1, [ File monitoring with polling ])
|
||||||
have_poll="yes"
|
have_poll="yes"
|
||||||
fi
|
fi
|
||||||
|
requirements_ecore_file="$requirements_ecore_file $requirements_ecore_con"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
dnl ecore_desktop
|
dnl ecore_desktop
|
||||||
|
|
|
@ -149,8 +149,14 @@ extern "C" {
|
||||||
struct _Ecore_Con_Event_Url_Progress
|
struct _Ecore_Con_Event_Url_Progress
|
||||||
{
|
{
|
||||||
Ecore_Con_Url *url_con;
|
Ecore_Con_Url *url_con;
|
||||||
double total;
|
struct {
|
||||||
double now;
|
double total;
|
||||||
|
double now;
|
||||||
|
} down;
|
||||||
|
struct {
|
||||||
|
double total;
|
||||||
|
double now;
|
||||||
|
} up;
|
||||||
};
|
};
|
||||||
|
|
||||||
EAPI extern int ECORE_CON_EVENT_CLIENT_ADD;
|
EAPI extern int ECORE_CON_EVENT_CLIENT_ADD;
|
||||||
|
@ -161,8 +167,7 @@ extern "C" {
|
||||||
EAPI extern int ECORE_CON_EVENT_SERVER_DATA;
|
EAPI extern int ECORE_CON_EVENT_SERVER_DATA;
|
||||||
EAPI extern int ECORE_CON_EVENT_URL_DATA;
|
EAPI extern int ECORE_CON_EVENT_URL_DATA;
|
||||||
EAPI extern int ECORE_CON_EVENT_URL_COMPLETE;
|
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;
|
||||||
EAPI extern int ECORE_CON_EVENT_URL_PROGRESS_UPLOAD;
|
|
||||||
|
|
||||||
EAPI int ecore_con_init(void);
|
EAPI int ecore_con_init(void);
|
||||||
EAPI int ecore_con_shutdown(void);
|
EAPI int ecore_con_shutdown(void);
|
||||||
|
@ -196,6 +201,8 @@ extern "C" {
|
||||||
EAPI void ecore_con_url_data_set(Ecore_Con_Url *url_con, void *data);
|
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 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 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 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);
|
EAPI void ecore_con_url_time(Ecore_Con_Url *url_con, Ecore_Con_Url_Time condition, time_t tm);
|
||||||
|
|
||||||
|
|
|
@ -78,6 +78,11 @@ struct _Ecore_Con_Url
|
||||||
void *data;
|
void *data;
|
||||||
|
|
||||||
Ecore_Fd_Handler *fd_handler;
|
Ecore_Fd_Handler *fd_handler;
|
||||||
|
int fd;
|
||||||
|
int flags;
|
||||||
|
|
||||||
|
int received;
|
||||||
|
int write_fd;
|
||||||
|
|
||||||
unsigned char active : 1;
|
unsigned char active : 1;
|
||||||
};
|
};
|
||||||
|
|
|
@ -40,6 +40,8 @@
|
||||||
#include "Ecore_Con.h"
|
#include "Ecore_Con.h"
|
||||||
#include "ecore_con_private.h"
|
#include "ecore_con_private.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @defgroup Ecore_Con_Url_Group Ecore URL Connection Functions
|
* @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_DATA = 0;
|
||||||
int ECORE_CON_EVENT_URL_COMPLETE = 0;
|
int ECORE_CON_EVENT_URL_COMPLETE = 0;
|
||||||
int ECORE_CON_EVENT_URL_PROGRESS_DOWNLOAD = 0;
|
int ECORE_CON_EVENT_URL_PROGRESS = 0;
|
||||||
int ECORE_CON_EVENT_URL_PROGRESS_UPLOAD = 0;
|
|
||||||
|
|
||||||
#ifdef HAVE_CURL
|
#ifdef HAVE_CURL
|
||||||
static int _ecore_con_url_fd_handler(void *data, Ecore_Fd_Handler *fd_handler);
|
static int _ecore_con_url_fd_handler(void *data, Ecore_Fd_Handler *fd_handler);
|
||||||
|
@ -61,10 +62,11 @@ static int _ecore_con_url_progress_cb(void *clientp, double dltotal, double dlno
|
||||||
static void _ecore_con_event_url_free(void *data __UNUSED__, void *ev);
|
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 int _ecore_con_url_process_completed_jobs(Ecore_Con_Url *url_con_to_match);
|
||||||
|
|
||||||
static CURLM *curlm = NULL;
|
static Ecore_Idler *_fd_idler_handler = NULL;
|
||||||
static Ecore_List *_url_con_list = NULL;
|
static Ecore_List *_url_con_list = NULL;
|
||||||
static fd_set _current_fd_set;
|
static CURLM *curlm = NULL;
|
||||||
static int init_count = 0;
|
static fd_set _current_fd_set;
|
||||||
|
static int init_count = 0;
|
||||||
|
|
||||||
struct _Ecore_Con_Url_Event
|
struct _Ecore_Con_Url_Event
|
||||||
{
|
{
|
||||||
|
@ -114,8 +116,7 @@ ecore_con_url_init(void)
|
||||||
{
|
{
|
||||||
ECORE_CON_EVENT_URL_DATA = ecore_event_type_new();
|
ECORE_CON_EVENT_URL_DATA = ecore_event_type_new();
|
||||||
ECORE_CON_EVENT_URL_COMPLETE = 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 = ecore_event_type_new();
|
||||||
ECORE_CON_EVENT_URL_PROGRESS_UPLOAD = ecore_event_type_new();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_url_con_list)
|
if (!_url_con_list)
|
||||||
|
@ -168,7 +169,7 @@ ecore_con_url_shutdown(void)
|
||||||
if (!ecore_list_empty_is(_url_con_list))
|
if (!ecore_list_empty_is(_url_con_list))
|
||||||
{
|
{
|
||||||
Ecore_Con_Url *url_con;
|
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);
|
ecore_con_url_destroy(url_con);
|
||||||
}
|
}
|
||||||
|
@ -230,6 +231,11 @@ ecore_con_url_new(const char *url)
|
||||||
curl_easy_setopt(url_con->curl_easy, CURLOPT_TIMEOUT, 300);
|
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_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;
|
return url_con;
|
||||||
#else
|
#else
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -237,6 +243,15 @@ ecore_con_url_new(const char *url)
|
||||||
#endif
|
#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.
|
* Frees the Ecore_Con_Url.
|
||||||
* @return FIXME: To be documented.
|
* @return FIXME: To be documented.
|
||||||
|
@ -255,11 +270,20 @@ ecore_con_url_destroy(Ecore_Con_Url *url_con)
|
||||||
|
|
||||||
ECORE_MAGIC_SET(url_con, ECORE_MAGIC_NONE);
|
ECORE_MAGIC_SET(url_con, ECORE_MAGIC_NONE);
|
||||||
if (url_con->fd_handler)
|
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->curl_easy)
|
||||||
{
|
{
|
||||||
if (url_con->active)
|
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_easy_cleanup(url_con->curl_easy);
|
||||||
}
|
}
|
||||||
curl_slist_free_all(url_con->headers);
|
curl_slist_free_all(url_con->headers);
|
||||||
|
@ -371,6 +395,43 @@ ecore_con_url_time(Ecore_Con_Url *url_con, Ecore_Con_Url_Time condition, time_t
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FIXME: To be documented.
|
||||||
|
* @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.
|
* FIXME: To be documented.
|
||||||
* @return FIXME: To be documented.
|
* @return FIXME: To be documented.
|
||||||
|
@ -440,6 +501,57 @@ ecore_con_url_send(Ecore_Con_Url *url_con, void *data, size_t length, char *cont
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_CURL
|
#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
|
static size_t
|
||||||
_ecore_con_url_data_cb(void *buffer, size_t size, size_t nmemb, void *userp)
|
_ecore_con_url_data_cb(void *buffer, size_t size, size_t nmemb, void *userp)
|
||||||
{
|
{
|
||||||
|
@ -448,15 +560,50 @@ _ecore_con_url_data_cb(void *buffer, size_t size, size_t nmemb, void *userp)
|
||||||
size_t real_size = size * nmemb;
|
size_t real_size = size * nmemb;
|
||||||
|
|
||||||
url_con = (Ecore_Con_Url *)userp;
|
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;
|
ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_data_cb");
|
||||||
e->size = real_size;
|
return -1;
|
||||||
memcpy(e->data, buffer, real_size);
|
|
||||||
ecore_event_add(ECORE_CON_EVENT_URL_DATA, e,
|
|
||||||
_ecore_con_event_url_free, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
return real_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -479,12 +626,21 @@ _ecore_con_url_data_cb(void *buffer, size_t size, size_t nmemb, void *userp)
|
||||||
static int
|
static int
|
||||||
_ecore_con_url_progress_cb(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow)
|
_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;
|
url_con = clientp;
|
||||||
|
|
||||||
ECORE_CON_URL_TRANSMISSION(Download, ECORE_CON_EVENT_URL_PROGRESS_DOWNLOAD, url_con, dltotal, dlnow);
|
e = calloc(1, sizeof(Ecore_Con_Event_Url_Progress));
|
||||||
ECORE_CON_URL_TRANSMISSION(Upload, ECORE_CON_EVENT_URL_PROGRESS_UPLOAD, url_con, ultotal, ulnow);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -493,6 +649,7 @@ static int
|
||||||
_ecore_con_url_perform(Ecore_Con_Url *url_con)
|
_ecore_con_url_perform(Ecore_Con_Url *url_con)
|
||||||
{
|
{
|
||||||
fd_set read_set, write_set, exc_set;
|
fd_set read_set, write_set, exc_set;
|
||||||
|
double start;
|
||||||
int fd_max;
|
int fd_max;
|
||||||
int fd;
|
int fd;
|
||||||
int flags;
|
int flags;
|
||||||
|
@ -501,8 +658,10 @@ _ecore_con_url_perform(Ecore_Con_Url *url_con)
|
||||||
|
|
||||||
ecore_list_append(_url_con_list, url_con);
|
ecore_list_append(_url_con_list, url_con);
|
||||||
|
|
||||||
|
start = ecore_time_get();
|
||||||
url_con->active = 1;
|
url_con->active = 1;
|
||||||
curl_multi_add_handle(curlm, url_con->curl_easy);
|
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);
|
while (curl_multi_perform(curlm, &still_running) == CURLM_CALL_MULTI_PERFORM);
|
||||||
|
|
||||||
completed_immediately = _ecore_con_url_process_completed_jobs(url_con);
|
completed_immediately = _ecore_con_url_process_completed_jobs(url_con);
|
||||||
|
@ -527,9 +686,12 @@ _ecore_con_url_perform(Ecore_Con_Url *url_con)
|
||||||
if (flags)
|
if (flags)
|
||||||
{
|
{
|
||||||
FD_SET(fd, &_current_fd_set);
|
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,
|
url_con->fd_handler = ecore_main_fd_handler_add(fd, flags,
|
||||||
_ecore_con_url_fd_handler,
|
_ecore_con_url_fd_handler,
|
||||||
NULL, NULL, NULL);
|
NULL, NULL, NULL);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -538,6 +700,7 @@ _ecore_con_url_perform(Ecore_Con_Url *url_con)
|
||||||
/* Failed to set up an fd_handler */
|
/* Failed to set up an fd_handler */
|
||||||
curl_multi_remove_handle(curlm, url_con->curl_easy);
|
curl_multi_remove_handle(curlm, url_con->curl_easy);
|
||||||
url_con->active = 0;
|
url_con->active = 0;
|
||||||
|
url_con->fd = -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -546,14 +709,41 @@ _ecore_con_url_perform(Ecore_Con_Url *url_con)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_ecore_con_url_fd_handler(void *data __UNUSED__, Ecore_Fd_Handler *fd_handler __UNUSED__)
|
_ecore_con_url_idler_handler(void *data)
|
||||||
{
|
{
|
||||||
int still_running;
|
double start;
|
||||||
|
int done = 1;
|
||||||
|
int still_running;
|
||||||
|
|
||||||
/* FIXME: Can this run for a long time? Maybe limit how long it can run */
|
start = ecore_time_get();
|
||||||
while (curl_multi_perform(curlm, &still_running) == CURLM_CALL_MULTI_PERFORM);
|
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);
|
_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__)
|
||||||
|
{
|
||||||
|
_ecore_con_url_suspend_fd_handler();
|
||||||
|
|
||||||
|
if (_fd_idler_handler == NULL)
|
||||||
|
_fd_idler_handler = ecore_idler_add(_ecore_con_url_idler_handler, NULL);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -580,11 +770,12 @@ _ecore_con_url_process_completed_jobs(Ecore_Con_Url *url_con_to_match)
|
||||||
if (url_con_to_match && (url_con == url_con_to_match)) {
|
if (url_con_to_match && (url_con == url_con_to_match)) {
|
||||||
job_matched = 1;
|
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),
|
FD_CLR(url_con->fd, &_current_fd_set);
|
||||||
&_current_fd_set);
|
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;
|
||||||
url_con->fd_handler = NULL;
|
url_con->fd_handler = NULL;
|
||||||
}
|
}
|
||||||
ecore_list_remove(_url_con_list);
|
ecore_list_remove(_url_con_list);
|
||||||
|
|
|
@ -2,6 +2,7 @@ MAINTAINERCLEANFILES = Makefile.in
|
||||||
|
|
||||||
AM_CPPFLAGS = \
|
AM_CPPFLAGS = \
|
||||||
-I$(top_srcdir)/src/lib/ecore \
|
-I$(top_srcdir)/src/lib/ecore \
|
||||||
|
-I$(top_srcdir)/src/lib/ecore_con \
|
||||||
-I$(top_builddir)/src/lib/ecore \
|
-I$(top_builddir)/src/lib/ecore \
|
||||||
@CURL_CFLAGS@
|
@CURL_CFLAGS@
|
||||||
|
|
||||||
|
@ -21,7 +22,8 @@ ecore_file_download.c
|
||||||
|
|
||||||
libecore_file_la_LIBADD = \
|
libecore_file_la_LIBADD = \
|
||||||
$(top_builddir)/src/lib/ecore/libecore.la \
|
$(top_builddir)/src/lib/ecore/libecore.la \
|
||||||
@CURL_LIBS@ @ecore_file_win32_lib@ @winsock_libs@
|
$(top_builddir)/src/lib/ecore_con/libecore_con.la \
|
||||||
|
@ecore_file_win32_lib@ @winsock_libs@
|
||||||
|
|
||||||
libecore_file_la_LDFLAGS = @create_shared_lib@ -version-info @version_info@
|
libecore_file_la_LDFLAGS = @create_shared_lib@ -version-info @version_info@
|
||||||
|
|
||||||
|
|
|
@ -1,111 +1,98 @@
|
||||||
/*
|
/*
|
||||||
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
|
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
|
||||||
*/
|
*/
|
||||||
|
#include "Ecore_Con.h"
|
||||||
#include "ecore_file_private.h"
|
#include "ecore_file_private.h"
|
||||||
|
|
||||||
static int init = 0;
|
#define ECORE_MAGIC_FILE_DOWNLOAD_JOB 0xf7427cb8
|
||||||
|
|
||||||
#ifdef HAVE_CURL
|
|
||||||
#include <curl/curl.h>
|
|
||||||
|
|
||||||
typedef struct _Ecore_File_Download_Job Ecore_File_Download_Job;
|
|
||||||
|
|
||||||
|
typedef struct _Ecore_File_Download_Job Ecore_File_Download_Job;
|
||||||
struct _Ecore_File_Download_Job
|
struct _Ecore_File_Download_Job
|
||||||
{
|
{
|
||||||
Ecore_Fd_Handler *fd_handler;
|
ECORE_MAGIC;
|
||||||
CURL *curl;
|
|
||||||
void (*completion_cb)(void *data, const char *file, int status);
|
Ecore_Con_Url *url_con;
|
||||||
int (*progress_cb)(void *data, const char *file, long int dltotal, long int dlnow, long int ultotal, long int ulnow);
|
FILE *file;
|
||||||
void *data;
|
|
||||||
FILE *file;
|
char *dst;
|
||||||
char *dst;
|
|
||||||
|
void (*completion_cb)(void *data, const char *file, int status);
|
||||||
|
|
||||||
|
int (*progress_cb) (void *data, const char *file,
|
||||||
|
long int dltotal, long int dlnow,
|
||||||
|
long int ultotal, long int ulnow);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef HAVE_CURL
|
||||||
Ecore_File_Download_Job *_ecore_file_download_curl(const char *url, const char *dst,
|
Ecore_File_Download_Job *_ecore_file_download_curl(const char *url, const char *dst,
|
||||||
void (*completion_cb)(void *data, const char *file, int status),
|
void (*completion_cb)(void *data, const char *file, int status),
|
||||||
int (*progress_cb)(void *data, const char *file, long int dltotal, long int dlnow, long int ultotal, long int ulnow),
|
int (*progress_cb)(void *data, const char *file, long int dltotal, long int dlnow, long int ultotal, long int ulnow),
|
||||||
void *data);
|
void *data);
|
||||||
static int _ecore_file_download_curl_fd_handler(void *data, Ecore_Fd_Handler *fd_handler);
|
static int _ecore_file_download_curl_fd_handler(void *data, Ecore_Fd_Handler *fd_handler);
|
||||||
|
|
||||||
static CURLM *curlm;
|
static void _ecore_file_download_abort(Ecore_File_Download_Job *job);
|
||||||
static Ecore_List *_job_list;
|
|
||||||
static fd_set _current_fd_set;
|
static int _ecore_file_download_url_complete_cb(void *data, int type, void *event);
|
||||||
|
static int _ecore_file_download_url_progress_cb(void *data, int type, void *event);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int
|
static int init = 0;
|
||||||
|
static Ecore_Event_Handler *_url_complete_handler = NULL;
|
||||||
|
static Ecore_Event_Handler *_url_progress_download = NULL;
|
||||||
|
static Ecore_List *_job_list;
|
||||||
|
|
||||||
|
EAPI int
|
||||||
ecore_file_download_init(void)
|
ecore_file_download_init(void)
|
||||||
{
|
{
|
||||||
if (++init != 1) return init;
|
ecore_con_url_init();
|
||||||
|
|
||||||
#ifdef HAVE_CURL
|
if (init++ == 0)
|
||||||
FD_ZERO(&_current_fd_set);
|
|
||||||
_job_list = ecore_list_new();
|
|
||||||
if (!_job_list) return --init;
|
|
||||||
|
|
||||||
if (curl_global_init(CURL_GLOBAL_NOTHING)) return 0;
|
|
||||||
|
|
||||||
curlm = curl_multi_init();
|
|
||||||
if (!curlm)
|
|
||||||
{
|
{
|
||||||
ecore_list_destroy(_job_list);
|
#ifdef HAVE_CURL
|
||||||
_job_list = NULL;
|
_url_complete_handler = ecore_event_handler_add(ECORE_CON_EVENT_URL_COMPLETE, _ecore_file_download_url_complete_cb, NULL);
|
||||||
return --init;
|
_url_progress_download = ecore_event_handler_add(ECORE_CON_EVENT_URL_PROGRESS, _ecore_file_download_url_progress_cb, NULL);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
if (!_job_list)
|
||||||
return init;
|
{
|
||||||
|
_job_list = ecore_list_new();
|
||||||
|
if (!_job_list) return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
EAPI int
|
||||||
ecore_file_download_shutdown(void)
|
ecore_file_download_shutdown(void)
|
||||||
{
|
{
|
||||||
if (--init != 0) return init;
|
if (--init == 0)
|
||||||
#ifdef HAVE_CURL
|
|
||||||
Ecore_File_Download_Job *job;
|
|
||||||
|
|
||||||
if (!ecore_list_empty_is(_job_list))
|
|
||||||
{
|
{
|
||||||
ecore_list_first_goto(_job_list);
|
ecore_event_handler_del(_url_complete_handler);
|
||||||
while ((job = ecore_list_next(_job_list)))
|
ecore_event_handler_del(_url_progress_download);
|
||||||
{
|
_url_complete_handler = NULL;
|
||||||
ecore_main_fd_handler_del(job->fd_handler);
|
_url_progress_download = NULL;
|
||||||
curl_multi_remove_handle(curlm, job->curl);
|
|
||||||
curl_easy_cleanup(job->curl);
|
ecore_list_destroy(_job_list);
|
||||||
fclose(job->file);
|
|
||||||
free(job->dst);
|
|
||||||
free(job);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ecore_list_destroy(_job_list);
|
|
||||||
curl_multi_cleanup(curlm);
|
return ecore_con_url_shutdown();
|
||||||
curl_global_cleanup();
|
|
||||||
#endif
|
|
||||||
return init;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
EAPI void
|
||||||
ecore_file_download_abort_all(void)
|
ecore_file_download_abort_all(void)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_CURL
|
if (!ecore_list_empty_is(_job_list))
|
||||||
Ecore_File_Download_Job *job;
|
|
||||||
|
|
||||||
if (!_job_list)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ecore_list_first_goto(_job_list);
|
|
||||||
while ((job = ecore_list_next(_job_list)))
|
|
||||||
{
|
{
|
||||||
ecore_main_fd_handler_del(job->fd_handler);
|
Ecore_File_Download_Job *job;
|
||||||
curl_multi_remove_handle(curlm, job->curl);
|
|
||||||
curl_easy_cleanup(job->curl);
|
while ((job = ecore_list_first_remove(_job_list)))
|
||||||
fclose(job->file);
|
{
|
||||||
free(job->dst);
|
_ecore_file_download_abort(job);
|
||||||
free(job);
|
}
|
||||||
}
|
}
|
||||||
ecore_list_clear(_job_list);
|
ecore_list_clear(_job_list);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Download @p url to the given @p dst
|
* Download @p url to the given @p dst
|
||||||
* @param url The complete url to download
|
* @param url The complete url to download
|
||||||
|
@ -192,200 +179,108 @@ ecore_file_download_protocol_available(const char *protocol)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_CURL
|
#ifdef HAVE_CURL
|
||||||
|
static int
|
||||||
|
_ecore_file_download_url_compare_job(const void *data1, const void *data2)
|
||||||
|
{
|
||||||
|
const Ecore_File_Download_Job *job = data1;
|
||||||
|
const Ecore_Con_Url *url = data2;
|
||||||
|
|
||||||
|
if (job->url_con == url) return 0;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_ecore_file_download_url_complete_cb(void *data, int type, void *event)
|
||||||
|
{
|
||||||
|
Ecore_Con_Event_Url_Complete *ev = event;
|
||||||
|
Ecore_File_Download_Job *job;
|
||||||
|
|
||||||
|
job = ecore_list_find(_job_list, _ecore_file_download_url_compare_job, ev->url_con);
|
||||||
|
if (!ECORE_MAGIC_CHECK(job, ECORE_MAGIC_FILE_DOWNLOAD_JOB)) return 1;
|
||||||
|
|
||||||
|
ecore_list_remove(_job_list);
|
||||||
|
|
||||||
|
if (job->completion_cb)
|
||||||
|
job->completion_cb(ecore_con_url_data_get(job->url_con), job->dst, !ev->status);
|
||||||
|
|
||||||
|
_ecore_file_download_abort(job);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_ecore_file_download_url_progress_cb(void *data, int type, void *event)
|
||||||
|
{
|
||||||
/* this reports the downloads progress. if we return 0, then download
|
/* this reports the downloads progress. if we return 0, then download
|
||||||
* continues, if we return anything else, then the download stops */
|
* continues, if we return anything else, then the download stops */
|
||||||
static int
|
Ecore_Con_Event_Url_Progress *ev = event;
|
||||||
_ecore_file_download_curl_progress_func(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow)
|
Ecore_File_Download_Job *job;
|
||||||
{
|
|
||||||
Ecore_File_Download_Job *job;
|
|
||||||
|
|
||||||
job = clientp;
|
job = ecore_list_find(_job_list, _ecore_file_download_url_compare_job, ev->url_con);
|
||||||
|
if (!ECORE_MAGIC_CHECK(job, ECORE_MAGIC_FILE_DOWNLOAD_JOB)) return 1;
|
||||||
|
|
||||||
|
if (job->progress_cb)
|
||||||
|
if (job->progress_cb(ecore_con_url_data_get(job->url_con), job->dst,
|
||||||
|
(long int) ev->down.total, (long int) ev->down.now,
|
||||||
|
(long int) ev->up.total, (long int) ev->up.now) != 0)
|
||||||
|
{
|
||||||
|
ecore_list_remove(_job_list);
|
||||||
|
_ecore_file_download_abort(job);
|
||||||
|
}
|
||||||
|
|
||||||
if(job->progress_cb)
|
|
||||||
return job->progress_cb(job->data, job->dst, (long int)dltotal, (long int)dlnow, (long int)ultotal, (long int)ulnow);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_ecore_file_download_abort(Ecore_File_Download_Job *job)
|
||||||
|
{
|
||||||
|
ecore_con_url_destroy(job->url_con);
|
||||||
|
fclose(job->file);
|
||||||
|
free(job->dst);
|
||||||
|
free(job);
|
||||||
|
}
|
||||||
|
|
||||||
Ecore_File_Download_Job *
|
Ecore_File_Download_Job *
|
||||||
_ecore_file_download_curl(const char *url, const char *dst,
|
_ecore_file_download_curl(const char *url, const char *dst,
|
||||||
void (*completion_cb)(void *data, const char *file,
|
void (*completion_cb)(void *data, const char *file,
|
||||||
int status),
|
int status),
|
||||||
int (*progress_cb)(void *data, const char *file,
|
int (*progress_cb)(void *data, const char *file,
|
||||||
long int dltotal, long int dlnow,
|
long int dltotal, long int dlnow,
|
||||||
long int ultotal,
|
long int ultotal, long int ulnow),
|
||||||
long int ulnow),
|
|
||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
CURLMsg *curlmsg;
|
|
||||||
fd_set read_set, write_set, exc_set;
|
|
||||||
int fd_max;
|
|
||||||
int fd;
|
|
||||||
int flags;
|
|
||||||
int n_remaining, still_running;
|
|
||||||
Ecore_File_Download_Job *job;
|
Ecore_File_Download_Job *job;
|
||||||
double start = 0.0;
|
|
||||||
|
|
||||||
job = calloc(1, sizeof(Ecore_File_Download_Job));
|
job = calloc(1, sizeof(Ecore_File_Download_Job));
|
||||||
if (!job) return NULL;
|
if (!job) return NULL;
|
||||||
|
|
||||||
|
ECORE_MAGIC_SET(job, ECORE_MAGIC_FILE_DOWNLOAD_JOB);
|
||||||
|
|
||||||
job->file = fopen(dst, "wb");
|
job->file = fopen(dst, "wb");
|
||||||
if (!job->file)
|
if (!job->file)
|
||||||
{
|
{
|
||||||
free(job);
|
free(job);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
job->curl = curl_easy_init();
|
job->url_con = ecore_con_url_new(url);
|
||||||
if (!job->curl)
|
if (!job->url_con)
|
||||||
{
|
{
|
||||||
fclose(job->file);
|
fclose(job->file);
|
||||||
free(job);
|
free(job);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
curl_easy_setopt(job->curl, CURLOPT_URL, url);
|
ecore_con_url_fd_set(job->url_con, fileno(job->file));
|
||||||
curl_easy_setopt(job->curl, CURLOPT_WRITEDATA, job->file);
|
ecore_con_url_data_set(job->url_con, data);
|
||||||
curl_easy_setopt(job->curl, CURLOPT_FOLLOWLOCATION, TRUE);
|
|
||||||
|
job->dst = strdup(dst);
|
||||||
if (progress_cb)
|
|
||||||
{
|
|
||||||
curl_easy_setopt(job->curl, CURLOPT_NOPROGRESS, FALSE);
|
|
||||||
curl_easy_setopt(job->curl, CURLOPT_PROGRESSDATA, job);
|
|
||||||
curl_easy_setopt(job->curl, CURLOPT_PROGRESSFUNCTION, _ecore_file_download_curl_progress_func);
|
|
||||||
}
|
|
||||||
|
|
||||||
job->data = data;
|
|
||||||
job->completion_cb = completion_cb;
|
job->completion_cb = completion_cb;
|
||||||
job->progress_cb = progress_cb;
|
job->progress_cb = progress_cb;
|
||||||
job->dst = strdup(dst);
|
|
||||||
ecore_list_append(_job_list, job);
|
ecore_list_append(_job_list, job);
|
||||||
|
|
||||||
curl_multi_add_handle(curlm, job->curl);
|
ecore_con_url_send(job->url_con, NULL, 0, NULL);
|
||||||
start = ecore_time_get();
|
|
||||||
while (curl_multi_perform(curlm, &still_running) == CURLM_CALL_MULTI_PERFORM)
|
|
||||||
{
|
|
||||||
/* make this 1/100th of a second to keep interactivity high. really
|
|
||||||
* though this needs to somehow get the fd from curl and use an fd handler
|
|
||||||
* and thus select
|
|
||||||
*/
|
|
||||||
if ((ecore_time_get() - start) > 0.01) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check for completed jobs */
|
|
||||||
while ((curlmsg = curl_multi_info_read(curlm, &n_remaining)) != NULL)
|
|
||||||
{
|
|
||||||
Ecore_File_Download_Job *current;
|
|
||||||
|
|
||||||
if (curlmsg->msg != CURLMSG_DONE) continue;
|
|
||||||
|
|
||||||
/* find the job which is done */
|
|
||||||
ecore_list_first_goto(_job_list);
|
|
||||||
while ((current = ecore_list_current(_job_list)))
|
|
||||||
{
|
|
||||||
if (curlmsg->easy_handle == current->curl)
|
|
||||||
{
|
|
||||||
/* We have a match -- delete the job */
|
|
||||||
if (current == job)
|
|
||||||
job = NULL;
|
|
||||||
if (current->fd_handler)
|
|
||||||
{
|
|
||||||
FD_CLR(ecore_main_fd_handler_fd_get(current->fd_handler),
|
|
||||||
&_current_fd_set);
|
|
||||||
ecore_main_fd_handler_del(current->fd_handler);
|
|
||||||
}
|
|
||||||
ecore_list_remove(_job_list);
|
|
||||||
curl_multi_remove_handle(curlm, current->curl);
|
|
||||||
curl_easy_cleanup(current->curl);
|
|
||||||
fclose(current->file);
|
|
||||||
if (current->completion_cb)
|
|
||||||
current->completion_cb(current->data, current->dst,
|
|
||||||
curlmsg->data.result);
|
|
||||||
free(current->dst);
|
|
||||||
free(current);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ecore_list_next(_job_list);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (job)
|
|
||||||
{
|
|
||||||
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? */
|
|
||||||
curl_multi_fdset(curlm, &read_set, &write_set, &exc_set, &fd_max);
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
FD_SET(fd, &_current_fd_set);
|
|
||||||
job->fd_handler = ecore_main_fd_handler_add(fd, flags,
|
|
||||||
_ecore_file_download_curl_fd_handler,
|
|
||||||
NULL, NULL, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!job->fd_handler)
|
|
||||||
{
|
|
||||||
curl_easy_cleanup(job->curl);
|
|
||||||
fclose(job->file);
|
|
||||||
free(job);
|
|
||||||
job = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return job;
|
return job;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
_ecore_file_download_curl_fd_handler(void *data __UNUSED__, Ecore_Fd_Handler *fd_handler __UNUSED__)
|
|
||||||
{
|
|
||||||
Ecore_File_Download_Job *job;
|
|
||||||
CURLMsg *curlmsg;
|
|
||||||
int n_remaining, still_running;
|
|
||||||
double start = 0.0;
|
|
||||||
|
|
||||||
start = ecore_time_get();
|
|
||||||
while (curl_multi_perform(curlm, &still_running) == CURLM_CALL_MULTI_PERFORM)
|
|
||||||
{
|
|
||||||
if ((ecore_time_get() - start) > 0.2) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Loop jobs and check if any are done */
|
|
||||||
while ((curlmsg = curl_multi_info_read(curlm, &n_remaining)) != NULL)
|
|
||||||
{
|
|
||||||
if (curlmsg->msg != CURLMSG_DONE) continue;
|
|
||||||
|
|
||||||
/* find the job which is done */
|
|
||||||
ecore_list_first_goto(_job_list);
|
|
||||||
while ((job = ecore_list_current(_job_list)))
|
|
||||||
{
|
|
||||||
if (curlmsg->easy_handle == job->curl)
|
|
||||||
{
|
|
||||||
/* We have a match -- delete the job */
|
|
||||||
FD_CLR(ecore_main_fd_handler_fd_get(job->fd_handler),
|
|
||||||
&_current_fd_set);
|
|
||||||
ecore_list_remove(_job_list);
|
|
||||||
ecore_main_fd_handler_del(job->fd_handler);
|
|
||||||
curl_multi_remove_handle(curlm, job->curl);
|
|
||||||
curl_easy_cleanup(job->curl);
|
|
||||||
fclose(job->file);
|
|
||||||
if (job->completion_cb)
|
|
||||||
job->completion_cb(job->data, job->dst, !curlmsg->data.result);
|
|
||||||
free(job->dst);
|
|
||||||
free(job);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ecore_list_next(_job_list);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue