/* Callback from ares when socket operation is started */ static void uv__ares_sockstate_cb(void* data, ares_socket_t sock, int read, int write) { uv_loop_t* loop = data; uv_ares_task_t* h; assert((uv_loop_t*)loop->timer.data == loop); h = uv_find_ares_handle(loop, sock); if (read || write) { if (!h) { /* New socket */ /* If this is the first socket then start the timer. */ if (!uv_is_active((uv_handle_t*)&loop->timer)) { assert(uv_ares_handles_empty(loop)); uv__ares_timer_start(loop); } h = uv__ares_task_create(loop, sock); uv_add_ares_handle(loop, h); } if (read) { ev_io_start(loop->ev, &h->read_watcher); } else { ev_io_stop(loop->ev, &h->read_watcher); } if (write) { ev_io_start(loop->ev, &h->write_watcher); } else { ev_io_stop(loop->ev, &h->write_watcher); } } else { /* * read == 0 and write == 0 this is c-ares's way of notifying us that * the socket is now closed. We must free the data associated with * socket. */ assert(h && "When an ares socket is closed we should have a handle for it"); ev_io_stop(loop->ev, &h->read_watcher); ev_io_stop(loop->ev, &h->write_watcher); uv_remove_ares_handle(h); free(h); if (uv_ares_handles_empty(loop)) { uv__ares_timer_stop(loop); } } }
/* Callback from ares when socket operation is started */ static void uv__ares_sockstate_cb(void* data, ares_socket_t sock, int read, int write) { uv_ares_task_t* h = uv_find_ares_handle(sock); if (read || write) { if (!h) { /* New socket */ /* If this is the first socket then start the timer. */ if (!ev_is_active(&ares_data.timer)) { assert(uv_ares_handles_empty()); ev_timer_again(EV_DEFAULT_UC_ &ares_data.timer); } h = uv__ares_task_create(sock); uv_add_ares_handle(h); } if (read) { ev_io_start(EV_DEFAULT_UC_ &h->read_watcher); } else { ev_io_stop(EV_DEFAULT_UC_ &h->read_watcher); } if (write) { ev_io_start(EV_DEFAULT_UC_ &h->write_watcher); } else { ev_io_stop(EV_DEFAULT_UC_ &h->write_watcher); } } else { /* * read == 0 and write == 0 this is c-ares's way of notifying us that * the socket is now closed. We must free the data associated with * socket. */ assert(h && "When an ares socket is closed we should have a handle for it"); ev_io_stop(EV_DEFAULT_UC_ &h->read_watcher); ev_io_stop(EV_DEFAULT_UC_ &h->write_watcher); uv_remove_ares_handle(h); free(h); if (uv_ares_handles_empty()) { ev_timer_stop(EV_DEFAULT_UC_ &ares_data.timer); } } }
/* * This is called once per second by ares_data.timer. It is used to * constantly callback into c-ares for possibly processing timeouts. */ static void uv__ares_timeout(EV_P_ struct ev_timer* watcher, int revents) { assert(watcher == &ares_data.timer); assert(revents == EV_TIMER); assert(!uv_ares_handles_empty()); ares_process_fd(ares_data.channel, ARES_SOCKET_BAD, ARES_SOCKET_BAD); }
/* * This is called once per second by loop->timer. It is used to * constantly callback into c-ares for possibly processing timeouts. */ static void uv__ares_timeout(uv_timer_t* handle, int status) { assert(!uv_ares_handles_empty(handle->loop)); ares_process_fd(handle->loop->channel, ARES_SOCKET_BAD, ARES_SOCKET_BAD); }