Files
libucore/include/ucore/iomux.h
T
2014-10-26 14:27:26 +01:00

154 lines
4.3 KiB
C

#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. Only one event(bit)
* will 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
*
* @return 0 on success, an errno value on error
*/
int iomux_update_events(struct IOMux *mux, struct IOMuxFD *fd, unsigned int what);
/**
* Convenience macro for clearing the new event
*/
#define iomux_clear_event(mux, fd, what_)\
({\
(fd)->what &= ~(what_);\
iomux_update_events((mux), (fd), (fd)->what & ~(what_));\
})
/**
* Convenience macro for adding the new event to the existing events
*/
#define iomux_add_event(mux, fd, what_)\
({\
iomux_update_events((mux), (fd), (fd)->what | (what_));\
})
/** @return a UCTimer instance tied to this mux.
* Used to schedule timers within this mux.
*/
struct UCTimers *iomux_get_timers(struct IOMux *mux);
/** Given an UCTimers associated with an IOMux, return the associated IOMux.
* (the UCTimers must previously been obtained from iomux_get_timers directly,
* or indirectly by the UCTimers provieded in a timer callback handler.
*/
struct IOMux *iomux_from_timers(struct UCTimers *timers);
/** Get the clock associated with the IOMux. This is the clock used
* used to drive the UCTimers associated with this IOMux
*/
struct UCoreClock *iomux_get_clock(struct IOMux *mux);
#ifdef __cplusplus
}
#endif
/** @} (addtogroup)*/
#endif