Skip to content
Browse files

spindly_outdata: use a list of outgoing nodes

Now all functions that generate binary outgoing SPDY protocol data will
fetch a node from the phys->pendq list to generate the binary in and
then add that node last in the phys->outq list. spindly_phys_outgoing()
then returns data from outq and puts the node back in phys->pendq.
  • Loading branch information...
1 parent 0f73954 commit 060559309207020d59de3025fa41312634525b82 @bagder committed
Showing with 60 additions and 38 deletions.
  1. +21 −15 src/spindly_phys.c
  2. +20 −0 src/spindly_phys.h
  3. +19 −13 src/spindly_stream.c
  4. +0 −10 src/spindly_stream.h
View
36 src/spindly_phys.c
@@ -43,6 +43,7 @@ struct spindly_phys *spindly_phys_init(spindly_side_t side,
{
struct spindly_phys *phys;
int rc;
+ struct spindly_outdata *od;
/* this is the first malloc, it should use the malloc function provided in
the config struct if set, but probably cannot use the MALLOC macro */
@@ -67,6 +68,16 @@ struct spindly_phys *spindly_phys_init(spindly_side_t side,
_spindly_list_init(&phys->streams);
_spindly_list_init(&phys->outq);
_spindly_list_init(&phys->inq);
+ _spindly_list_init(&phys->pendq);
+
+ /* now add all outdata nodes to the pending queue */
+ for(rc=0; rc < PHYS_NUM_OUTDATA; rc++) {
+ od = CALLOC(phys, sizeof(struct spindly_outdata));
+ if(!od)
+ goto fail;
+
+ _spindly_list_add(&phys->pendq, &od->node);
+ }
/* init receiver variables */
spdy_frame_init(&phys->frame);
@@ -81,6 +92,8 @@ struct spindly_phys *spindly_phys_init(spindly_side_t side,
spdy_zlib_inflate_end(&phys->zlib_in);
spdy_zlib_inflate_end(&phys->zlib_out);
+ /* TODO: clean up the pendq list */
+
if(phys)
free(phys);
@@ -104,21 +117,14 @@ spindly_error_t spindly_phys_outgoing(struct spindly_phys *phys,
unsigned char **data,
size_t *len)
{
- struct list_node *n = _spindly_list_first(&phys->outq);
- if(n) {
- struct spindly_stream *s= (struct spindly_stream *)
- ((char *)n - offsetof(struct spindly_stream, outnode));
-
- /* iterate over the attached streams and return binary data */
- switch(s->out) {
- case SPDY_CTRL_SYN_STREAM:
- case SPDY_CTRL_SYN_REPLY:
- *data = s->buffer;
- *len = s->outlen;
- /* remove this node from the outgoing queue */
- _spindly_list_remove(&s->outnode);
- break;
- }
+ struct spindly_outdata *od = _spindly_list_first(&phys->outq);
+ if(od) {
+ *data = od->buffer;
+ *len = od->len;
+ /* remove this node from the outgoing queue */
+ _spindly_list_remove(&od->node);
+ /* add this node back to the pending queue */
+ _spindly_list_add(&phys->pendq, &od->node);
}
else {
*data = NULL;
View
20 src/spindly_phys.h
@@ -26,6 +26,23 @@
#include "spdy_frame.h"
+/*
+ * We use a set of pre-allocated structs in a linked list to put data in to
+ * get sent.
+ */
+#define PHYS_NUM_OUTDATA 64 /* number of allocated structs by default */
+#define PHYS_OUTBUFSIZE 128 /* size of buffer that avoids malloc */
+
+struct spindly_outdata {
+ struct list_node node;
+ size_t len; /* number of bytes of data provided */
+ unsigned char *alloced; /* if not NULL, an allocated pointer with data
+ instead of buffer */
+ unsigned char buffer[PHYS_OUTBUFSIZE];
+ struct spindly_stream *stream; /* originating stream */
+};
+
+
struct spindly_indata {
struct list_node node;
void *identifier;
@@ -50,6 +67,9 @@ struct spindly_phys
struct list_head inq;
size_t inq_size; /* total number of bytes in the queue */
+ /* list of spindly_outdata nodes that are unused */
+ struct list_head pendq;
+
/* state variables for the parsing and demuxing of single incoming data
stream */
spdy_frame frame;
View
32 src/spindly_stream.c
@@ -71,9 +71,7 @@ spindly_error_t _spindly_stream_init(struct spindly_phys *phys,
if(!madebypeer) {
/* only send a SYN_STREAM if this stream is not the result of a received
SYN_STREAM from the peer */
-
- /* mark the current action */
- s->out = SPDY_CTRL_SYN_STREAM;
+ struct spindly_outdata *od;
/* make it a SYN_STREAM frame.
@@ -95,14 +93,20 @@ spindly_error_t _spindly_stream_init(struct spindly_phys *phys,
if(rc)
goto fail;
+ /* get an out buffer, TODO: what if drained? */
+ od = _spindly_list_first(&phys->pendq);
+
/* pack a control frame to the output buffer */
- rc = spdy_control_frame_pack(s->buffer, sizeof(s->buffer),
- &s->outlen, &ctrl_frame);
+ rc = spdy_control_frame_pack(od->buffer, PHYS_OUTBUFSIZE,
+ &od->len, &ctrl_frame);
+
if(rc)
goto fail;
+ od->stream = s;
+
/* add this handle to the outq */
- _spindly_list_add(&phys->outq, &s->outnode);
+ _spindly_list_add(&phys->outq, &od->node);
}
/* append this stream to the list of streams held by the phys handle */
@@ -154,14 +158,11 @@ static spindly_error_t stream_acknack(struct spindly_stream *s, bool ack)
{
spindly_error_t rc = SPINDLYE_OK;
spdy_control_frame ctrl_frame;
+ struct spindly_outdata *od;
assert(s != NULL);
/* queue up a SYN_REPLY or RST_STREAM message */
-
- /* mark the current action */
- s->out = ack?SPDY_CTRL_SYN_REPLY:SPDY_CTRL_RST_STREAM;
-
if(ack)
rc = spdy_control_mk_syn_reply(&ctrl_frame, s->streamid, NULL);
else
@@ -170,14 +171,19 @@ static spindly_error_t stream_acknack(struct spindly_stream *s, bool ack)
if(rc)
goto fail;
+ /* get an out buffer TODO: what if drained? */
+ od = _spindly_list_first(&s->phys->pendq);
+
/* pack a control frame to the output buffer */
- rc = spdy_control_frame_pack(s->buffer, sizeof(s->buffer),
- &s->outlen, &ctrl_frame);
+ rc = spdy_control_frame_pack(od->buffer, PHYS_OUTBUFSIZE,
+ &od->len, &ctrl_frame);
if(rc)
goto fail;
+ od->stream = s;
+
/* add this handle to the outq */
- _spindly_list_add(&s->phys->outq, &s->outnode);
+ _spindly_list_add(&s->phys->outq, &od->node);
fail:
return rc;
View
10 src/spindly_stream.h
@@ -23,8 +23,6 @@
#include "spdy_zlib.h"
#include "spdy_stream.h"
-#define STREAM_BUFSIZE 32 /* scratch buffer for generated frame contents */
-
enum stream_state
{
STREAM_NEW, /* as before the peer has ACKed it */
@@ -44,17 +42,9 @@ struct spindly_stream
void *userp; /* set in stream_new() */
unsigned int prio; /* 0 - 7 */
- int out; /* when this handle is added to the outq, this field will hold the
- hint of what to send */
- size_t outlen; /* number of bytes in 'buffer' that is stored and ready to
- get sent off */
- struct list_node outnode;
-
struct spindly_stream_config *config;
spdy_stream spdy;
-
- unsigned char buffer[STREAM_BUFSIZE];
};
#define PRIO_MAX 7

0 comments on commit 0605593

Please sign in to comment.
Something went wrong with that request. Please try again.