/*! \file select.h * select loop abstraction. */ #pragma once #include #include #include #include /*! \defgroup select Select loop abstraction * @{ * \file select.h */ /*! Indicate interest in reading from the file descriptor */ #define OSMO_FD_READ 0x0001 /*! Indicate interest in writing to the file descriptor */ #define OSMO_FD_WRITE 0x0002 /*! Indicate interest in exceptions from the file descriptor */ #define OSMO_FD_EXCEPT 0x0004 /*! Used as when_mask in osmo_fd_update_when() */ #define OSMO_FD_MASK 0xFFFF /* legacy naming dating back to early OpenBSC / bsc_hack of 2008 */ #define BSC_FD_READ OSMO_FD_READ #define BSC_FD_WRITE OSMO_FD_WRITE #define BSC_FD_EXCEPT OSMO_FD_EXCEPT /*! Structure representing a file dsecriptor */ struct osmo_fd { /*! linked list for internal management */ struct llist_head list; /*! actual operating-system level file decriptor */ int fd; /*! bit-mask or of \ref OSMO_FD_READ, \ref OSMO_FD_WRITE and/or * \ref OSMO_FD_EXCEPT */ unsigned int when; /*! call-back function to be called once file descriptor becomes * available */ int (*cb)(struct osmo_fd *fd, unsigned int what); /*! data pointer passed through to call-back function */ void *data; /*! private number, extending \a data */ unsigned int priv_nr; }; void osmo_fd_setup(struct osmo_fd *ofd, int fd, unsigned int when, int (*cb)(struct osmo_fd *fd, unsigned int what), void *data, unsigned int priv_nr); void osmo_fd_update_when(struct osmo_fd *ofd, unsigned int when_mask, unsigned int when); static inline void osmo_fd_read_enable(struct osmo_fd *ofd) { osmo_fd_update_when(ofd, OSMO_FD_MASK, OSMO_FD_READ); } static inline void osmo_fd_read_disable(struct osmo_fd *ofd) { osmo_fd_update_when(ofd, ~OSMO_FD_READ, 0); } static inline void osmo_fd_write_enable(struct osmo_fd *ofd) { osmo_fd_update_when(ofd, OSMO_FD_MASK, OSMO_FD_WRITE); } static inline void osmo_fd_write_disable(struct osmo_fd *ofd) { osmo_fd_update_when(ofd, ~OSMO_FD_WRITE, 0); } bool osmo_fd_is_registered(struct osmo_fd *fd); int osmo_fd_register(struct osmo_fd *fd); void osmo_fd_unregister(struct osmo_fd *fd); void osmo_fd_close(struct osmo_fd *fd); int osmo_select_main(int polling); int osmo_select_main_ctx(int polling); void osmo_select_init(void); struct osmo_fd *osmo_fd_get_by_fd(int fd); /* * foreign event loop integration */ int osmo_fd_fill_fds(void *readset, void *writeset, void *exceptset); int osmo_fd_disp_fds(void *readset, void *writeset, void *exceptset); /* timerfd integration */ int osmo_timerfd_disable(struct osmo_fd *ofd); int osmo_timerfd_schedule(struct osmo_fd *ofd, const struct timespec *first, const struct timespec *interval); int osmo_timerfd_setup(struct osmo_fd *ofd, int (*cb)(struct osmo_fd *, unsigned int), void *data); /* signalfd integration */ struct osmo_signalfd; struct signalfd_siginfo; typedef void osmo_signalfd_cb(struct osmo_signalfd *osfd, const struct signalfd_siginfo *fdsi); struct osmo_signalfd { struct osmo_fd ofd; sigset_t sigset; osmo_signalfd_cb *cb; void *data; }; struct osmo_signalfd * osmo_signalfd_setup(void *ctx, sigset_t set, osmo_signalfd_cb *cb, void *data); void osmo_select_shutdown_request(void); int osmo_select_shutdown_requested(void); bool osmo_select_shutdown_done(void); /*! @} */