Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Libev - I/O callbacks

I have a chat server in C/Linux using TCP sockets. When using libev I am able to create an ev_io watcher for read events once for a socket. Something like:

ev_io* new_watcher = (ev_io*)malloc(sizeof(ev_io));

//initialize the watcher
ev_init(new_watcher, read_cb);

//set the fd and event to fire on write
ev_io_set(new_watcher, watcher->fd, EV_READ);

//start watching
ev_io_start(loop, new_watcher);

and this works fine because the read event will only fire when there is data to read. However, I have to treat write events differently because they are constantly firing even when I don't have data to write. To solve this problem I have my read_callback create an ev_io watcher for a write data only when there is data ready to be written, and then the write_callback will delete the watcher after it has sent it's message.

This means that I am allocating, initialising, setting, watching, unwatching and deallocating the write watcher each time I need to handle a message. I worry that I may be handling this incorrectly and inefficiently.

What is the best method for handling write_callback events in libev?

Thanks in advance.

like image 699
Josh Brittain Avatar asked Sep 16 '25 09:09

Josh Brittain


1 Answers

Easy, there is also ev_io_stop, so what you do is not start the write watcher unless you have anything to write, and inside the callback, you call ev_io_stop when you have written the whole buffer.

In the common case where you rarely overflow trhe write buffer (because your data is small and you don't wirte too often), you can make this more efficient by trying to write the data directly (if the watcher is not active) and only buffering the data and starting the write watcher if you couldn't completely writee it.

Under the assumptions above, this means you almost never need to start the write watcher. The drawback is vastly more complex code, so in many cases, it's best to start witht he simple "append data to write buffer, start the watcher, inside the watcher stop it if buffer has been written fully" logic.

like image 154
Remember Monica Avatar answered Sep 19 '25 02:09

Remember Monica