mirror of
https://github.com/nginx/nginx.git
synced 2024-12-02 11:49:01 +08:00
Refactored ngx_linux_sendfile_chain() even more.
The code that calls sendfile() was cut into a separate function. This simplifies EINTR processing, yet is needed for the following changes that add threads support.
This commit is contained in:
parent
a0d543595d
commit
ea881578a2
@ -10,6 +10,10 @@
|
|||||||
#include <ngx_event.h>
|
#include <ngx_event.h>
|
||||||
|
|
||||||
|
|
||||||
|
static ssize_t ngx_linux_sendfile(ngx_connection_t *c, ngx_buf_t *file,
|
||||||
|
size_t size);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* On Linux up to 2.4.21 sendfile() (syscall #187) works with 32-bit
|
* On Linux up to 2.4.21 sendfile() (syscall #187) works with 32-bit
|
||||||
* offsets only, and the including <sys/sendfile.h> breaks the compiling,
|
* offsets only, and the including <sys/sendfile.h> breaks the compiling,
|
||||||
@ -36,16 +40,10 @@ ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
|
|||||||
ssize_t n;
|
ssize_t n;
|
||||||
ngx_err_t err;
|
ngx_err_t err;
|
||||||
ngx_buf_t *file;
|
ngx_buf_t *file;
|
||||||
ngx_uint_t eintr;
|
|
||||||
ngx_event_t *wev;
|
ngx_event_t *wev;
|
||||||
ngx_chain_t *cl;
|
ngx_chain_t *cl;
|
||||||
ngx_iovec_t header;
|
ngx_iovec_t header;
|
||||||
struct iovec headers[NGX_IOVS_PREALLOCATE];
|
struct iovec headers[NGX_IOVS_PREALLOCATE];
|
||||||
#if (NGX_HAVE_SENDFILE64)
|
|
||||||
off_t offset;
|
|
||||||
#else
|
|
||||||
int32_t offset;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
wev = c->write;
|
wev = c->write;
|
||||||
|
|
||||||
@ -67,7 +65,6 @@ ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
|
|||||||
header.nalloc = NGX_IOVS_PREALLOCATE;
|
header.nalloc = NGX_IOVS_PREALLOCATE;
|
||||||
|
|
||||||
for ( ;; ) {
|
for ( ;; ) {
|
||||||
eintr = 0;
|
|
||||||
prev_send = send;
|
prev_send = send;
|
||||||
|
|
||||||
/* create the iovec and coalesce the neighbouring bufs */
|
/* create the iovec and coalesce the neighbouring bufs */
|
||||||
@ -161,43 +158,13 @@ ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
|
|||||||
return NGX_CHAIN_ERROR;
|
return NGX_CHAIN_ERROR;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if (NGX_HAVE_SENDFILE64)
|
n = ngx_linux_sendfile(c, file, file_size);
|
||||||
offset = file->file_pos;
|
|
||||||
#else
|
|
||||||
offset = (int32_t) file->file_pos;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
if (n == NGX_ERROR) {
|
||||||
"sendfile: @%O %uz", file->file_pos, file_size);
|
return NGX_CHAIN_ERROR;
|
||||||
|
|
||||||
n = sendfile(c->fd, file->file->fd, &offset, file_size);
|
|
||||||
|
|
||||||
if (n == -1) {
|
|
||||||
err = ngx_errno;
|
|
||||||
|
|
||||||
switch (err) {
|
|
||||||
case NGX_EAGAIN:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NGX_EINTR:
|
|
||||||
eintr = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
wev->error = 1;
|
|
||||||
ngx_connection_error(c, err, "sendfile() failed");
|
|
||||||
return NGX_CHAIN_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
|
|
||||||
"sendfile() is not ready");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sent = n > 0 ? n : 0;
|
sent = (n == NGX_AGAIN) ? 0 : n;
|
||||||
|
|
||||||
ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
|
||||||
"sendfile: %z, @%O %O:%uz",
|
|
||||||
n, file->file_pos, sent, file_size);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
n = ngx_writev(c, &header);
|
n = ngx_writev(c, &header);
|
||||||
@ -213,11 +180,6 @@ ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
|
|||||||
|
|
||||||
in = ngx_chain_update_sent(in, sent);
|
in = ngx_chain_update_sent(in, sent);
|
||||||
|
|
||||||
if (eintr) {
|
|
||||||
send = prev_send;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (send - prev_send != sent) {
|
if (send - prev_send != sent) {
|
||||||
wev->ready = 0;
|
wev->ready = 0;
|
||||||
return in;
|
return in;
|
||||||
@ -228,3 +190,55 @@ ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static ssize_t
|
||||||
|
ngx_linux_sendfile(ngx_connection_t *c, ngx_buf_t *file, size_t size)
|
||||||
|
{
|
||||||
|
#if (NGX_HAVE_SENDFILE64)
|
||||||
|
off_t offset;
|
||||||
|
#else
|
||||||
|
int32_t offset;
|
||||||
|
#endif
|
||||||
|
ssize_t n;
|
||||||
|
ngx_err_t err;
|
||||||
|
|
||||||
|
#if (NGX_HAVE_SENDFILE64)
|
||||||
|
offset = file->file_pos;
|
||||||
|
#else
|
||||||
|
offset = (int32_t) file->file_pos;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
eintr:
|
||||||
|
|
||||||
|
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||||
|
"sendfile: @%O %uz", file->file_pos, size);
|
||||||
|
|
||||||
|
n = sendfile(c->fd, file->file->fd, &offset, size);
|
||||||
|
|
||||||
|
if (n == -1) {
|
||||||
|
err = ngx_errno;
|
||||||
|
|
||||||
|
switch (err) {
|
||||||
|
case NGX_EAGAIN:
|
||||||
|
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
|
||||||
|
"sendfile() is not ready");
|
||||||
|
return NGX_AGAIN;
|
||||||
|
|
||||||
|
case NGX_EINTR:
|
||||||
|
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
|
||||||
|
"sendfile() was interrupted");
|
||||||
|
goto eintr;
|
||||||
|
|
||||||
|
default:
|
||||||
|
c->write->error = 1;
|
||||||
|
ngx_connection_error(c, err, "sendfile() failed");
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, "sendfile: %z of %uz @%O",
|
||||||
|
n, size, file->file_pos);
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user