static int connection_enable_event_sources(Connection *c) { uint32_t a = 0, b = 0; int r; assert(c); if (c->server_to_client_buffer_full > 0) b |= EPOLLOUT; if (c->server_to_client_buffer_full < c->server_to_client_buffer_size) a |= EPOLLIN; if (c->client_to_server_buffer_full > 0) a |= EPOLLOUT; if (c->client_to_server_buffer_full < c->client_to_server_buffer_size) b |= EPOLLIN; if (c->server_event_source) r = sd_event_source_set_io_events(c->server_event_source, a); else if (c->server_fd >= 0) r = sd_event_add_io(c->context->event, &c->server_event_source, c->server_fd, a, traffic_cb, c); else r = 0; if (r < 0) return log_error_errno(r, "Failed to set up server event source: %m"); if (c->client_event_source) r = sd_event_source_set_io_events(c->client_event_source, b); else if (c->client_fd >= 0) r = sd_event_add_io(c->context->event, &c->client_event_source, c->client_fd, b, traffic_cb, c); else r = 0; if (r < 0) return log_error_errno(r, "Failed to set up client event source: %m"); return 0; }
static int curl_glue_socket_callback(CURLM *curl, curl_socket_t s, int action, void *userdata, void *socketp) { sd_event_source *io; CurlGlue *g = userdata; uint32_t events = 0; int r; assert(curl); assert(g); io = hashmap_get(g->ios, FD_TO_PTR(s)); if (action == CURL_POLL_REMOVE) { if (io) { int fd; fd = sd_event_source_get_io_fd(io); assert(fd >= 0); sd_event_source_set_enabled(io, SD_EVENT_OFF); sd_event_source_unref(io); hashmap_remove(g->ios, FD_TO_PTR(s)); hashmap_remove(g->translate_fds, FD_TO_PTR(fd)); safe_close(fd); } return 0; } r = hashmap_ensure_allocated(&g->ios, &trivial_hash_ops); if (r < 0) { log_oom(); return -1; } r = hashmap_ensure_allocated(&g->translate_fds, &trivial_hash_ops); if (r < 0) { log_oom(); return -1; } if (action == CURL_POLL_IN) events = EPOLLIN; else if (action == CURL_POLL_OUT) events = EPOLLOUT; else if (action == CURL_POLL_INOUT) events = EPOLLIN|EPOLLOUT; if (io) { if (sd_event_source_set_io_events(io, events) < 0) return -1; if (sd_event_source_set_enabled(io, SD_EVENT_ON) < 0) return -1; } else { _cleanup_close_ int fd = -1; /* When curl needs to remove an fd from us it closes * the fd first, and only then calls into us. This is * nasty, since we cannot pass the fd on to epoll() * anymore. Hence, duplicate the fds here, and keep a * copy for epoll which we control after use. */ fd = fcntl(s, F_DUPFD_CLOEXEC, 3); if (fd < 0) return -1; if (sd_event_add_io(g->event, &io, fd, events, curl_glue_on_io, g) < 0) return -1; (void) sd_event_source_set_description(io, "curl-io"); r = hashmap_put(g->ios, FD_TO_PTR(s), io); if (r < 0) { log_oom(); sd_event_source_unref(io); return -1; } r = hashmap_put(g->translate_fds, FD_TO_PTR(fd), FD_TO_PTR(s)); if (r < 0) { log_oom(); hashmap_remove(g->ios, FD_TO_PTR(s)); sd_event_source_unref(io); return -1; } fd = -1; } return 0; }