+ if (fd < 0) {
+ return NULL;
+ }
+
+ client_t *tmp = client_acquire();
+ tmp->io.fd = fd;
+ tmp->data = data;
+ tmp->run = runner;
+ tmp->clear_data = NULL;
+ ev_io_init(&tmp->io.io, client_cb, tmp->io.fd, EV_READ);
+ ev_io_start(gl_loop, &tmp->io.io);
+ return tmp;
+}
+
+
+/* Listeners management.
+ */
+
+/* 1 - Allocation */
+
+static listener_t *listener_new(void)
+{
+ listener_t *io = p_new(listener_t, 1);
+ io->io.fd = -1;
+ return io;
+}
+
+static inline void listener_wipe(listener_t *io)
+{
+ server_io_wipe(&io->io);
+}
+
+static inline void listener_delete(listener_t **io)
+{
+ if (*io) {
+ listener_wipe(*io);
+ p_delete(io);
+ }
+}
+
+
+/* 2 - Management */
+
+static void listener_cb(EV_P_ struct ev_io *w, int events)
+{
+ listener_t *server = (listener_t*)w;
+ client_t *tmp;