Search code examples
ciolibev

libev pass argument to callback


When we call ev_io_init we give it a function address that has (struct ev_loop*, struct ev_io, int) parameters but how we can make parameters like (struct ev_loop*, struct ev_io, int, void *ptr) and make ev_io_init call it with constant ptr value?

I know how to carry extra data from struct ev_io* but saving same data for every different event is not good way i guess


Solution

  • From the documentation:

    ASSOCIATING CUSTOM DATA WITH A WATCHER

    Each watcher has, by default, a void *data member that you can read or modify at any time: libev will completely ignore it. This can be used to associate arbitrary data with your watcher. If you need more data and don't want to allocate memory separately and store a pointer to it in that data member, you can also "subclass" the watcher type and provide your own data:

    struct my_io
    {
      ev_io io;
      int otherfd;
      void *somedata;
      struct whatever *mostinteresting;
    };
    
    ...
    struct my_io w;
    ev_io_init (&w.io, my_cb, fd, EV_READ);
    

    And since your callback will be called with a pointer to the watcher, you can cast it back to your own type:

    static void my_cb (struct ev_loop *loop, ev_io *w_, int revents)   
    {
      struct my_io *w = (struct my_io *)w_;
      ...
    }
    

    More interesting and less C-conformant ways of casting your callback function type instead have been omitted.

    Since you just want to pass one pointer, the easiest way is definitely just sticking it in the data field.