/* This software was written by Dirk Engling It is considered beerware. Prost. Skol. Cheers or whatever. $id$ */ #ifndef OT_BATCH_H__ #define OT_BATCH_H__ #include #include #include /* A queue of buffers on their way to one socket. The batch owns every buffer handed to it and frees each one as soon as it has left, so a client that reads slowly costs memory only for what it has not received yet. A zeroed ot_batch is ready to use. */ typedef struct { struct iovec *entries; size_t space; size_t count; size_t first; /* entries before this one are sent and freed */ size_t offset; /* bytes of entries[first] already sent */ } ot_batch; static inline int batch_pending(const ot_batch *batch) { return batch->first != batch->count; } /* What batch_send reports instead of a byte count */ enum { BATCH_DONE = 0, BATCH_AGAIN = -1, BATCH_FAILED = -2 }; /* Queue buf and take ownership of it. Returns 0, or -1 having freed buf. */ int batch_add(ot_batch *batch, void *buf, size_t len); /* Write as much as the socket takes. Returns the number of bytes written, or BATCH_DONE, BATCH_AGAIN or BATCH_FAILED. */ ssize_t batch_send(int s, ot_batch *batch); /* Queue every entry of a vector, taking ownership of each buffer but not of the vector itself. Returns 0, or -1 having freed all of them. */ int batch_add_vector(ot_batch *batch, const struct iovec *entries, size_t count); /* Queue a copy of buf, which the batch then owns. Returns 0, or -1. */ int batch_add_copy(ot_batch *batch, const void *buf, size_t len); /* Free whatever has not left yet, along with the batch's own array */ void batch_reset(ot_batch *batch); #endif