Search code examples
zeromq

How can I shoehorn a regular file descriptor into zmq::poller_t (specifically using cppzmq)?


I've got some existing code that uses template<typename t = no_user_data> class poller_t from cppzmq. It's actually instantiated with t being int, not that it matters.

In libzmq, there is a method zmq_poller_add_fd(void *, int, void *, short) that would allow me to wait on a regular file descriptor as well as the zmq::socket_t objects that are already being used.

I need to add a regular file descriptor to the wait_all of the poller_t object, but unfortunately, I can't see an equivalent feature (equivalent to zmq_poller_add_fd) in cppzmq.

What approaches have people used to get around this?


Solution

  • The answer is that it can't be done using cppzmq facilities, but you can write your own implementation of the poller_t class, because it's FOSS, and just extend it with the additional features that you need. It works a charm.

    The starting point is to copy your version of the implementation of the poller_t template class into a new header file, and then just add the following in the appropriate locations. You may need to make slight modifications to suit, depending on how the cppzmq library evolves. Use using declarations to bring the necessary types into your namespace.

        template<
          typename Dummy = void,
          typename =
            typename std::enable_if<!std::is_same<T, no_user_data>::value, Dummy>::type>
        void add(int fd, event_flags events, T *user_data)
        {
            add_fd_impl(fd, events, user_data);
        }
    
        void add(int fd, event_flags events)
        {
            add_fd_impl(fd, events, nullptr);
        }
    
        void remove(int fd)
        {
            if (0 != zmq_poller_remove_fd(poller_ptr.get(), fd)) {
                throw error_t();
            }
        }
    
        void modify(int fd, event_flags events)
        {
            if (0
                != zmq_poller_modify_fd(poller_ptr.get(), fd,
                                     static_cast<short>(events))) {
                throw error_t();
            }
        }
    
    
        void add_fd_impl(int fd, event_flags events, T *user_data)
        {
            if (0
                != zmq_poller_add_fd(poller_ptr.get(), fd, user_data,
                                  static_cast<short>(events))) {
                throw error_t();
            }
        }