Instead of just passing the watcher to the start function like so:
ev_io_init(&io_watcher);
ev_io_start(EV_A_ &io_watcher);
Make a struct with the watcher as the first member and pass that:
struct client {
ev_io io;
int socket;
};
// ... later ...
struct client *my_client = calloc(1, sizeof(struct client));
my_client->socket = socket;
ev_io_init(&(my_client->io), my_cb, socket, EV_READ);
ev_io_start(EV_A_ &(my_client->io));
// ... later ...
static void my_cb (struct ev_loop *loop, ev_io *w_, int revents) {
struct client *w = (struct client *)w_;
// ...
}
This is what the documentation says to do, and what I use in my own projects.