nginxtra 1.6.3.9 → 1.8.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (181) hide show
  1. checksums.yaml +4 -4
  2. data/bin/nginxtra +1 -1
  3. data/bin/nginxtra_rails +1 -1
  4. data/lib/nginxtra/version.rb +1 -1
  5. data/vendor/nginx/CHANGES +358 -14
  6. data/vendor/nginx/CHANGES.ru +372 -18
  7. data/vendor/nginx/LICENSE +2 -2
  8. data/vendor/nginx/auto/cc/clang +5 -0
  9. data/vendor/nginx/auto/cc/gcc +5 -0
  10. data/vendor/nginx/auto/lib/google-perftools/conf +1 -1
  11. data/vendor/nginx/auto/lib/openssl/make +0 -5
  12. data/vendor/nginx/auto/lib/perl/conf +9 -1
  13. data/vendor/nginx/auto/make +1 -1
  14. data/vendor/nginx/auto/modules +11 -0
  15. data/vendor/nginx/auto/options +10 -2
  16. data/vendor/nginx/auto/os/darwin +0 -1
  17. data/vendor/nginx/auto/os/freebsd +6 -23
  18. data/vendor/nginx/auto/sources +16 -14
  19. data/vendor/nginx/auto/summary +3 -24
  20. data/vendor/nginx/auto/threads +20 -0
  21. data/vendor/nginx/auto/types/sizeof +2 -12
  22. data/vendor/nginx/auto/unix +50 -6
  23. data/vendor/nginx/configure +5 -0
  24. data/vendor/nginx/contrib/vim/syntax/nginx.vim +183 -50
  25. data/vendor/nginx/src/core/nginx.c +21 -9
  26. data/vendor/nginx/src/core/nginx.h +8 -2
  27. data/vendor/nginx/src/core/ngx_buf.c +88 -0
  28. data/vendor/nginx/src/core/ngx_buf.h +15 -1
  29. data/vendor/nginx/src/core/ngx_conf_file.c +4 -1
  30. data/vendor/nginx/src/core/ngx_connection.c +25 -66
  31. data/vendor/nginx/src/core/ngx_connection.h +1 -3
  32. data/vendor/nginx/src/core/ngx_core.h +11 -3
  33. data/vendor/nginx/src/core/ngx_crypt.c +1 -1
  34. data/vendor/nginx/src/core/ngx_cycle.c +7 -1
  35. data/vendor/nginx/src/core/ngx_cycle.h +6 -2
  36. data/vendor/nginx/src/core/ngx_file.c +13 -5
  37. data/vendor/nginx/src/core/ngx_file.h +6 -0
  38. data/vendor/nginx/src/core/ngx_log.c +215 -21
  39. data/vendor/nginx/src/core/ngx_log.h +9 -1
  40. data/vendor/nginx/src/core/ngx_output_chain.c +104 -15
  41. data/vendor/nginx/src/core/ngx_palloc.c +3 -7
  42. data/vendor/nginx/src/core/ngx_rbtree.c +2 -4
  43. data/vendor/nginx/src/core/ngx_rbtree.h +2 -4
  44. data/vendor/nginx/src/core/ngx_regex.c +14 -6
  45. data/vendor/nginx/src/core/ngx_resolver.c +16 -23
  46. data/vendor/nginx/src/core/ngx_resolver.h +8 -7
  47. data/vendor/nginx/src/core/ngx_shmtx.c +1 -1
  48. data/vendor/nginx/src/core/ngx_slab.c +89 -2
  49. data/vendor/nginx/src/core/ngx_slab.h +3 -0
  50. data/vendor/nginx/src/core/ngx_string.c +58 -2
  51. data/vendor/nginx/src/core/ngx_string.h +1 -0
  52. data/vendor/nginx/src/core/ngx_syslog.c +374 -0
  53. data/vendor/nginx/src/core/ngx_syslog.h +30 -0
  54. data/vendor/nginx/src/core/ngx_thread_pool.c +630 -0
  55. data/vendor/nginx/src/core/ngx_thread_pool.h +36 -0
  56. data/vendor/nginx/src/core/ngx_times.c +19 -2
  57. data/vendor/nginx/src/core/ngx_times.h +1 -0
  58. data/vendor/nginx/src/event/modules/ngx_aio_module.c +1 -1
  59. data/vendor/nginx/src/event/modules/ngx_devpoll_module.c +9 -24
  60. data/vendor/nginx/src/event/modules/ngx_epoll_module.c +152 -28
  61. data/vendor/nginx/src/event/modules/ngx_eventport_module.c +43 -25
  62. data/vendor/nginx/src/event/modules/ngx_kqueue_module.c +86 -156
  63. data/vendor/nginx/src/event/modules/ngx_poll_module.c +21 -37
  64. data/vendor/nginx/src/event/modules/ngx_rtsig_module.c +15 -27
  65. data/vendor/nginx/src/event/modules/ngx_select_module.c +10 -12
  66. data/vendor/nginx/src/event/modules/ngx_win32_select_module.c +7 -9
  67. data/vendor/nginx/src/event/ngx_event.c +5 -33
  68. data/vendor/nginx/src/event/ngx_event.h +15 -50
  69. data/vendor/nginx/src/event/ngx_event_accept.c +11 -10
  70. data/vendor/nginx/src/event/ngx_event_connect.c +0 -11
  71. data/vendor/nginx/src/event/ngx_event_connect.h +1 -4
  72. data/vendor/nginx/src/event/ngx_event_openssl.c +622 -38
  73. data/vendor/nginx/src/event/ngx_event_openssl.h +20 -2
  74. data/vendor/nginx/src/event/ngx_event_openssl_stapling.c +5 -1
  75. data/vendor/nginx/src/event/ngx_event_pipe.c +45 -19
  76. data/vendor/nginx/src/event/ngx_event_pipe.h +3 -0
  77. data/vendor/nginx/src/event/ngx_event_posted.c +7 -145
  78. data/vendor/nginx/src/event/ngx_event_posted.h +12 -39
  79. data/vendor/nginx/src/event/ngx_event_timer.c +50 -70
  80. data/vendor/nginx/src/event/ngx_event_timer.h +2 -14
  81. data/vendor/nginx/src/http/modules/ngx_http_addition_filter_module.c +1 -1
  82. data/vendor/nginx/src/http/modules/ngx_http_autoindex_module.c +416 -71
  83. data/vendor/nginx/src/http/modules/ngx_http_charset_filter_module.c +19 -15
  84. data/vendor/nginx/src/http/modules/ngx_http_dav_module.c +16 -4
  85. data/vendor/nginx/src/http/modules/ngx_http_fastcgi_module.c +601 -134
  86. data/vendor/nginx/src/http/modules/ngx_http_geo_module.c +1 -1
  87. data/vendor/nginx/src/http/modules/ngx_http_geoip_module.c +9 -3
  88. data/vendor/nginx/src/http/modules/ngx_http_gunzip_filter_module.c +9 -3
  89. data/vendor/nginx/src/http/modules/ngx_http_gzip_filter_module.c +9 -3
  90. data/vendor/nginx/src/http/modules/ngx_http_gzip_static_module.c +0 -2
  91. data/vendor/nginx/src/http/modules/ngx_http_headers_filter_module.c +197 -91
  92. data/vendor/nginx/src/http/modules/ngx_http_image_filter_module.c +1 -0
  93. data/vendor/nginx/src/http/modules/ngx_http_limit_conn_module.c +65 -162
  94. data/vendor/nginx/src/http/modules/ngx_http_limit_req_module.c +53 -67
  95. data/vendor/nginx/src/http/modules/ngx_http_log_module.c +128 -23
  96. data/vendor/nginx/src/http/modules/ngx_http_memcached_module.c +25 -6
  97. data/vendor/nginx/src/http/modules/ngx_http_mp4_module.c +1 -1
  98. data/vendor/nginx/src/http/modules/ngx_http_not_modified_filter_module.c +39 -13
  99. data/vendor/nginx/src/http/modules/ngx_http_proxy_module.c +697 -141
  100. data/vendor/nginx/src/http/modules/ngx_http_rewrite_module.c +5 -1
  101. data/vendor/nginx/src/http/modules/ngx_http_scgi_module.c +282 -125
  102. data/vendor/nginx/src/http/modules/ngx_http_ssi_filter_module.c +4 -1
  103. data/vendor/nginx/src/http/modules/ngx_http_ssl_module.c +44 -1
  104. data/vendor/nginx/src/http/modules/ngx_http_ssl_module.h +2 -0
  105. data/vendor/nginx/src/http/modules/ngx_http_stub_status_module.c +10 -8
  106. data/vendor/nginx/src/http/modules/ngx_http_sub_filter_module.c +18 -3
  107. data/vendor/nginx/src/http/modules/ngx_http_upstream_hash_module.c +641 -0
  108. data/vendor/nginx/src/http/modules/ngx_http_upstream_ip_hash_module.c +1 -1
  109. data/vendor/nginx/src/http/modules/ngx_http_upstream_keepalive_module.c +3 -21
  110. data/vendor/nginx/src/http/modules/ngx_http_upstream_least_conn_module.c +0 -5
  111. data/vendor/nginx/src/http/modules/ngx_http_uwsgi_module.c +449 -125
  112. data/vendor/nginx/src/http/modules/ngx_http_xslt_filter_module.c +4 -2
  113. data/vendor/nginx/src/http/modules/perl/ngx_http_perl_module.c +2 -1
  114. data/vendor/nginx/src/http/ngx_http.c +10 -5
  115. data/vendor/nginx/src/http/ngx_http.h +4 -4
  116. data/vendor/nginx/src/http/ngx_http_cache.h +26 -1
  117. data/vendor/nginx/src/http/ngx_http_copy_filter_module.c +109 -68
  118. data/vendor/nginx/src/http/ngx_http_core_module.c +191 -46
  119. data/vendor/nginx/src/http/ngx_http_core_module.h +16 -4
  120. data/vendor/nginx/src/http/ngx_http_file_cache.c +584 -67
  121. data/vendor/nginx/src/http/ngx_http_parse.c +55 -4
  122. data/vendor/nginx/src/http/ngx_http_request.c +14 -6
  123. data/vendor/nginx/src/http/ngx_http_request.h +12 -4
  124. data/vendor/nginx/src/http/ngx_http_request_body.c +114 -28
  125. data/vendor/nginx/src/http/ngx_http_spdy.c +383 -229
  126. data/vendor/nginx/src/http/ngx_http_spdy.h +8 -5
  127. data/vendor/nginx/src/http/ngx_http_spdy_filter_module.c +12 -4
  128. data/vendor/nginx/src/http/ngx_http_special_response.c +2 -2
  129. data/vendor/nginx/src/http/ngx_http_upstream.c +808 -132
  130. data/vendor/nginx/src/http/ngx_http_upstream.h +33 -3
  131. data/vendor/nginx/src/http/ngx_http_upstream_round_robin.c +72 -65
  132. data/vendor/nginx/src/http/ngx_http_upstream_round_robin.h +1 -2
  133. data/vendor/nginx/src/http/ngx_http_variables.c +47 -3
  134. data/vendor/nginx/src/http/ngx_http_write_filter_module.c +15 -6
  135. data/vendor/nginx/src/mail/ngx_mail.c +2 -3
  136. data/vendor/nginx/src/mail/ngx_mail.h +2 -0
  137. data/vendor/nginx/src/mail/ngx_mail_auth_http_module.c +140 -11
  138. data/vendor/nginx/src/mail/ngx_mail_core_module.c +3 -3
  139. data/vendor/nginx/src/mail/ngx_mail_handler.c +79 -2
  140. data/vendor/nginx/src/mail/ngx_mail_imap_module.c +3 -1
  141. data/vendor/nginx/src/mail/ngx_mail_pop3_module.c +3 -1
  142. data/vendor/nginx/src/mail/ngx_mail_smtp_module.c +3 -1
  143. data/vendor/nginx/src/mail/ngx_mail_ssl_module.c +125 -1
  144. data/vendor/nginx/src/mail/ngx_mail_ssl_module.h +8 -0
  145. data/vendor/nginx/src/misc/ngx_cpp_test_module.cpp +1 -1
  146. data/vendor/nginx/src/os/unix/ngx_aio_read_chain.c +1 -1
  147. data/vendor/nginx/src/os/unix/ngx_channel.c +0 -7
  148. data/vendor/nginx/src/os/unix/ngx_darwin_config.h +0 -3
  149. data/vendor/nginx/src/os/unix/ngx_darwin_sendfile_chain.c +44 -208
  150. data/vendor/nginx/src/os/unix/ngx_file_aio_read.c +25 -17
  151. data/vendor/nginx/src/os/unix/ngx_files.c +109 -0
  152. data/vendor/nginx/src/os/unix/ngx_files.h +6 -0
  153. data/vendor/nginx/src/os/unix/ngx_freebsd_config.h +0 -6
  154. data/vendor/nginx/src/os/unix/ngx_freebsd_sendfile_chain.c +78 -206
  155. data/vendor/nginx/src/os/unix/ngx_linux_aio_read.c +25 -14
  156. data/vendor/nginx/src/os/unix/ngx_linux_config.h +4 -1
  157. data/vendor/nginx/src/os/unix/ngx_linux_sendfile_chain.c +235 -194
  158. data/vendor/nginx/src/os/unix/ngx_os.h +25 -3
  159. data/vendor/nginx/src/os/unix/ngx_posix_init.c +4 -2
  160. data/vendor/nginx/src/os/unix/ngx_process_cycle.c +13 -195
  161. data/vendor/nginx/src/os/unix/ngx_process_cycle.h +0 -1
  162. data/vendor/nginx/src/os/unix/ngx_readv_chain.c +27 -108
  163. data/vendor/nginx/src/os/unix/ngx_setproctitle.h +2 -2
  164. data/vendor/nginx/src/os/unix/ngx_solaris_sendfilev_chain.c +12 -67
  165. data/vendor/nginx/src/os/unix/ngx_thread.h +26 -83
  166. data/vendor/nginx/src/os/unix/ngx_thread_cond.c +87 -0
  167. data/vendor/nginx/src/os/unix/ngx_thread_id.c +70 -0
  168. data/vendor/nginx/src/os/unix/ngx_thread_mutex.c +174 -0
  169. data/vendor/nginx/src/os/unix/ngx_user.c +2 -20
  170. data/vendor/nginx/src/os/unix/ngx_writev_chain.c +129 -98
  171. metadata +16 -17
  172. data/vendor/nginx/auto/lib/zlib/patch.zlib.h +0 -10
  173. data/vendor/nginx/src/event/ngx_event_busy_lock.c +0 -286
  174. data/vendor/nginx/src/event/ngx_event_busy_lock.h +0 -65
  175. data/vendor/nginx/src/event/ngx_event_mutex.c +0 -70
  176. data/vendor/nginx/src/http/ngx_http_busy_lock.c +0 -307
  177. data/vendor/nginx/src/http/ngx_http_busy_lock.h +0 -54
  178. data/vendor/nginx/src/os/unix/ngx_freebsd_rfork_thread.c +0 -756
  179. data/vendor/nginx/src/os/unix/ngx_freebsd_rfork_thread.h +0 -122
  180. data/vendor/nginx/src/os/unix/ngx_pthread_thread.c +0 -278
  181. data/vendor/nginx/src/os/unix/rfork_thread.S +0 -73
@@ -24,6 +24,28 @@ io_submit(aio_context_t ctx, long n, struct iocb **paiocb)
24
24
  }
25
25
 
26
26
 
27
+ ngx_int_t
28
+ ngx_file_aio_init(ngx_file_t *file, ngx_pool_t *pool)
29
+ {
30
+ ngx_event_aio_t *aio;
31
+
32
+ aio = ngx_pcalloc(pool, sizeof(ngx_event_aio_t));
33
+ if (aio == NULL) {
34
+ return NGX_ERROR;
35
+ }
36
+
37
+ aio->file = file;
38
+ aio->fd = file->fd;
39
+ aio->event.data = aio;
40
+ aio->event.ready = 1;
41
+ aio->event.log = file->log;
42
+
43
+ file->aio = aio;
44
+
45
+ return NGX_OK;
46
+ }
47
+
48
+
27
49
  ssize_t
28
50
  ngx_file_aio_read(ngx_file_t *file, u_char *buf, size_t size, off_t offset,
29
51
  ngx_pool_t *pool)
@@ -37,22 +59,11 @@ ngx_file_aio_read(ngx_file_t *file, u_char *buf, size_t size, off_t offset,
37
59
  return ngx_read_file(file, buf, size, offset);
38
60
  }
39
61
 
40
- aio = file->aio;
41
-
42
- if (aio == NULL) {
43
- aio = ngx_pcalloc(pool, sizeof(ngx_event_aio_t));
44
- if (aio == NULL) {
45
- return NGX_ERROR;
46
- }
47
-
48
- aio->file = file;
49
- aio->fd = file->fd;
50
- aio->event.data = aio;
51
- aio->event.ready = 1;
52
- aio->event.log = file->log;
53
- file->aio = aio;
62
+ if (file->aio == NULL && ngx_file_aio_init(file, pool) != NGX_OK) {
63
+ return NGX_ERROR;
54
64
  }
55
65
 
66
+ aio = file->aio;
56
67
  ev = &aio->event;
57
68
 
58
69
  if (!ev->ready) {
@@ -93,8 +93,11 @@ extern ssize_t sendfile(int s, int fd, int32_t *offset, size_t size);
93
93
  #endif
94
94
 
95
95
 
96
- #if (NGX_HAVE_FILE_AIO)
96
+ #if (NGX_HAVE_SYS_EVENTFD_H)
97
+ #include <sys/eventfd.h>
98
+ #endif
97
99
  #include <sys/syscall.h>
100
+ #if (NGX_HAVE_FILE_AIO)
98
101
  #include <linux/aio_abi.h>
99
102
  typedef struct iocb ngx_aiocb_t;
100
103
  #endif
@@ -10,6 +10,22 @@
10
10
  #include <ngx_event.h>
11
11
 
12
12
 
13
+ static ssize_t ngx_linux_sendfile(ngx_connection_t *c, ngx_buf_t *file,
14
+ size_t size);
15
+
16
+ #if (NGX_THREADS)
17
+ #include <ngx_thread_pool.h>
18
+
19
+ #if !(NGX_HAVE_SENDFILE64)
20
+ #error sendfile64() is required!
21
+ #endif
22
+
23
+ static ngx_int_t ngx_linux_sendfile_thread(ngx_connection_t *c, ngx_buf_t *file,
24
+ size_t size, size_t *sent);
25
+ static void ngx_linux_sendfile_thread_handler(void *data, ngx_log_t *log);
26
+ #endif
27
+
28
+
13
29
  /*
14
30
  * On Linux up to 2.4.21 sendfile() (syscall #187) works with 32-bit
15
31
  * offsets only, and the including <sys/sendfile.h> breaks the compiling,
@@ -27,31 +43,22 @@
27
43
  #define NGX_SENDFILE_MAXSIZE 2147483647L
28
44
 
29
45
 
30
- #if (IOV_MAX > 64)
31
- #define NGX_HEADERS 64
32
- #else
33
- #define NGX_HEADERS IOV_MAX
34
- #endif
35
-
36
-
37
46
  ngx_chain_t *
38
47
  ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
39
48
  {
40
- int rc, tcp_nodelay;
41
- off_t size, send, prev_send, aligned, sent, fprev;
42
- u_char *prev;
43
- size_t file_size;
49
+ int tcp_nodelay;
50
+ off_t send, prev_send;
51
+ size_t file_size, sent;
52
+ ssize_t n;
44
53
  ngx_err_t err;
45
54
  ngx_buf_t *file;
46
- ngx_uint_t eintr, complete;
47
- ngx_array_t header;
48
55
  ngx_event_t *wev;
49
56
  ngx_chain_t *cl;
50
- struct iovec *iov, headers[NGX_HEADERS];
51
- #if (NGX_HAVE_SENDFILE64)
52
- off_t offset;
53
- #else
54
- int32_t offset;
57
+ ngx_iovec_t header;
58
+ struct iovec headers[NGX_IOVS_PREALLOCATE];
59
+ #if (NGX_THREADS)
60
+ ngx_int_t rc;
61
+ ngx_uint_t thread_handled, thread_complete;
55
62
  #endif
56
63
 
57
64
  wev = c->write;
@@ -70,87 +77,30 @@ ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
70
77
 
71
78
  send = 0;
72
79
 
73
- header.elts = headers;
74
- header.size = sizeof(struct iovec);
75
- header.nalloc = NGX_HEADERS;
76
- header.pool = c->pool;
80
+ header.iovs = headers;
81
+ header.nalloc = NGX_IOVS_PREALLOCATE;
77
82
 
78
83
  for ( ;; ) {
79
- file = NULL;
80
- file_size = 0;
81
- eintr = 0;
82
- complete = 0;
83
84
  prev_send = send;
84
-
85
- header.nelts = 0;
86
-
87
- prev = NULL;
88
- iov = NULL;
89
-
90
- /* create the iovec and coalesce the neighbouring bufs */
91
-
92
- for (cl = in; cl && send < limit; cl = cl->next) {
93
-
94
- if (ngx_buf_special(cl->buf)) {
95
- continue;
96
- }
97
-
98
- #if 1
99
- if (!ngx_buf_in_memory(cl->buf) && !cl->buf->in_file) {
100
- ngx_log_error(NGX_LOG_ALERT, c->log, 0,
101
- "zero size buf in sendfile "
102
- "t:%d r:%d f:%d %p %p-%p %p %O-%O",
103
- cl->buf->temporary,
104
- cl->buf->recycled,
105
- cl->buf->in_file,
106
- cl->buf->start,
107
- cl->buf->pos,
108
- cl->buf->last,
109
- cl->buf->file,
110
- cl->buf->file_pos,
111
- cl->buf->file_last);
112
-
113
- ngx_debug_point();
114
-
115
- return NGX_CHAIN_ERROR;
116
- }
85
+ #if (NGX_THREADS)
86
+ thread_handled = 0;
87
+ thread_complete = 0;
117
88
  #endif
118
89
 
119
- if (!ngx_buf_in_memory_only(cl->buf)) {
120
- break;
121
- }
122
-
123
- size = cl->buf->last - cl->buf->pos;
124
-
125
- if (send + size > limit) {
126
- size = limit - send;
127
- }
128
-
129
- if (prev == cl->buf->pos) {
130
- iov->iov_len += (size_t) size;
131
-
132
- } else {
133
- if (header.nelts >= IOV_MAX) {
134
- break;
135
- }
136
-
137
- iov = ngx_array_push(&header);
138
- if (iov == NULL) {
139
- return NGX_CHAIN_ERROR;
140
- }
90
+ /* create the iovec and coalesce the neighbouring bufs */
141
91
 
142
- iov->iov_base = (void *) cl->buf->pos;
143
- iov->iov_len = (size_t) size;
144
- }
92
+ cl = ngx_output_chain_to_iovec(&header, in, limit - send, c->log);
145
93
 
146
- prev = cl->buf->pos + (size_t) size;
147
- send += size;
94
+ if (cl == NGX_CHAIN_ERROR) {
95
+ return NGX_CHAIN_ERROR;
148
96
  }
149
97
 
98
+ send += header.size;
99
+
150
100
  /* set TCP_CORK if there is a header before a file */
151
101
 
152
102
  if (c->tcp_nopush == NGX_TCP_NOPUSH_UNSET
153
- && header.nelts != 0
103
+ && header.count != 0
154
104
  && cl
155
105
  && cl->buf->in_file)
156
106
  {
@@ -214,165 +164,256 @@ ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
214
164
 
215
165
  /* get the file buf */
216
166
 
217
- if (header.nelts == 0 && cl && cl->buf->in_file && send < limit) {
167
+ if (header.count == 0 && cl && cl->buf->in_file && send < limit) {
218
168
  file = cl->buf;
219
169
 
220
170
  /* coalesce the neighbouring file bufs */
221
171
 
222
- do {
223
- size = cl->buf->file_last - cl->buf->file_pos;
224
-
225
- if (send + size > limit) {
226
- size = limit - send;
227
-
228
- aligned = (cl->buf->file_pos + size + ngx_pagesize - 1)
229
- & ~((off_t) ngx_pagesize - 1);
230
-
231
- if (aligned <= cl->buf->file_last) {
232
- size = aligned - cl->buf->file_pos;
233
- }
234
- }
172
+ file_size = (size_t) ngx_chain_coalesce_file(&cl, limit - send);
235
173
 
236
- file_size += (size_t) size;
237
- send += size;
238
- fprev = cl->buf->file_pos + size;
239
- cl = cl->next;
240
-
241
- } while (cl
242
- && cl->buf->in_file
243
- && send < limit
244
- && file->file->fd == cl->buf->file->fd
245
- && fprev == cl->buf->file_pos);
246
- }
247
-
248
- if (file) {
174
+ send += file_size;
249
175
  #if 1
250
176
  if (file_size == 0) {
251
177
  ngx_debug_point();
252
178
  return NGX_CHAIN_ERROR;
253
179
  }
254
180
  #endif
255
- #if (NGX_HAVE_SENDFILE64)
256
- offset = file->file_pos;
257
- #else
258
- offset = (int32_t) file->file_pos;
259
- #endif
260
-
261
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
262
- "sendfile: @%O %uz", file->file_pos, file_size);
263
181
 
264
- rc = sendfile(c->fd, file->file->fd, &offset, file_size);
182
+ #if (NGX_THREADS)
183
+ if (file->file->thread_handler) {
184
+ rc = ngx_linux_sendfile_thread(c, file, file_size, &sent);
265
185
 
266
- if (rc == -1) {
267
- err = ngx_errno;
186
+ switch (rc) {
187
+ case NGX_OK:
188
+ thread_handled = 1;
189
+ break;
268
190
 
269
- switch (err) {
270
- case NGX_EAGAIN:
191
+ case NGX_DONE:
192
+ thread_complete = 1;
271
193
  break;
272
194
 
273
- case NGX_EINTR:
274
- eintr = 1;
195
+ case NGX_AGAIN:
275
196
  break;
276
197
 
277
- default:
278
- wev->error = 1;
279
- ngx_connection_error(c, err, "sendfile() failed");
198
+ default: /* NGX_ERROR */
280
199
  return NGX_CHAIN_ERROR;
281
200
  }
282
201
 
283
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
284
- "sendfile() is not ready");
285
- }
202
+ } else
203
+ #endif
204
+ {
205
+ n = ngx_linux_sendfile(c, file, file_size);
286
206
 
287
- sent = rc > 0 ? rc : 0;
207
+ if (n == NGX_ERROR) {
208
+ return NGX_CHAIN_ERROR;
209
+ }
288
210
 
289
- ngx_log_debug4(NGX_LOG_DEBUG_EVENT, c->log, 0,
290
- "sendfile: %d, @%O %O:%uz",
291
- rc, file->file_pos, sent, file_size);
211
+ sent = (n == NGX_AGAIN) ? 0 : n;
212
+ }
292
213
 
293
214
  } else {
294
- rc = writev(c->fd, header.elts, header.nelts);
215
+ n = ngx_writev(c, &header);
295
216
 
296
- if (rc == -1) {
297
- err = ngx_errno;
217
+ if (n == NGX_ERROR) {
218
+ return NGX_CHAIN_ERROR;
219
+ }
298
220
 
299
- switch (err) {
300
- case NGX_EAGAIN:
301
- break;
221
+ sent = (n == NGX_AGAIN) ? 0 : n;
222
+ }
302
223
 
303
- case NGX_EINTR:
304
- eintr = 1;
305
- break;
224
+ c->sent += sent;
306
225
 
307
- default:
308
- wev->error = 1;
309
- ngx_connection_error(c, err, "writev() failed");
310
- return NGX_CHAIN_ERROR;
311
- }
226
+ in = ngx_chain_update_sent(in, sent);
312
227
 
313
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
314
- "writev() not ready");
228
+ if ((size_t) (send - prev_send) != sent) {
229
+ #if (NGX_THREADS)
230
+ if (thread_handled) {
231
+ return in;
315
232
  }
316
233
 
317
- sent = rc > 0 ? rc : 0;
318
-
319
- ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "writev: %O", sent);
234
+ if (thread_complete) {
235
+ send = prev_send + sent;
236
+ continue;
237
+ }
238
+ #endif
239
+ wev->ready = 0;
240
+ return in;
320
241
  }
321
242
 
322
- if (send - prev_send == sent) {
323
- complete = 1;
243
+ if (send >= limit || in == NULL) {
244
+ return in;
324
245
  }
246
+ }
247
+ }
325
248
 
326
- c->sent += sent;
327
249
 
328
- for ( /* void */ ; in; in = in->next) {
250
+ static ssize_t
251
+ ngx_linux_sendfile(ngx_connection_t *c, ngx_buf_t *file, size_t size)
252
+ {
253
+ #if (NGX_HAVE_SENDFILE64)
254
+ off_t offset;
255
+ #else
256
+ int32_t offset;
257
+ #endif
258
+ ssize_t n;
259
+ ngx_err_t err;
329
260
 
330
- if (ngx_buf_special(in->buf)) {
331
- continue;
332
- }
261
+ #if (NGX_HAVE_SENDFILE64)
262
+ offset = file->file_pos;
263
+ #else
264
+ offset = (int32_t) file->file_pos;
265
+ #endif
333
266
 
334
- if (sent == 0) {
335
- break;
336
- }
267
+ eintr:
337
268
 
338
- size = ngx_buf_size(in->buf);
269
+ ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
270
+ "sendfile: @%O %uz", file->file_pos, size);
339
271
 
340
- if (sent >= size) {
341
- sent -= size;
272
+ n = sendfile(c->fd, file->file->fd, &offset, size);
342
273
 
343
- if (ngx_buf_in_memory(in->buf)) {
344
- in->buf->pos = in->buf->last;
345
- }
274
+ if (n == -1) {
275
+ err = ngx_errno;
346
276
 
347
- if (in->buf->in_file) {
348
- in->buf->file_pos = in->buf->file_last;
349
- }
277
+ switch (err) {
278
+ case NGX_EAGAIN:
279
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
280
+ "sendfile() is not ready");
281
+ return NGX_AGAIN;
350
282
 
351
- continue;
352
- }
283
+ case NGX_EINTR:
284
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err,
285
+ "sendfile() was interrupted");
286
+ goto eintr;
353
287
 
354
- if (ngx_buf_in_memory(in->buf)) {
355
- in->buf->pos += (size_t) sent;
356
- }
288
+ default:
289
+ c->write->error = 1;
290
+ ngx_connection_error(c, err, "sendfile() failed");
291
+ return NGX_ERROR;
292
+ }
293
+ }
357
294
 
358
- if (in->buf->in_file) {
359
- in->buf->file_pos += sent;
360
- }
295
+ ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, "sendfile: %z of %uz @%O",
296
+ n, size, file->file_pos);
361
297
 
362
- break;
363
- }
298
+ return n;
299
+ }
300
+
301
+
302
+ #if (NGX_THREADS)
303
+
304
+ typedef struct {
305
+ ngx_buf_t *file;
306
+ ngx_socket_t socket;
307
+ size_t size;
308
+
309
+ size_t sent;
310
+ ngx_err_t err;
311
+ } ngx_linux_sendfile_ctx_t;
364
312
 
365
- if (eintr) {
366
- continue;
313
+
314
+ static ngx_int_t
315
+ ngx_linux_sendfile_thread(ngx_connection_t *c, ngx_buf_t *file, size_t size,
316
+ size_t *sent)
317
+ {
318
+ ngx_uint_t flags;
319
+ ngx_event_t *wev;
320
+ ngx_thread_task_t *task;
321
+ ngx_linux_sendfile_ctx_t *ctx;
322
+
323
+ ngx_log_debug3(NGX_LOG_DEBUG_CORE, c->log, 0,
324
+ "linux sendfile thread: %d, %uz, %O",
325
+ file->file->fd, size, file->file_pos);
326
+
327
+ task = c->sendfile_task;
328
+
329
+ if (task == NULL) {
330
+ task = ngx_thread_task_alloc(c->pool, sizeof(ngx_linux_sendfile_ctx_t));
331
+ if (task == NULL) {
332
+ return NGX_ERROR;
367
333
  }
368
334
 
369
- if (!complete) {
370
- wev->ready = 0;
371
- return in;
335
+ task->handler = ngx_linux_sendfile_thread_handler;
336
+
337
+ c->sendfile_task = task;
338
+ }
339
+
340
+ ctx = task->ctx;
341
+ wev = c->write;
342
+
343
+ if (task->event.complete) {
344
+ task->event.complete = 0;
345
+
346
+ if (ctx->err && ctx->err != NGX_EAGAIN) {
347
+ wev->error = 1;
348
+ ngx_connection_error(c, ctx->err, "sendfile() failed");
349
+ return NGX_ERROR;
372
350
  }
373
351
 
374
- if (send >= limit || in == NULL) {
375
- return in;
352
+ *sent = ctx->sent;
353
+
354
+ return (ctx->sent == ctx->size) ? NGX_DONE : NGX_AGAIN;
355
+ }
356
+
357
+ ctx->file = file;
358
+ ctx->socket = c->fd;
359
+ ctx->size = size;
360
+
361
+ if (wev->active) {
362
+ flags = (ngx_event_flags & NGX_USE_CLEAR_EVENT) ? NGX_CLEAR_EVENT
363
+ : NGX_LEVEL_EVENT;
364
+
365
+ if (ngx_del_event(wev, NGX_WRITE_EVENT, flags) == NGX_ERROR) {
366
+ return NGX_ERROR;
376
367
  }
377
368
  }
369
+
370
+ if (file->file->thread_handler(task, file->file) != NGX_OK) {
371
+ return NGX_ERROR;
372
+ }
373
+
374
+ *sent = 0;
375
+
376
+ return NGX_OK;
377
+ }
378
+
379
+
380
+ static void
381
+ ngx_linux_sendfile_thread_handler(void *data, ngx_log_t *log)
382
+ {
383
+ ngx_linux_sendfile_ctx_t *ctx = data;
384
+
385
+ off_t offset;
386
+ ssize_t n;
387
+ ngx_buf_t *file;
388
+
389
+ ngx_log_debug0(NGX_LOG_DEBUG_CORE, log, 0, "linux sendfile thread handler");
390
+
391
+ file = ctx->file;
392
+ offset = file->file_pos;
393
+
394
+ again:
395
+
396
+ n = sendfile(ctx->socket, file->file->fd, &offset, ctx->size);
397
+
398
+ if (n == -1) {
399
+ ctx->err = ngx_errno;
400
+
401
+ } else {
402
+ ctx->sent = n;
403
+ ctx->err = 0;
404
+ }
405
+
406
+ #if 0
407
+ ngx_time_update();
408
+ #endif
409
+
410
+ ngx_log_debug4(NGX_LOG_DEBUG_EVENT, log, 0,
411
+ "sendfile: %z (err: %i) of %uz @%O",
412
+ n, ctx->err, ctx->size, file->file_pos);
413
+
414
+ if (ctx->err == NGX_EINTR) {
415
+ goto again;
416
+ }
378
417
  }
418
+
419
+ #endif /* NGX_THREADS */