clibuv

How to know if a handle has been already initialized


The handles in libuv must be initialized before the use.
All of them have an associated uv_<handle>_init function. As an example, uv_timer_t has an associated function uv_timer_init to initialize it.

That said, I noticed that libuv has an undefined behavior if I call more than once the init function for a given handle.
It shows problems once I close the loop and performs a bunch of invalid read/write operations.
Is there a way to know wheter a handle has been already initialized?

As an example, to know if a handle is closing or closed there exists the function uv_is_closing.
Is there a similar function to know if a handle is already initialized?


Solution

  • As suggested here (actually the documentation of libev, but the suggestion applies also to libuv):

    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_;
        // ...
    }
    

    Using a similar approach, we can define a new struct having a boolean parameter that indicates if it has been initialized or not.
    Set it to false during the creation (a factory method could help here) and switch it to true once initialized.