From 9fc5c7c299fc23d66cff8e13063a6cf73f07111c Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Sun, 26 May 2013 15:40:16 +0900 Subject: [PATCH] Adjust priority of outbound DATA frames so that it does not starve others --- lib/spdylay_outbound_item.h | 11 +++++++++++ lib/spdylay_session.c | 16 ++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/lib/spdylay_outbound_item.h b/lib/spdylay_outbound_item.h index 12db6a6f..902c94d8 100644 --- a/lib/spdylay_outbound_item.h +++ b/lib/spdylay_outbound_item.h @@ -50,6 +50,17 @@ typedef struct { spdylay_frame_category frame_cat; void *frame; void *aux_data; + /* Initial priority of this item */ + int inipri; + /* The current priority of this item. Initially, pri equals to + inipri. The item is chosen from the queue based on pri and + seq. For control frames, they consist of just 1 frame and pri + does not change. For DATA frame, they could split up to several + frames. After sending a frame, the pri is increased by 1. If it + becomes more than lowest priority, then it returns back to inipri + and do the same sequence again and again. By doing this, the + higher priority long DATA frames don't starve the lower + prioritized streams. */ int pri; int64_t seq; } spdylay_outbound_item; diff --git a/lib/spdylay_session.c b/lib/spdylay_session.c index f4d6961e..f1247b47 100644 --- a/lib/spdylay_session.c +++ b/lib/spdylay_session.c @@ -444,6 +444,7 @@ int spdylay_session_add_frame(spdylay_session *session, free(item); return r; } + item->inipri = item->pri; return 0; } @@ -1246,6 +1247,20 @@ spdylay_outbound_item* spdylay_session_pop_next_ob_item } } +/* + * Adjust priority of item so that the higher priority long DATA + * frames don't starve lower priority streams. + */ +static void spdylay_outbound_item_adjust_pri(spdylay_session *session, + spdylay_outbound_item *item) +{ + if(item->pri > spdylay_session_get_pri_lowest(session)) { + item->pri = item->inipri; + } else { + ++item->pri; + } +} + /* * Called after a frame is sent. * @@ -1400,6 +1415,7 @@ static int spdylay_session_after_frame_sent(spdylay_session *session) } else { spdylay_outbound_item* next_item; next_item = spdylay_session_get_next_ob_item(session); + spdylay_outbound_item_adjust_pri(session, session->aob.item); /* If priority of this stream is higher or equal to other stream waiting at the top of the queue, we continue to send this data. */