Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fix a long-standing truncated write defect.

When more than one write buffer (iomatrix) was getting used to compose a response, only the first buffer was getting sent.

Instead, try to call writev() again immediately if another iomatrix is pending (until writev() returns EAGAIN or some other error).

This defect has likely been present for a long time, since at least 0cc3309 (2010 Jun 22) when Feersum changed from write() to writev().
  • Loading branch information...
commit fbb3664fb25cf67c2a0f4dde8c7b7dac07435ac6 1 parent 43b1a1f
@stash authored
Showing with 15 additions and 3 deletions.
  1. +15 −3 Feersum.xs
View
18 Feersum.xs
@@ -264,23 +264,29 @@ next_iomatrix (struct feer_conn *c)
struct iomatrix *m;
if (!c->wbuf_rinq) {
+ trace3("next_iomatrix(%d): head\n", c->fd);
add_iomatrix = 1;
}
else {
// get the tail-end struct
m = (struct iomatrix *)c->wbuf_rinq->prev->ref;
- if (m->count >= IOMATRIX_SIZE) {
+ trace3("next_iomatrix(%d): tail, count=%d, offset=%d\n",
+ c->fd, m->count, m->offset);
+ if (m->count >= FEERSUM_IOMATRIX_SIZE) {
add_iomatrix = 1;
}
}
if (add_iomatrix) {
+ trace3("next_iomatrix(%d): malloc\n", c->fd);
Newx(m,1,struct iomatrix);
Poison(m,1,struct iomatrix);
m->offset = m->count = 0;
rinq_push(&c->wbuf_rinq, m);
}
+ trace3("next_iomatrix(%d): end, count=%d, offset=%d\n",
+ c->fd, m->count, m->offset);
return m;
}
@@ -718,6 +724,7 @@ try_conn_write(EV_P_ struct ev_io *w, int revents)
{
dCONN;
int i;
+ struct iomatrix *m;
SvREFCNT_inc_void_NN(c->self);
@@ -752,7 +759,8 @@ try_conn_write(EV_P_ struct ev_io *w, int revents)
if (unlikely(!c->wbuf_rinq)) goto try_write_again;
}
- struct iomatrix *m = (struct iomatrix *)c->wbuf_rinq->ref;
+try_write_again_immediately:
+ m = (struct iomatrix *)c->wbuf_rinq->ref;
#if DEBUG >= 2
warn("going to write to %d:\n",c->fd);
for (i=0; i < m->count; i++) {
@@ -800,9 +808,13 @@ try_conn_write(EV_P_ struct ev_io *w, int revents)
trace2("all done with iomatrix %d state=%d\n",w->fd,c->responding);
rinq_shift(&c->wbuf_rinq);
Safefree(m);
- goto try_write_finished;
+ if (!c->wbuf_rinq)
+ goto try_write_finished;
+ trace2("write again immediately %d state=%d\n",w->fd,c->responding);
+ goto try_write_again_immediately;
}
// else, fallthrough:
+ trace2("write fallthrough %d state=%d\n",w->fd,c->responding);
try_write_again:
trace("write again %d state=%d\n",w->fd,c->responding);
Please sign in to comment.
Something went wrong with that request. Please try again.