struct _Ecore_Con_FD
{
Ecore_Fd_Handler *handler;
- int active;
+ Ecore_Timer *timer;
int fd;
};
static ares_channel info_channel;
static int info_init = 0;
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,
int status,
int status,
int timeouts,
struct hostent *hostent);
-static Eina_Bool _ecore_con_info_cares_fd_cb(void *data,
- Ecore_Fd_Handler *fd_handler);
+static Eina_Bool _ecore_con_info_cares_fd_cb(Ecore_Con_FD *ecf,
+ Ecore_Fd_Handler *fd_handler);
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
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;
- 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();
return 0;
ares_cancel(info_channel);
ares_destroy(info_channel);
- /* Destroy FD handler here. */
/* Shutdown ares */
ares_library_cleanup();
}
cares);
}
- _ecore_con_info_cares_clean();
-
return 1;
}
-static int
-_ecore_con_info_fds_search(const Ecore_Con_FD *fd1,
- const Ecore_Con_FD *fd2)
+static Eina_Bool
+_ecore_con_info_cares_timeout_cb(void *data __UNUSED__)
{
- return fd1->fd - fd2->fd;
+ ares_process_fd(info_channel, ARES_SOCKET_BAD, ARES_SOCKET_BAD);
+ return ECORE_CALLBACK_RENEW;
}
static Eina_Bool
-_ecore_con_info_fds_lookup(int fd)
+_ecore_con_info_cares_fd_cb(Ecore_Con_FD *ecf,
+ Ecore_Fd_Handler *fd_handler)
{
- Ecore_Con_FD fdl;
- Ecore_Con_FD *search;
+ int read, write;
- fdl.fd = fd;
+ read = write = ARES_SOCKET_BAD;
- search = eina_list_search_unsorted(
- info_fds, (Eina_Compare_Cb)_ecore_con_info_fds_search, &fdl);
+ 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);
- if (search)
- {
- search->active = active;
- return EINA_TRUE;
- }
+ return ECORE_CALLBACK_RENEW;
+}
- return EINA_FALSE;
+static int
+_ecore_con_info_fds_search(const Ecore_Con_FD *fd1,
+ const Ecore_Con_FD *fd2)
+{
+ return fd1->fd - fd2->fd;
}
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;
- Eina_List *l, *l_next;
- Ecore_Con_FD *ecf;
- int nfds;
- int i;
-
- FD_ZERO(&readers);
- FD_ZERO(&writers);
- nfds = ares_fds(info_channel, &readers, &writers);
-
- active++;
- for (i = 0; i < nfds; ++i)
- {
- int flags = 0;
-
- if (FD_ISSET(i, &readers))
- flags |= ECORE_FD_READ;
+ int flags = 0;
+ Ecore_Con_FD *search, *ecf;
- if (FD_ISSET(i, &writers))
- flags |= ECORE_FD_WRITE;
+ search = eina_list_search_unsorted(info_fds,
+ (Eina_Compare_Cb)_ecore_con_info_fds_search, &ecf);
- if (flags && (!_ecore_con_info_fds_lookup(i)))
- {
- ecf = malloc(sizeof(Ecore_Con_FD));
- if (ecf)
- {
- ecf->fd = i;
- 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);
- }
- }
- }
-
- info_readers = readers;
- info_writers = writers;
-
- EINA_LIST_FOREACH_SAFE(info_fds, l, l_next, ecf)
+ if (!(read | write))
{
- if (ecf->active != active)
+ ares_process_fd(info_channel, ARES_SOCKET_BAD, ARES_SOCKET_BAD);
+ if (search)
{
- if (ecf->handler) ecore_main_fd_handler_del(ecf->handler);
- free(ecf);
- info_fds = eina_list_remove_list(info_fds, l);
+ info_fds = eina_list_remove(info_fds, search);
+ ecore_timer_del(search->timer);
+ ecore_main_fd_handler_del(search->handler);
+ free(search);
}
+ return;
}
- if (!info_fds)
- {
- if (tm)
- ecore_timer_del(tm);
-
- tm = NULL;
- }
- else
+ if (!search)
{
- 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);
+ search = malloc(sizeof(Ecore_Con_FD));
+ EINA_SAFETY_ON_NULL_RETURN(search);
+
+ search->fd = fd;
+ 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);
}
-}
-
-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;
+ if (read) flags |= ECORE_FD_READ;
+ if (write) flags |= ECORE_FD_WRITE;
+ ecore_main_fd_handler_active_set(search->handler, flags);
}
static void