forked from enlightenment/efl
complete rewrite of c-ares fd handling: fixes an instance of ticket #637 and also integrates with main loop much more nicely
SVN revision: 55958
This commit is contained in:
parent
89b5e3fa75
commit
828dce5677
|
@ -23,7 +23,7 @@ typedef struct _Ecore_Con_CAres Ecore_Con_CAres;
|
||||||
struct _Ecore_Con_FD
|
struct _Ecore_Con_FD
|
||||||
{
|
{
|
||||||
Ecore_Fd_Handler *handler;
|
Ecore_Fd_Handler *handler;
|
||||||
int active;
|
Ecore_Timer *timer;
|
||||||
int fd;
|
int fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -47,9 +47,6 @@ struct _Ecore_Con_CAres
|
||||||
static ares_channel info_channel;
|
static ares_channel info_channel;
|
||||||
static int info_init = 0;
|
static int info_init = 0;
|
||||||
static Eina_List *info_fds = NULL;
|
static Eina_List *info_fds = NULL;
|
||||||
static int active = 0;
|
|
||||||
static Ecore_Timer *tm = NULL;
|
|
||||||
static fd_set info_readers, info_writers;
|
|
||||||
|
|
||||||
static void _ecore_con_info_ares_nameinfo(Ecore_Con_CAres *arg,
|
static void _ecore_con_info_ares_nameinfo(Ecore_Con_CAres *arg,
|
||||||
int status,
|
int status,
|
||||||
|
@ -60,20 +57,34 @@ static void _ecore_con_info_ares_host_cb(Ecore_Con_CAres *arg,
|
||||||
int status,
|
int status,
|
||||||
int timeouts,
|
int timeouts,
|
||||||
struct hostent *hostent);
|
struct hostent *hostent);
|
||||||
static Eina_Bool _ecore_con_info_cares_fd_cb(void *data,
|
static Eina_Bool _ecore_con_info_cares_fd_cb(Ecore_Con_FD *ecf,
|
||||||
Ecore_Fd_Handler *fd_handler);
|
Ecore_Fd_Handler *fd_handler);
|
||||||
static Eina_Bool _ecore_con_info_cares_timeout_cb(void *data);
|
static Eina_Bool _ecore_con_info_cares_timeout_cb(void *data);
|
||||||
static void _ecore_con_info_cares_clean(void);
|
|
||||||
|
static void
|
||||||
|
_ecore_con_info_cares_state_cb(void *data,
|
||||||
|
int fd,
|
||||||
|
int read,
|
||||||
|
int write);
|
||||||
|
static int
|
||||||
|
_ecore_con_info_fds_search(const Ecore_Con_FD *fd1,
|
||||||
|
const Ecore_Con_FD *fd2);
|
||||||
|
|
||||||
int
|
int
|
||||||
ecore_con_info_init(void)
|
ecore_con_info_init(void)
|
||||||
{
|
{
|
||||||
if (info_init == 0)
|
struct ares_options opts;
|
||||||
|
|
||||||
|
if (!info_init)
|
||||||
{
|
{
|
||||||
if (ares_library_init(ARES_LIB_INIT_ALL) != 0)
|
if (ares_library_init(ARES_LIB_INIT_ALL))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (ares_init(&info_channel) != ARES_SUCCESS)
|
opts.lookups = "fb"; /* hosts file then dns */
|
||||||
|
opts.sock_state_cb = _ecore_con_info_cares_state_cb;
|
||||||
|
|
||||||
|
if (ares_init_options(&info_channel, &opts,
|
||||||
|
ARES_OPT_LOOKUPS | ARES_OPT_SOCK_STATE_CB) != ARES_SUCCESS)
|
||||||
{
|
{
|
||||||
ares_library_cleanup();
|
ares_library_cleanup();
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -94,7 +105,6 @@ ecore_con_info_shutdown(void)
|
||||||
ares_cancel(info_channel);
|
ares_cancel(info_channel);
|
||||||
ares_destroy(info_channel);
|
ares_destroy(info_channel);
|
||||||
|
|
||||||
/* Destroy FD handler here. */
|
|
||||||
/* Shutdown ares */
|
/* Shutdown ares */
|
||||||
ares_library_cleanup();
|
ares_library_cleanup();
|
||||||
}
|
}
|
||||||
|
@ -292,11 +302,34 @@ ecore_con_info_get(Ecore_Con_Server *svr,
|
||||||
cares);
|
cares);
|
||||||
}
|
}
|
||||||
|
|
||||||
_ecore_con_info_cares_clean();
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_ecore_con_info_cares_timeout_cb(void *data __UNUSED__)
|
||||||
|
{
|
||||||
|
ares_process_fd(info_channel, ARES_SOCKET_BAD, ARES_SOCKET_BAD);
|
||||||
|
return ECORE_CALLBACK_RENEW;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_ecore_con_info_cares_fd_cb(Ecore_Con_FD *ecf,
|
||||||
|
Ecore_Fd_Handler *fd_handler)
|
||||||
|
{
|
||||||
|
int read, write;
|
||||||
|
|
||||||
|
read = write = ARES_SOCKET_BAD;
|
||||||
|
|
||||||
|
if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_READ))
|
||||||
|
read = ecf->fd;
|
||||||
|
if (ecore_main_fd_handler_active_get(fd_handler, ECORE_FD_WRITE))
|
||||||
|
write = ecf->fd;
|
||||||
|
|
||||||
|
ares_process_fd(info_channel, read, write);
|
||||||
|
|
||||||
|
return ECORE_CALLBACK_RENEW;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_ecore_con_info_fds_search(const Ecore_Con_FD *fd1,
|
_ecore_con_info_fds_search(const Ecore_Con_FD *fd1,
|
||||||
const Ecore_Con_FD *fd2)
|
const Ecore_Con_FD *fd2)
|
||||||
|
@ -304,119 +337,47 @@ _ecore_con_info_fds_search(const Ecore_Con_FD *fd1,
|
||||||
return fd1->fd - fd2->fd;
|
return fd1->fd - fd2->fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Eina_Bool
|
|
||||||
_ecore_con_info_fds_lookup(int fd)
|
|
||||||
{
|
|
||||||
Ecore_Con_FD fdl;
|
|
||||||
Ecore_Con_FD *search;
|
|
||||||
|
|
||||||
fdl.fd = fd;
|
|
||||||
|
|
||||||
search = eina_list_search_unsorted(
|
|
||||||
info_fds, (Eina_Compare_Cb)_ecore_con_info_fds_search, &fdl);
|
|
||||||
|
|
||||||
if (search)
|
|
||||||
{
|
|
||||||
search->active = active;
|
|
||||||
return EINA_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return EINA_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_ecore_con_info_cares_clean(void)
|
_ecore_con_info_cares_state_cb(void *data __UNUSED__,
|
||||||
|
int fd,
|
||||||
|
int read,
|
||||||
|
int write)
|
||||||
{
|
{
|
||||||
fd_set readers, writers;
|
int flags = 0;
|
||||||
Eina_List *l, *l_next;
|
Ecore_Con_FD *search, *ecf;
|
||||||
Ecore_Con_FD *ecf;
|
|
||||||
int nfds;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
FD_ZERO(&readers);
|
search = eina_list_search_unsorted(info_fds,
|
||||||
FD_ZERO(&writers);
|
(Eina_Compare_Cb)_ecore_con_info_fds_search, &ecf);
|
||||||
nfds = ares_fds(info_channel, &readers, &writers);
|
|
||||||
|
|
||||||
active++;
|
if (!(read | write))
|
||||||
for (i = 0; i < nfds; ++i)
|
|
||||||
{
|
{
|
||||||
int flags = 0;
|
ares_process_fd(info_channel, ARES_SOCKET_BAD, ARES_SOCKET_BAD);
|
||||||
|
if (search)
|
||||||
if (FD_ISSET(i, &readers))
|
|
||||||
flags |= ECORE_FD_READ;
|
|
||||||
|
|
||||||
if (FD_ISSET(i, &writers))
|
|
||||||
flags |= ECORE_FD_WRITE;
|
|
||||||
|
|
||||||
if (flags && (!_ecore_con_info_fds_lookup(i)))
|
|
||||||
{
|
{
|
||||||
ecf = malloc(sizeof(Ecore_Con_FD));
|
info_fds = eina_list_remove(info_fds, search);
|
||||||
if (ecf)
|
ecore_timer_del(search->timer);
|
||||||
{
|
ecore_main_fd_handler_del(search->handler);
|
||||||
ecf->fd = i;
|
free(search);
|
||||||
ecf->active = active;
|
|
||||||
ecf->handler = ecore_main_fd_handler_add(
|
|
||||||
i, ECORE_FD_WRITE | ECORE_FD_READ,
|
|
||||||
_ecore_con_info_cares_fd_cb,
|
|
||||||
NULL, NULL, NULL);
|
|
||||||
info_fds = eina_list_append(info_fds, ecf);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
info_readers = readers;
|
if (!search)
|
||||||
info_writers = writers;
|
|
||||||
|
|
||||||
EINA_LIST_FOREACH_SAFE(info_fds, l, l_next, ecf)
|
|
||||||
{
|
{
|
||||||
if (ecf->active != active)
|
search = malloc(sizeof(Ecore_Con_FD));
|
||||||
{
|
EINA_SAFETY_ON_NULL_RETURN(search);
|
||||||
if (ecf->handler) ecore_main_fd_handler_del(ecf->handler);
|
|
||||||
free(ecf);
|
search->fd = fd;
|
||||||
info_fds = eina_list_remove_list(info_fds, l);
|
search->handler = ecore_main_fd_handler_add(fd, ECORE_FD_WRITE | ECORE_FD_READ,
|
||||||
}
|
(Ecore_Fd_Cb)_ecore_con_info_cares_fd_cb, search, NULL, NULL);
|
||||||
|
/* c-ares default timeout is 5 seconds */
|
||||||
|
search->timer = ecore_timer_add(5, _ecore_con_info_cares_timeout_cb, NULL);
|
||||||
|
info_fds = eina_list_append(info_fds, search);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!info_fds)
|
if (read) flags |= ECORE_FD_READ;
|
||||||
{
|
if (write) flags |= ECORE_FD_WRITE;
|
||||||
if (tm)
|
ecore_main_fd_handler_active_set(search->handler, flags);
|
||||||
ecore_timer_del(tm);
|
|
||||||
|
|
||||||
tm = NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
struct timeval tv;
|
|
||||||
|
|
||||||
ares_timeout(info_channel, NULL, &tv);
|
|
||||||
|
|
||||||
if (tm)
|
|
||||||
ecore_timer_delay(tm, tv.tv_sec);
|
|
||||||
else
|
|
||||||
tm =
|
|
||||||
ecore_timer_add((double)tv.tv_sec,
|
|
||||||
_ecore_con_info_cares_timeout_cb,
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static Eina_Bool
|
|
||||||
_ecore_con_info_cares_timeout_cb(void *data __UNUSED__)
|
|
||||||
{
|
|
||||||
ares_process(info_channel, &info_readers, &info_writers);
|
|
||||||
_ecore_con_info_cares_clean();
|
|
||||||
|
|
||||||
return ECORE_CALLBACK_RENEW;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Eina_Bool
|
|
||||||
_ecore_con_info_cares_fd_cb(void *data __UNUSED__,
|
|
||||||
Ecore_Fd_Handler *fd_handler __UNUSED__)
|
|
||||||
{
|
|
||||||
ares_process(info_channel, &info_readers, &info_writers);
|
|
||||||
_ecore_con_info_cares_clean();
|
|
||||||
|
|
||||||
return ECORE_CALLBACK_RENEW;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
Loading…
Reference in New Issue