Skip to content

Commit

Permalink
Don't lose pointer to first nonempty buf in ngx_*_sendfile_chain().
Browse files Browse the repository at this point in the history
In ngx_*_sendfile_chain() when calculating pointer to a first
non-zero sized buf, use "in" as iterator.  This fixes processing
of zero sized buf(s) after EINTR.  Otherwise function can return
zero sized buf to caller, and later ngx_http_write_filter()
logs warning.
  • Loading branch information
Gleb Smirnoff committed Aug 8, 2013
1 parent be27365 commit 65e37b4
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 66 deletions.
30 changes: 14 additions & 16 deletions src/os/unix/ngx_darwin_sendfile_chain.c
Original file line number Diff line number Diff line change
Expand Up @@ -317,38 +317,38 @@ ngx_darwin_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)

c->sent += sent;

for (cl = in; cl; cl = cl->next) {
for ( /* void */ ; in; in = in->next) {

if (ngx_buf_special(cl->buf)) {
if (ngx_buf_special(in->buf)) {
continue;
}

if (sent == 0) {
break;
}

size = ngx_buf_size(cl->buf);
size = ngx_buf_size(in->buf);

if (sent >= size) {
sent -= size;

if (ngx_buf_in_memory(cl->buf)) {
cl->buf->pos = cl->buf->last;
if (ngx_buf_in_memory(in->buf)) {
in->buf->pos = in->buf->last;
}

if (cl->buf->in_file) {
cl->buf->file_pos = cl->buf->file_last;
if (in->buf->in_file) {
in->buf->file_pos = in->buf->file_last;
}

continue;
}

if (ngx_buf_in_memory(cl->buf)) {
cl->buf->pos += (size_t) sent;
if (ngx_buf_in_memory(in->buf)) {
in->buf->pos += (size_t) sent;
}

if (cl->buf->in_file) {
cl->buf->file_pos += sent;
if (in->buf->in_file) {
in->buf->file_pos += sent;
}

break;
Expand All @@ -360,13 +360,11 @@ ngx_darwin_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)

if (!complete) {
wev->ready = 0;
return cl;
return in;
}

if (send >= limit || cl == NULL) {
return cl;
if (send >= limit || in == NULL) {
return in;
}

in = cl;
}
}
34 changes: 16 additions & 18 deletions src/os/unix/ngx_freebsd_sendfile_chain.c
Original file line number Diff line number Diff line change
Expand Up @@ -368,46 +368,46 @@ ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)

c->sent += sent;

for (cl = in; cl; cl = cl->next) {
for ( /* void */ ; in; in = in->next) {

if (ngx_buf_special(cl->buf)) {
if (ngx_buf_special(in->buf)) {
continue;
}

if (sent == 0) {
break;
}

size = ngx_buf_size(cl->buf);
size = ngx_buf_size(in->buf);

if (sent >= size) {
sent -= size;

if (ngx_buf_in_memory(cl->buf)) {
cl->buf->pos = cl->buf->last;
if (ngx_buf_in_memory(in->buf)) {
in->buf->pos = in->buf->last;
}

if (cl->buf->in_file) {
cl->buf->file_pos = cl->buf->file_last;
if (in->buf->in_file) {
in->buf->file_pos = in->buf->file_last;
}

continue;
}

if (ngx_buf_in_memory(cl->buf)) {
cl->buf->pos += (size_t) sent;
if (ngx_buf_in_memory(in->buf)) {
in->buf->pos += (size_t) sent;
}

if (cl->buf->in_file) {
cl->buf->file_pos += sent;
if (in->buf->in_file) {
in->buf->file_pos += sent;
}

break;
}

#if (NGX_HAVE_AIO_SENDFILE)
if (c->busy_sendfile) {
return cl;
return in;
}
#endif

Expand All @@ -421,7 +421,7 @@ ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
*/

wev->ready = 0;
return cl;
return in;
}

if (eintr) {
Expand All @@ -430,13 +430,11 @@ ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)

if (!complete) {
wev->ready = 0;
return cl;
return in;
}

if (send >= limit || cl == NULL) {
return cl;
if (send >= limit || in == NULL) {
return in;
}

in = cl;
}
}
30 changes: 14 additions & 16 deletions src/os/unix/ngx_linux_sendfile_chain.c
Original file line number Diff line number Diff line change
Expand Up @@ -325,38 +325,38 @@ ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)

c->sent += sent;

for (cl = in; cl; cl = cl->next) {
for ( /* void */ ; in; in = in->next) {

if (ngx_buf_special(cl->buf)) {
if (ngx_buf_special(in->buf)) {
continue;
}

if (sent == 0) {
break;
}

size = ngx_buf_size(cl->buf);
size = ngx_buf_size(in->buf);

if (sent >= size) {
sent -= size;

if (ngx_buf_in_memory(cl->buf)) {
cl->buf->pos = cl->buf->last;
if (ngx_buf_in_memory(in->buf)) {
in->buf->pos = in->buf->last;
}

if (cl->buf->in_file) {
cl->buf->file_pos = cl->buf->file_last;
if (in->buf->in_file) {
in->buf->file_pos = in->buf->file_last;
}

continue;
}

if (ngx_buf_in_memory(cl->buf)) {
cl->buf->pos += (size_t) sent;
if (ngx_buf_in_memory(in->buf)) {
in->buf->pos += (size_t) sent;
}

if (cl->buf->in_file) {
cl->buf->file_pos += sent;
if (in->buf->in_file) {
in->buf->file_pos += sent;
}

break;
Expand All @@ -368,13 +368,11 @@ ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)

if (!complete) {
wev->ready = 0;
return cl;
return in;
}

if (send >= limit || cl == NULL) {
return cl;
if (send >= limit || in == NULL) {
return in;
}

in = cl;
}
}
30 changes: 14 additions & 16 deletions src/os/unix/ngx_solaris_sendfilev_chain.c
Original file line number Diff line number Diff line change
Expand Up @@ -207,38 +207,38 @@ ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)

c->sent += sent;

for (cl = in; cl; cl = cl->next) {
for ( /* void */ ; in; in = in->next) {

if (ngx_buf_special(cl->buf)) {
if (ngx_buf_special(in->buf)) {
continue;
}

if (sent == 0) {
break;
}

size = ngx_buf_size(cl->buf);
size = ngx_buf_size(in->buf);

if ((off_t) sent >= size) {
sent = (size_t) ((off_t) sent - size);

if (ngx_buf_in_memory(cl->buf)) {
cl->buf->pos = cl->buf->last;
if (ngx_buf_in_memory(in->buf)) {
in->buf->pos = in->buf->last;
}

if (cl->buf->in_file) {
cl->buf->file_pos = cl->buf->file_last;
if (in->buf->in_file) {
in->buf->file_pos = in->buf->file_last;
}

continue;
}

if (ngx_buf_in_memory(cl->buf)) {
cl->buf->pos += sent;
if (ngx_buf_in_memory(in->buf)) {
in->buf->pos += sent;
}

if (cl->buf->in_file) {
cl->buf->file_pos += sent;
if (in->buf->in_file) {
in->buf->file_pos += sent;
}

break;
Expand All @@ -250,13 +250,11 @@ ngx_solaris_sendfilev_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)

if (!complete) {
wev->ready = 0;
return cl;
return in;
}

if (send >= limit || cl == NULL) {
return cl;
if (send >= limit || in == NULL) {
return in;
}

in = cl;
}
}

0 comments on commit 65e37b4

Please sign in to comment.