aboutsummaryrefslogtreecommitdiffstats
path: root/libglouglou/sendbuf.c
diff options
context:
space:
mode:
Diffstat (limited to 'libglouglou/sendbuf.c')
-rw-r--r--libglouglou/sendbuf.c95
1 files changed, 57 insertions, 38 deletions
diff --git a/libglouglou/sendbuf.c b/libglouglou/sendbuf.c
index 078d6a6..7571cc4 100644
--- a/libglouglou/sendbuf.c
+++ b/libglouglou/sendbuf.c
@@ -1,32 +1,33 @@
+#include <stdlib.h>
+#include <string.h>
+
#include "sendbuf.h"
+static int flushbuf(struct sendbuf *);
+static void cb_timer(evutil_socket_t, short, void *);
+
/*
* Public
*/
/*
* Create a sendbuf
- * send_func should return the number of successfuly sent bytes
*/
struct sendbuf *
-sendbuf_init(struct event_base *ev_base, int size, int sndbuf_max, int msec_max,
- int (*send_func)(void *, int, void *), void *usrdata)
+sendbuf_new(struct event_base *ev_base, int buffer_size, int msec_max,
+ int (*send_func)(void *, int, void *), void *usrdata)
{
struct sendbuf *sbuf = NULL;
- struct event ev_timer;
- struct timeval *tv;
- void *buffer;
- void *data;
+ struct event *ev_timer;
sbuf = calloc(1, sizeof(struct sendbuf));
if (!sbuf)
return NULL;
sbuf->ev_base = ev_base;
- sbuf->sndbuf_max = sndbuf_max;
sbuf->msec_max = msec_max;
- sbuf->usrdata = usrdata;
+ sbuf->buffer_size = buffer_size;
sbuf->send_func = send_func;
- sbuf->buffer_size = size;
+ sbuf->usrdata = usrdata;
sbuf->buffer = malloc(sbuf->buffer_size);
if (!sbuf->buffer)
goto err;
@@ -34,20 +35,20 @@ sendbuf_init(struct event_base *ev_base, int size, int sndbuf_max, int msec_max,
ev_timer = evtimer_new(ev_base, cb_timer, sbuf);
sbuf->ev_timer = ev_timer;
sbuf->ev_timer_tv.tv_usec = msec_max * 1000;
- evtimer_add(ev, &sbuf->ev_timer_tv);
+ evtimer_add(ev_timer, &sbuf->ev_timer_tv);
return sbuf;
err:
- sendbuf_shutdown(sbuf);
+ sendbuf_free(sbuf);
return NULL;
}
void
-sendbuf_shutdown(struct sendbuf *sbuf)
+sendbuf_free(struct sendbuf *sbuf)
{
- if (sbuf->send_timer)
- event_del(sbuf->send_timer);
+ if (sbuf->ev_timer)
+ event_del(sbuf->ev_timer);
if (sbuf->buffer && sbuf->send_func)
flushbuf(sbuf);
if (sbuf->buffer)
@@ -56,17 +57,41 @@ sendbuf_shutdown(struct sendbuf *sbuf)
}
/*
- * Returns a buffer to write data to be sent
+ * Append to the token buffer data to be sent
+ * uses a memcpy, in contrary to sendbuf_gettoken().
+ * return size on success, -1 on error
+ */
+int
+sendbuf_append(struct sendbuf *sbuf, void *token, int size)
+{
+ if (sbuf->buffer_pos + size >= sbuf->buffer_size)
+ if (flushbuf(sbuf) == -1)
+ return -1;
+
+ memcpy(sbuf->buffer + sbuf->buffer_pos, token, size);
+ sbuf->buffer_pos = sbuf->buffer_pos + size;
+
+ return size;
+}
+
+/*
+ * Returns a token buffer to write data to be sent
+ * avoids memcpy, in contrary to sendbuf_append().
* might return NULL if the sendbuf is temporary full
*/
void *
-sendbuf_getoken(struct sendbuf *sbuf, int size)
+sendbuf_gettoken(struct sendbuf *sbuf, int size)
{
+ void *token;
+
if (sbuf->buffer_pos + size >= sbuf->buffer_size)
if (flushbuf(sbuf) == -1)
return NULL;
- return sbuf->buffer_pos;
+ token = sbuf->buffer + sbuf->buffer_pos;
+ sbuf->buffer_pos = sbuf->buffer_pos + size;
+
+ return token;
}
/*
@@ -77,36 +102,30 @@ sendbuf_getoken(struct sendbuf *sbuf, int size)
* Note that you can still add data to the buffer even if flushing is in
* progress
*/
-int
+static int
flushbuf(struct sendbuf *sbuf)
{
- int sent;
- int sent_total;
- int len;
+ int tosend, sent;
sbuf->flushing = 1;
- do {
- pos = sbuf->buffer + sbuf->flushed_len;
- if (sbuf->buffer_pos > sbuf->sndbuf_max)
- tosend = sbuf->sndbuf_max;
- else
- tosend = sbuf->buffer_pos;
- sent = sbuf->send_func(sbuf->buffer + pos, tosend, sbuf->usrdata);
- sbuf->flushed_len = sbuf->flushed_len + sent;
- if (sent == -1) {
- // XXX handle erorr
- } else if (sent < tosend) {
- return -1;
- }
- } while (sbuf->flushed_len < sbuf->buffer_pos)
+ tosend = sbuf->buffer_size - sbuf->flushing_pos;
+ sent = sbuf->send_func(sbuf->buffer + sbuf->flushing_pos,
+ tosend, sbuf->usrdata);
+ if (sent == -1) {
+ // XXX handle error
+ return -1;
+ } else if (sent < tosend) {
+ sbuf->flushing_pos = sbuf->flushing_pos + sent;
+ return -1;
+ }
sbuf->flushing = 0;
- sbuf->flushed_len = 0;
+ sbuf->flushing_pos = 0;
return 0;
}
-void
+static void
cb_timer(evutil_socket_t fd, short what, void *arg)
{
struct sendbuf *sbuf;