Skip to content

Commit

Permalink
spindly_outdata: use a list of outgoing nodes
Browse files Browse the repository at this point in the history
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
bagder committed Feb 17, 2012
1 parent 0f73954 commit 0605593
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 38 deletions.
36 changes: 21 additions & 15 deletions src/spindly_phys.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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);
Expand All @@ -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);

Expand All @@ -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;
Expand Down
20 changes: 20 additions & 0 deletions src/spindly_phys.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
32 changes: 19 additions & 13 deletions src/spindly_stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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 */
Expand Down Expand Up @@ -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
Expand All @@ -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;
Expand Down
10 changes: 0 additions & 10 deletions src/spindly_stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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
Expand Down

0 comments on commit 0605593

Please sign in to comment.