#ifndef UC_IO_MUX_H_ #define UC_IO_MUX_H_ #include "timers.h" /** @addtogroup IOMux * @{ * The IOMux is an I/O multiplexer, implementing a main eventloop. * The event loop can be used to register callbacks for activity on * file descriptors such as sockets and pips, and for timers. * * The IOMux is backed either by the select() system call, or the epoll * facility on Linux. Several IOMuxes can run in different threads concurrently, * but note that the IOMux itself is not thread safe so operations in one thread * cannot work on an IOMux running in another thread. * * */ #ifdef __cplusplus extern "C" { #endif #define MUX_EV_READ (1U << 0x00) #define MUX_EV_WRITE (1U << 0x01) //#define MUX_EV_EXCEPT (1 << 0x02) #define MUX_EV_MASK (MUX_EV_READ | MUX_EV_WRITE ) /** * mux implementation to use */ enum IOMUX_TYPE { IOMUX_TYPE_DEFAULT = 0, IOMUX_TYPE_SELECT, IOMUX_TYPE_EPOLL }; /** The IOMux used to issue mux operations. This is to be treated as an opaque * handle. Use iomux_create() or iomux_create_ex() to create an IOMux, register * callbakcs, and call iomux_run() to process the events */ struct IOMux; struct IOMuxFD; /** Callback function used in struct IOMuxFD * @param mux the mux that issued the callback. * @param fd the file desciptor structure. * @param event A bitmask of the MUX_EV_XX values. Both a read and a write event * might be signalled in the same callback */ typedef void (*iomux_cb)(struct IOMux *mux, struct IOMuxFD *fd, unsigned int event); /** Represents a watched file descriptor */ struct IOMuxFD { /** The file descriptor */ int fd; /** The events to watch for, MUX_EV_XX mask */ unsigned int what; /** callback to call on an event */ iomux_cb callback; /** values available to the caller. These will bbe passed * back on the callback */ void *cookie_ptr; int cookie_int; int cookie_int2; }; /** Creates a new IOMux. * * @param type the underlying implementation to use @see IOMUX_TYPE * @return Newly allocated IOMux. NULL if memory allocation fails. */ struct IOMux *iomux_create(enum IOMUX_TYPE type); /** Creates a new IOMux with a user supplied clock * * The supplied clock is used for the UCTimers associated * with the mux. */ struct IOMux *iomux_create_ex(enum IOMUX_TYPE type, struct UCoreClock *uclock); /** Deletes the IOMux and frees its resources. * Can not be called from within a callback */ void iomux_delete(struct IOMux *mux); /** Runs the event loop of the mux * * @return if the number of file descriptors and timers are 0 or * an error occurs */ int iomux_run(struct IOMux *mux); /* Adds a file descriptor to the watch set. * The file descriptor integer value must reside in only * one struct IOMuxFD. Adding e.g. the same file descriptor * in 2 different struct IOMuxFD, one for read events and one for * write events is not supported. * * @return 0 on success, an errno value on error */ int iomux_register_fd(struct IOMux *mux, struct IOMuxFD *fd); /** Removes the file descriptor * * @return 0 on success, an errno value on error */ int iomux_unregister_fd(struct IOMux *mux, struct IOMuxFD *fd); /** Updates the events to watch for in fd->what * @return 0 on success, an errno value on error */ int iomux_update_events(struct IOMux *mux, struct IOMuxFD *fd); /** * Convenience macro for setting the new event */ #define iomux_set_event(mux, fd, what)\ ({\ (fd)->what = (what);\ iomux_update_events((mux), (fd));\ }) /** * Convenience macro for clearing the new event */ #define iomux_clear_event(mux, fd, what)\ ({\ (fd)->what &= ~(what);\ iomux_update_events((mux), (fd));\ }) /** * Convenience macro for adding the new event to the existing events */ #define iomux_add_event(mux, fd, what)\ ({\ (fd)->what &= (what);\ iomux_update_events((mux), (fd));\ }) /** @return a UCTimer instance tied to this mux. * Used to schedule timers within this mux. */ struct UCTimers *iomux_get_timers(struct IOMux *mux); #ifdef __cplusplus } #endif /** @} (addtogroup)*/ #endif