summaryrefslogtreecommitdiff
path: root/ot_batch.h
blob: c85567171ac77d6e6fc12e8a78065449b0159da7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/* This software was written by Dirk Engling <erdgeist@erdgeist.org>
   It is considered beerware. Prost. Skol. Cheers or whatever.

   $id$ */

#ifndef OT_BATCH_H__
#define OT_BATCH_H__

#include <stddef.h>
#include <sys/types.h>
#include <sys/uio.h>

/* 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