diff --git a/include/ucore/wqueue.h b/include/ucore/wqueue.h index 6dcfad2..879434f 100644 --- a/include/ucore/wqueue.h +++ b/include/ucore/wqueue.h @@ -4,9 +4,55 @@ #include "mbuf.h" #include "iomux.h" -typedef int (*wqueue_write_cb)(struct IOMux *mux, struct IOMuxFD *fd, struct MBuf *mbuf); -typedef int (*wqueue_read_cb)(struct IOMux *mux, struct IOMuxFD *fd); +enum UC_WQ_RESULT { + /** INdicates the MBuf was fully processed and can be freed*/ + UC_WQ_DONE = 1, + /** Indicates the MBuf was not fully processed, and will not be freed */ + UC_WQ_UC_PARTIAL = 0, + /** Indicats an error and further processing of the wqueue should not be done*/ + UC_WQ_ABORT = -1 +}; +/** + * Callback that will be called when data can be written to the fd. + * The return value from this function must be strictly followed. + * Write events on an fd will be processed before read events. + * + * For one write event, the callback is called for all mbufs in the queue, + * as long as UC_WQ_DONE is returned. + * + * If UC_WQ_PARTIAL is returned, queue processing is stopped, but any read + * events will also be dispatched. + * If UC_WQ_ABORT is done, no further processing is done, and the wqueue is not + * acccessed any more, making it safe to destroy the wqueue before UC_WQ_ABORY is + * returned. + * + * @param mux associated IOMux + * @param the fd of the current wqueue + * @return UC_WQ_DONE when the entire mbuf was written, and its memory can be released. + * UC_WQ_PARTIAL when partial data was written, the mbuf is not released, + * queue procesing is stopped, and the callback will be passed the same mbuf + * on the next write event, you need to provide a mean to know where to + * start processing the mbuf on the next event. + * UC_WQ_ABORT when all processing, both write and read events should be aborted + * for this event. + * + */ +typedef UC_WQ_RESULT (*wqueue_write_cb)(struct IOMux *mux, struct IOMuxFD *fd, struct MBuf *mbuf); + +/** + * Callback when read events are indicated. + * The return value is currently unused. The wqueue is not accessed after + * this callback returns, making it safe to destroy the wqueue before + * the callback function returns. + * + * @param mux associated IOMux + * @param the fd of the current wqueue + */ +typedef UC_WQ_RESULT (*wqueue_read_cb)(struct IOMux *mux, struct IOMuxFD *fd); + +/** Represents a queue of data to write. + */ struct UCWQueue { struct IOMuxFD fd; struct TailQ queue; @@ -17,10 +63,44 @@ struct UCWQueue { unsigned int queue_len; }; +/** Initialize a wqueue. After this you need to + * set the read_cb, write_cb. Set the fd.fd and fd.event + * and register the fd with the same IOMux as the mux parameter. + * Do not set the fd.callback. + * + * Note that on some IOMux'es the read_cb may be called as + * a result of read events, even if you havn't enabled + * MUX_EV_READ events. + * + * The wqueue manages a queue of MBufs, and will enable write events + * on the IOMux * and call the write_cb when messages are enqueued. + * + * @param wqueue wqueue to initialize + * @param mux the IOMux that you intend to register wqueue->fd on. + */ void uc_wqueue_init(struct UCWQueue *wqueue, struct IOMux *mux); +/** + * Frees all the enqueued mbufs. + * + * @return code from iomux_update_events, when write events need + * to be unregisrted on the IOMux + */ int uc_wqueue_clear(struct UCWQueue *wqueue); +/** + * Enqueues an mbuf onto the wqueue. The wqueue will take ownership + * of the mbuf, and will be responsible for releasing its memory, + * mbuf->entry will be used by the wqueue. + * + * Write events will be enabled on the IOMux, and on write events + * the write_cb is invoked for each message in the queue. + * + * @param wqueueu + * @param mbuf mbuf to enqueue + * @return code from iomux_update_events, when write events need + * to be regisrted on the IOMux + */ int uc_wqueue_enqueue(struct UCWQueue *wqueue, struct MBuf *mbuf); #endif