Skip to content
This repository
Browse code

git-svn-id: svn://cherokee-project.com/cherokee/trunk@1708 5dc97367-9…

…7f1-0310-9951-d761b3857238
  • Loading branch information...
commit a18b3459db37e68429fe2b616bc332db83956f13 1 parent b6e3098
Alvaro Lopez Ortega alobbs authored
24 ChangeLog
... ... @@ -1,8 +1,26 @@
  1 +2008-08-01 Alvaro Lopez Ortega <alvaro@alobbs.com>
  2 +
  3 + * cherokee/socket.c, cherokee/buffer.c, cherokee/connection.c,
  4 + cherokee/handler_cgi_base.h, cherokee/source.c, cherokee/thread.c,
  5 + cherokee/handler_fcgi.c, cherokee/util.c, cherokee/handler_cgi.c,
  6 + cherokee/connection-protected.h, cherokee/handler_scgi.h,
  7 + cherokee/handler_fcgi.h, cherokee/handler_scgi.c: This jumbo-patch
  8 + fixes a really nasty bug (and a few other minor issues I found
  9 + along the way) that caused Cherokee to fail to handle PHP FastCGI
  10 + overloads "nicely". Actually, the main problem is the lousy
  11 + FastCGI implementation of php-cgi, which due a design flaw, does
  12 + not notify when it run out of resources (child processes). This
  13 + patch makes Cherokee perform much better when the PHP interpreter
  14 + starts misbehaving. (It would be grand if the PHP crowd would have
  15 + fixed the php-cgi design problem.. but, well, after 5 years I have
  16 + lost my faith). At least now Cherokee knows how to deal with such
  17 + a broken implementation. <sigh!!>
  18 +
1 19 2008-07-31 Taher Shihadeh <taher@unixwars.com>
  20 +
2 21 * spawn-fastcgi.1: fixed a minor glitch unknowinlgy introduced in
3 22 the past.
4 23
5   -2008-07-31 Taher Shihadeh <taher@unixwars.com>
6 24 * doc/build/TODO: plan for improved documentation is needed.
7 25
8 26 2008-07-31 Alvaro Lopez Ortega <alvaro@alobbs.com>
@@ -12,17 +30,21 @@
12 30 http://code.google.com/p/cherokee/issues/detail?id=61
13 31
14 32 2008-07-29 Taher Shihadeh <taher@unixwars.com>
  33 +
15 34 * doc/cherokee_tweak.txt: added some documentation.
16 35
17 36 2008-07-29 Milo van der Linden <milovanderlinden@gmail.com>
  37 +
18 38 * doc/admin.txt, doc/compiling_and_installing_unix.txt: some
19 39 documentation patches.
20 40
21 41 2008-07-28 Taher Shihadeh <taher@unixwars.com>
  42 +
22 43 * cherokee-tweak.1, cherokee-admin.1, cherokee.1: manpages needed
23 44 an update.
24 45
25 46 2008-07-28 Taher Shihadeh <taher@unixwars.com>
  47 +
26 48 * admin/PageEntry.py, admin/PageEncoders.py, admin/PageAdvanced.py,
27 49 admin/PageVServers.py, admin/PageGeneral.py, admin/PageMime.py,
28 50 admin/PageVServer.py, admin/Form.py, admin/PageFeedback.py,
3  cherokee/buffer.c
@@ -554,7 +554,8 @@ cherokee_buffer_add_va_list (cherokee_buffer_t *buf, char *format, va_list args)
554 554 /* At this point buf-size is always greater than buf-len, thus size > 0.
555 555 */
556 556 if (len >= size) {
557   - TRACE(ENTRIES, "Failed estimation=%d, needed=%d available size=%d\n", estimation, len, size);
  557 + PRINT_ERROR ("Failed estimation=%d, needed=%d available size=%d: %s\n",
  558 + estimation, len, size, format);
558 559
559 560 cherokee_buffer_ensure_size (buf, buf->len + len + 2);
560 561 size = buf->size - buf->len;
1  cherokee/connection-protected.h
@@ -173,6 +173,7 @@ struct cherokee_connection {
173 173 /* Polling
174 174 */
175 175 int polling_fd;
  176 + int polling_mode;
176 177 cherokee_boolean_t polling_multiple;
177 178
178 179 off_t range_start;
14 cherokee/connection.c
@@ -117,6 +117,7 @@ cherokee_connection_new (cherokee_connection_t **conn)
117 117 n->timeout = -1;
118 118 n->polling_fd = -1;
119 119 n->polling_multiple = false;
  120 + n->polling_mode = FDPOLL_MODE_NONE;
120 121
121 122 cherokee_buffer_init (&n->buffer);
122 123 cherokee_buffer_init (&n->header_buffer);
@@ -196,7 +197,8 @@ cherokee_connection_free (cherokee_connection_t *conn)
196 197
197 198 if (conn->polling_fd != -1) {
198 199 close (conn->polling_fd);
199   - conn->polling_fd = -1;
  200 + conn->polling_fd = -1;
  201 + conn->polling_mode = FDPOLL_MODE_NONE;
200 202 }
201 203
202 204 free (conn);
@@ -234,6 +236,7 @@ cherokee_connection_clean (cherokee_connection_t *conn)
234 236 conn->tx_partial = 0;
235 237 conn->traffic_next = 0;
236 238 conn->polling_multiple = false;
  239 + conn->polling_mode = FDPOLL_MODE_NONE;
237 240
238 241 memset (conn->regex_ovector, OVECTOR_LEN * sizeof(int), 0);
239 242 conn->regex_ovecsize = 0;
@@ -1898,9 +1901,14 @@ cherokee_connection_print (cherokee_connection_t *conn)
1898 1901 cherokee_buffer_t *buf = &conn->self_trace;
1899 1902 const char *phase;
1900 1903
1901   - phase = cherokee_connection_get_phase_str (conn);
1902   -
1903 1904 cherokee_buffer_clean (buf);
  1905 +
  1906 + if (conn == NULL) {
  1907 + cherokee_buffer_add_str (buf, "Connection is NULL\n");
  1908 + return ret_ok;
  1909 + }
  1910 +
  1911 + phase = cherokee_connection_get_phase_str (conn);
1904 1912 cherokee_buffer_add_va (buf, "Connection %p info\n", conn);
1905 1913
1906 1914 #define print_buf(title,name) \
3  cherokee/handler_cgi.c
@@ -415,6 +415,9 @@ cherokee_handler_cgi_init (cherokee_handler_cgi_t *cgi)
415 415 */
416 416 conn->timeout = CONN_THREAD(conn)->bogo_now + CGI_TIMEOUT;
417 417
  418 + cgi_base->init_phase = hcgi_phase_connect;
  419 +
  420 + case hcgi_phase_connect:
418 421 /* Launch the CGI
419 422 */
420 423 ret = fork_and_execute_cgi(cgi);
1  cherokee/handler_cgi_base.h
@@ -61,6 +61,7 @@ typedef ret_t (* cherokee_handler_cgi_base_read_from_cgi_t) (cherokee_handler_cg
61 61
62 62 typedef enum {
63 63 hcgi_phase_build_headers,
  64 + hcgi_phase_connect,
64 65 hcgi_phase_send_headers,
65 66 hcgi_phase_send_post
66 67 } cherokee_handler_cgi_base_phase_t;
98 cherokee/handler_fcgi.c
@@ -23,12 +23,16 @@
23 23 */
24 24
25 25 #include "common-internal.h"
  26 +
  27 +#include <fcntl.h>
  28 +
26 29 #include "handler_fcgi.h"
27 30 #include "header.h"
28 31 #include "connection-protected.h"
29 32 #include "util.h"
30 33 #include "thread.h"
31 34 #include "source_interpreter.h"
  35 +#include "bogotime.h"
32 36
33 37 #include "fastcgi.h"
34 38
@@ -285,10 +289,10 @@ cherokee_handler_fcgi_new (cherokee_handler_t **hdl, void *cnt, cherokee_module_
285 289 */
286 290 n->post_phase = fcgi_post_init;
287 291 n->post_len = 0;
288   -
289   - cherokee_socket_init (&n->socket);
290   - cherokee_socket_set_nodelay (&n->socket);
  292 + n->src_ref = NULL;
  293 + n->spawned = 0;
291 294
  295 + cherokee_socket_init (&n->socket);
292 296 cherokee_buffer_init (&n->write_buffer);
293 297 cherokee_buffer_ensure_size (&n->write_buffer, 512);
294 298
@@ -497,46 +501,73 @@ static ret_t
497 501 connect_to_server (cherokee_handler_fcgi_t *hdl)
498 502 {
499 503 ret_t ret;
500   - int try = 0;
501   - cherokee_source_t *src = NULL;
502   - cherokee_connection_t *conn = HANDLER_CONN(hdl);
503   - cherokee_handler_fcgi_props_t *props = HANDLER_FCGI_PROPS(hdl);
  504 + cherokee_connection_t *conn = HANDLER_CONN(hdl);
  505 + cherokee_handler_fcgi_props_t *props = HANDLER_FCGI_PROPS(hdl);
  506 + cherokee_source_interpreter_t *src_int = SOURCE_INT(hdl->src_ref);
504 507
505   - ret = cherokee_balancer_dispatch (props->balancer, conn, &src);
506   - if (ret != ret_ok)
507   - return ret;
  508 + /* Get a reference to the target host
  509 + */
  510 + if (hdl->src_ref == NULL) {
  511 + ret = cherokee_balancer_dispatch (props->balancer, conn, &hdl->src_ref);
  512 + if (ret != ret_ok)
  513 + return ret;
  514 + }
508 515
509   - ret = cherokee_source_connect (src, &hdl->socket);
510   - if (ret != ret_ok) {
511   - cherokee_source_interpreter_t *src_int = SOURCE_INT(src);
  516 + /* Try to connect
  517 + */
  518 + ret = cherokee_source_connect (hdl->src_ref, &hdl->socket);
  519 + switch (ret) {
  520 + case ret_ok:
  521 + goto out;
  522 + case ret_deny:
  523 + break;
  524 + case ret_eagain:
  525 + ret = cherokee_thread_deactive_to_polling (HANDLER_THREAD(hdl),
  526 + conn,
  527 + SOCKET_FD(&hdl->socket),
  528 + FDPOLL_MODE_WRITE,
  529 + false);
  530 + if (ret != ret_ok) {
  531 + return ret_deny;
  532 + }
512 533
  534 + return ret_eagain;
  535 + case ret_error:
  536 + return ret_error;
  537 + default:
  538 + break;
  539 + }
  540 +
  541 + /* In case it did not success, launch a interpreter
  542 + */
  543 + if (hdl->spawned == 0) {
  544 + /* Launch a new interpreter */
513 545 ret = cherokee_source_interpreter_spawn (src_int);
514 546 if (ret != ret_ok) {
515 547 if (src_int->interpreter.buf)
516   - TRACE (ENTRIES, "Couldn't spawn: %s\n", src_int->interpreter.buf);
  548 + TRACE (ENTRIES, "Couldn't spawn: %s\n",
  549 + src_int->interpreter.buf);
517 550 else
518   - TRACE (ENTRIES, "There was no interpreter to be spawned %s", "\n");
  551 + TRACE (ENTRIES, "No interpreter to be spawned %s", "\n");
519 552 return ret_error;
520 553 }
521 554
522   - while (true) {
523   - ret = cherokee_source_connect (src, &hdl->socket);
524   - if (ret == ret_ok)
525   - break;
  555 + hdl->spawned = cherokee_bogonow_now;
526 556
527   - TRACE (ENTRIES, "Couldn't connect: %s, try %d\n", src->host.buf ? src->host.buf : src->unix_socket.buf, try);
  557 + /* Reset the internal socket */
  558 + cherokee_socket_close (&hdl->socket);
528 559
529   - if (try++ >= 3)
530   - return ret;
  560 + } else if (cherokee_bogonow_now > hdl->spawned + 3) {
  561 + TRACE (ENTRIES, "Giving up; spawned 3 secs ago: %s\n",
  562 + src_int->interpreter.buf);
  563 + return ret_error;
531 564
532   - sleep (1);
533   - }
534   -
535 565 }
536 566
537   - TRACE (ENTRIES, "Connected successfully try=%d, fd=%d\n", try, hdl->socket.socket);
  567 + return ret_eagain;
538 568
539   - cherokee_fd_set_nonblocking (SOCKET_FD(&hdl->socket));
  569 +out:
  570 + TRACE (ENTRIES, "Connected successfully fd=%d\n", hdl->socket.socket);
540 571 return ret_ok;
541 572 }
542 573
@@ -707,7 +738,7 @@ cherokee_handler_fcgi_init (cherokee_handler_fcgi_t *hdl)
707 738
708 739 switch (HDL_CGI_BASE(hdl)->init_phase) {
709 740 case hcgi_phase_build_headers:
710   - TRACE (ENTRIES, "Init %s\n", "begins");
  741 + TRACE (ENTRIES, "Init: %s\n", "begins");
711 742
712 743 /* Prepare Post
713 744 */
@@ -726,12 +757,19 @@ cherokee_handler_fcgi_init (cherokee_handler_fcgi_t *hdl)
726 757 ret = build_header (hdl, &hdl->write_buffer);
727 758 if (unlikely (ret != ret_ok)) return ret;
728 759
729   - /* Connect
  760 + HDL_CGI_BASE(hdl)->init_phase = hcgi_phase_connect;
  761 +
  762 + case hcgi_phase_connect:
  763 + TRACE (ENTRIES, "Init: %s\n", "connect");
  764 +
  765 + /* Connect
730 766 */
731 767 ret = connect_to_server (hdl);
732 768 switch (ret) {
733 769 case ret_ok:
734 770 break;
  771 + case ret_eagain:
  772 + return ret_eagain;
735 773 case ret_deny:
736 774 conn->error_code = http_gateway_timeout;
737 775 return ret_error;
@@ -743,7 +781,7 @@ cherokee_handler_fcgi_init (cherokee_handler_fcgi_t *hdl)
743 781 HDL_CGI_BASE(hdl)->init_phase = hcgi_phase_send_headers;
744 782
745 783 case hcgi_phase_send_headers:
746   - TRACE (ENTRIES, "Init %s\n", "send_headers");
  784 + TRACE (ENTRIES, "Init: %s\n", "send_headers");
747 785
748 786 /* Send the header
749 787 */
2  cherokee/handler_fcgi.h
@@ -45,6 +45,8 @@ typedef enum {
45 45 */
46 46 typedef struct {
47 47 cherokee_handler_cgi_base_t base;
  48 + cherokee_source_t *src_ref;
  49 + time_t spawned;
48 50 cherokee_socket_t socket;
49 51 cherokee_handler_fcgi_post_t post_phase;
50 52 off_t post_len;
101 cherokee/handler_scgi.c
@@ -30,6 +30,7 @@
30 30 #include "thread.h"
31 31 #include "util.h"
32 32 #include "connection-protected.h"
  33 +#include "bogotime.h"
33 34
34 35 #define ENTRIES "handler,cgi"
35 36
@@ -180,6 +181,8 @@ cherokee_handler_scgi_new (cherokee_handler_t **hdl, void *cnt, cherokee_module_
180 181 /* Properties
181 182 */
182 183 n->post_len = 0;
  184 + n->spawned = 0;
  185 + n->src_ref = NULL;
183 186
184 187 cherokee_buffer_init (&n->header);
185 188 cherokee_socket_init (&n->socket);
@@ -248,49 +251,79 @@ build_header (cherokee_handler_scgi_t *hdl)
248 251 }
249 252
250 253
251   -static ret_t
  254 +
  255 +static ret_t
252 256 connect_to_server (cherokee_handler_scgi_t *hdl)
253 257 {
254 258 ret_t ret;
255   - cherokee_source_t *src = NULL;
256   - cherokee_connection_t *conn = HANDLER_CONN(hdl);
257   - cherokee_handler_scgi_props_t *props = HDL_SCGI_PROPS(hdl);
  259 + cherokee_connection_t *conn = HANDLER_CONN(hdl);
  260 + cherokee_handler_scgi_props_t *props = HANDLER_SCGI_PROPS(hdl);
  261 + cherokee_source_interpreter_t *src_int = SOURCE_INT(hdl->src_ref);
258 262
259   - ret = cherokee_balancer_dispatch (props->balancer, conn, &src);
260   - if (ret != ret_ok) return ret;
  263 + /* Get a reference to the target host
  264 + */
  265 + if (hdl->src_ref == NULL) {
  266 + ret = cherokee_balancer_dispatch (props->balancer, conn, &hdl->src_ref);
  267 + if (ret != ret_ok)
  268 + return ret;
  269 + }
261 270
262   - ret = cherokee_source_connect (src, &hdl->socket);
263   - if (ret != ret_ok) {
264   - int try = 0;
265   - cherokee_source_interpreter_t *src_int = SOURCE_INT(src);
  271 + /* Try to connect
  272 + */
  273 + ret = cherokee_source_connect (hdl->src_ref, &hdl->socket);
  274 + switch (ret) {
  275 + case ret_ok:
  276 + goto out;
  277 + case ret_deny:
  278 + break;
  279 + case ret_eagain:
  280 + ret = cherokee_thread_deactive_to_polling (HANDLER_THREAD(hdl),
  281 + conn,
  282 + SOCKET_FD(&hdl->socket),
  283 + FDPOLL_MODE_WRITE,
  284 + false);
  285 + if (ret != ret_ok) {
  286 + return ret_deny;
  287 + }
  288 +
  289 + return ret_eagain;
  290 + case ret_error:
  291 + return ret_error;
  292 + default:
  293 + break;
  294 + }
266 295
  296 + /* In case it did not success, launch a interpreter
  297 + */
  298 + if (hdl->spawned == 0) {
  299 + /* Launch a new interpreter */
267 300 ret = cherokee_source_interpreter_spawn (src_int);
268 301 if (ret != ret_ok) {
269 302 if (src_int->interpreter.buf)
270   - TRACE (ENTRIES, "Couldn't spawn: %s\n", src_int->interpreter.buf);
  303 + TRACE (ENTRIES, "Couldn't spawn: %s\n",
  304 + src_int->interpreter.buf);
271 305 else
272   - TRACE (ENTRIES, "There was no interpreter to be spawned %s", "\n");
  306 + TRACE (ENTRIES, "No interpreter to be spawned %s", "\n");
273 307 return ret_error;
274 308 }
275   -
276   - while (true) {
277   - ret = cherokee_source_connect (src, &hdl->socket);
278   - if (ret == ret_ok) break;
279 309
280   - TRACE (ENTRIES, "Couldn't connect: %s, try %d\n", src->host.buf ? src->host.buf : src->unix_socket.buf, try);
  310 + hdl->spawned = cherokee_bogonow_now;
281 311
282   - if (try++ >= 3)
283   - return ret;
  312 + /* Reset the internal socket */
  313 + cherokee_socket_close (&hdl->socket);
  314 +
  315 + } else if (cherokee_bogonow_now > hdl->spawned + 3) {
  316 + TRACE (ENTRIES, "Giving up; spawned 3 secs ago: %s\n",
  317 + src_int->interpreter.buf);
  318 + return ret_error;
284 319
285   - sleep (1);
286   - }
287   -
288 320 }
289   -
290   - TRACE (ENTRIES, "connected fd=%d\n", hdl->socket.socket);
291 321
292   - cherokee_fd_set_nonblocking (SOCKET_FD(&hdl->socket));
293   - return ret_ok;
  322 + return ret_eagain;
  323 +
  324 +out:
  325 + TRACE (ENTRIES, "Connected successfully fd=%d\n", hdl->socket.socket);
  326 + return ret_ok;
294 327 }
295 328
296 329
@@ -306,9 +339,10 @@ send_header (cherokee_handler_scgi_t *hdl)
306 339 conn->error_code = http_bad_gateway;
307 340 return ret;
308 341 }
309   -
310   -// cherokee_buffer_print_debug (&hdl->header, -1);
311 342
  343 +#if 0
  344 + cherokee_buffer_print_debug (&hdl->header, -1);
  345 +#endif
312 346 cherokee_buffer_move_to_begin (&hdl->header, written);
313 347
314 348 TRACE (ENTRIES, "sent remaining=%d\n", hdl->header.len);
@@ -354,6 +388,8 @@ cherokee_handler_scgi_init (cherokee_handler_scgi_t *hdl)
354 388
355 389 switch (HDL_CGI_BASE(hdl)->init_phase) {
356 390 case hcgi_phase_build_headers:
  391 + TRACE (ENTRIES, "Init: %s\n", "begins");
  392 +
357 393 /* Extracts PATH_INFO and filename from request uri
358 394 */
359 395 ret = cherokee_handler_cgi_base_extract_path (HDL_CGI_BASE(hdl), false);
@@ -377,12 +413,19 @@ cherokee_handler_scgi_init (cherokee_handler_scgi_t *hdl)
377 413 return ret_error;
378 414 }
379 415
  416 + HDL_CGI_BASE(hdl)->init_phase = hcgi_phase_connect;
  417 +
  418 + case hcgi_phase_connect:
  419 + TRACE (ENTRIES, "Init: %s\n", "connect");
  420 +
380 421 /* Connect
381 422 */
382 423 ret = connect_to_server (hdl);
383 424 switch (ret) {
384 425 case ret_ok:
385 426 break;
  427 + case ret_eagain:
  428 + return ret_eagain;
386 429 case ret_deny:
387 430 conn->error_code = http_gateway_timeout;
388 431 return ret_error;
@@ -394,6 +437,8 @@ cherokee_handler_scgi_init (cherokee_handler_scgi_t *hdl)
394 437 HDL_CGI_BASE(hdl)->init_phase = hcgi_phase_send_headers;
395 438
396 439 case hcgi_phase_send_headers:
  440 + TRACE (ENTRIES, "Init: %s\n", "send_headers");
  441 +
397 442 /* Send the header
398 443 */
399 444 ret = send_header (hdl);
8 cherokee/handler_scgi.h
@@ -46,12 +46,14 @@ typedef struct {
46 46 cherokee_handler_cgi_base_t base;
47 47 cherokee_buffer_t header;
48 48 cherokee_socket_t socket;
  49 + cherokee_source_t *src_ref;
  50 + time_t spawned;
49 51 off_t post_len;
50 52 } cherokee_handler_scgi_t;
51 53
52   -#define HDL_SCGI(x) ((cherokee_handler_scgi_t *)(x))
53   -#define PROP_SCGI(x) ((cherokee_handler_scgi_props_t *)(x))
54   -#define HDL_SCGI_PROPS(x) (PROP_SCGI(MODULE(x)->props))
  54 +#define HDL_SCGI(x) ((cherokee_handler_scgi_t *)(x))
  55 +#define PROP_SCGI(x) ((cherokee_handler_scgi_props_t *)(x))
  56 +#define HANDLER_SCGI_PROPS(x) (PROP_SCGI(MODULE(x)->props))
55 57
56 58
57 59 /* Library init function
25 cherokee/socket.c
@@ -507,13 +507,11 @@ cherokee_socket_close (cherokee_socket_t *socket)
507 507 #ifdef HAVE_TLS
508 508 if (socket->is_tls == TLS && socket->session != NULL) {
509 509 #if defined (HAVE_GNUTLS)
510   -
511 510 gnutls_bye (socket->session, GNUTLS_SHUT_WR);
512 511 gnutls_deinit (socket->session);
513 512 socket->session = NULL;
514 513
515 514 #elif defined (HAVE_OPENSSL)
516   -
517 515 SSL_shutdown (socket->session);
518 516
519 517 #endif
@@ -522,7 +520,8 @@ cherokee_socket_close (cherokee_socket_t *socket)
522 520
523 521 ret = cherokee_close_fd (socket->socket);
524 522
525   - TRACE (ENTRIES",close", "fd=%d is_tls=%d re=%d\n", socket->socket, socket->is_tls, (int) ret);
  523 + TRACE (ENTRIES",close", "fd=%d is_tls=%d re=%d\n",
  524 + socket->socket, socket->is_tls, (int) ret);
526 525
527 526 socket->socket = -1;
528 527 socket->status = socket_closed;
@@ -1085,6 +1084,9 @@ cherokee_socket_read (cherokee_socket_t *socket, char *buf, int buf_size, size_t
1085 1084 { /* len < 0 */
1086 1085 int err = SOCK_ERRNO();
1087 1086
  1087 + TRACE(ENTRIES",read", "Socket read error fd=%d: '%s'\n",
  1088 + SOCKET_FD(socket), strerror(errno));
  1089 +
1088 1090 switch (err) {
1089 1091 #if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN)
1090 1092 case EWOULDBLOCK:
@@ -1371,7 +1373,8 @@ cherokee_socket_bufread (cherokee_socket_t *socket, cherokee_buffer_t *buf, size
1371 1373 buf->buf[buf->len] = '\0';
1372 1374 }
1373 1375
1374   - TRACE (ENTRIES",bufread", "read fd=%d count=%d ret=%d read=%d\n", socket->socket, count, ret, *pcnt_read);
  1376 + TRACE (ENTRIES",bufread", "read fd=%d count=%d ret=%d read=%d\n",
  1377 + socket->socket, count, ret, *pcnt_read);
1375 1378
1376 1379 return ret;
1377 1380 }
@@ -1669,15 +1672,23 @@ cherokee_socket_connect (cherokee_socket_t *sock)
1669 1672 return ret_no_sys;
1670 1673 }
1671 1674
1672   - TRACE (ENTRIES, "connect type=%d ret=%d\n", SOCKET_AF(sock), r);
1673   -
1674 1675 if (r < 0) {
1675 1676 int err = SOCK_ERRNO();
1676 1677
  1678 + TRACE (ENTRIES",connect", "connect error type=%d errno='%s'\n",
  1679 + SOCKET_AF(sock), strerror(err));
  1680 +
1677 1681 switch (err) {
  1682 + case EISCONN:
  1683 + break;
1678 1684 case ECONNREFUSED:
  1685 + case EADDRNOTAVAIL:
1679 1686 return ret_deny;
  1687 + case ETIMEDOUT:
  1688 + return ret_error;
1680 1689 case EAGAIN:
  1690 + case EALREADY:
  1691 + case EINPROGRESS:
1681 1692 #if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN)
1682 1693 case EWOULDBLOCK:
1683 1694 #endif
@@ -1688,6 +1699,8 @@ cherokee_socket_connect (cherokee_socket_t *sock)
1688 1699 }
1689 1700 }
1690 1701
  1702 + TRACE (ENTRIES",connect", "successful connect (type=%d)\n", SOCKET_AF(sock));
  1703 +
1691 1704 sock->status = socket_reading;
1692 1705 return ret_ok;
1693 1706 }
35 cherokee/source.c
@@ -72,39 +72,58 @@ cherokee_source_connect (cherokee_source_t *src, cherokee_socket_t *sock)
72 72 ret_t ret;
73 73 cherokee_resolv_cache_t *resolv;
74 74 cherokee_connector_t *connector;
75   -
76   - ret = cherokee_resolv_cache_get_default (&resolv);
  75 +
  76 + ret = cherokee_connector_get_default (&connector);
77 77 if (unlikely (ret!=ret_ok))
78 78 return ret;
79 79
80   - ret = cherokee_connector_get_default (&connector);
  80 + /* Short path
  81 + */
  82 + if (sock->socket >= 0)
  83 + goto out;
  84 +
  85 + /* Get required objects
  86 + */
  87 + ret = cherokee_resolv_cache_get_default (&resolv);
81 88 if (unlikely (ret!=ret_ok))
82 89 return ret;
83 90
84 91 /* UNIX socket
85 92 */
86 93 if (! cherokee_buffer_is_empty (&src->unix_socket)) {
87   - ret = cherokee_socket_close (sock);
88 94 ret = cherokee_socket_set_client (sock, AF_UNIX);
89 95 if (ret != ret_ok) return ret;
90 96
91 97 ret = cherokee_resolv_cache_get_host (resolv, src->unix_socket.buf, sock);
92 98 if (ret != ret_ok) return ret;
93 99
94   - return cherokee_connector_connect (connector, sock);
  100 + /* Set non-blocking */
  101 + ret = cherokee_fd_set_nonblocking (sock->socket);
  102 + if (ret != ret_ok)
  103 + PRINT_ERRNO (errno, "Failed to set nonblocking (fd=%d): ${errno}\n",
  104 + sock->socket);
  105 +
  106 + goto out;
95 107 }
96 108
97 109 /* INET socket
98 110 */
99   - ret = cherokee_socket_close (sock);
100 111 ret = cherokee_socket_set_client (sock, AF_INET);
101 112 if (ret != ret_ok) return ret;
102   -
  113 +
  114 + /* Query the host */
103 115 ret = cherokee_resolv_cache_get_host (resolv, src->host.buf, sock);
104 116 if (ret != ret_ok) return ret;
105 117
106 118 SOCKET_ADDR_IPv4(sock)->sin_port = htons(src->port);
107   -
  119 +
  120 + /* Set non-blocking */
  121 + ret = cherokee_fd_set_nonblocking (sock->socket);
  122 + if (ret != ret_ok)
  123 + PRINT_ERRNO (errno, "Failed to set nonblocking (fd=%d): ${errno}\n",
  124 + sock->socket);
  125 +
  126 +out:
108 127 return cherokee_connector_connect (connector, sock);
109 128 }
110 129
55 cherokee/thread.c
@@ -521,7 +521,8 @@ process_polling_connections (cherokee_thread_t *thd)
521 521 /* Has it been too much without any work?
522 522 */
523 523 if (conn->timeout < thd->bogo_now) {
524   - TRACE (ENTRIES, "thread (%p) processing polling conn (%p): Time out\n", thd, conn);
  524 + TRACE (ENTRIES",polling", "conn %p(fd=%d): Time out\n",
  525 + conn, SOCKET_FD(&conn->socket));
525 526 purge_closed_polling_connection (thd, conn);
526 527 continue;
527 528 }
@@ -535,11 +536,14 @@ process_polling_connections (cherokee_thread_t *thd)
535 536
536 537 /* Check the "extra" file descriptor
537 538 */
538   - re = cherokee_fdpoll_check (thd->fdpoll, conn->polling_fd, FDPOLL_MODE_READ);
  539 + re = cherokee_fdpoll_check (thd->fdpoll, conn->polling_fd, conn->polling_mode);
539 540 switch (re) {
540 541 case -1:
541 542 /* Error, move back the connection
542 543 */
  544 + TRACE (ENTRIES",polling", "conn %p(fd=%d): status is Error\n",
  545 + conn, SOCKET_FD(&conn->socket));
  546 +
543 547 purge_closed_polling_connection (thd, conn);
544 548 continue;
545 549 case 0:
@@ -1995,7 +1999,7 @@ static ret_t
1995 1999 move_connection_to_polling (cherokee_thread_t *thd, cherokee_connection_t *conn)
1996 2000 {
1997 2001 del_connection (thd, conn);
1998   - add_connection_polling (thd, conn);
  2002 + add_connection_polling (thd, conn);
1999 2003
2000 2004 return ret_ok;
2001 2005 }
@@ -2018,6 +2022,8 @@ reactive_conn_from_polling (cherokee_thread_t *thd, cherokee_connection_t *conn)
2018 2022 cherokee_socket_t *socket = &conn->socket;
2019 2023 cherokee_boolean_t del = true;
2020 2024
  2025 + TRACE (ENTRIES",polling", "conn=%p(fd=%d)\n", conn, SOCKET_FD(socket));
  2026 +
2021 2027 /* Set the connection file descriptor and remove the old one
2022 2028 */
2023 2029 if (conn->polling_multiple)
@@ -2029,45 +2035,57 @@ reactive_conn_from_polling (cherokee_thread_t *thd, cherokee_connection_t *conn)
2029 2035 SHOULDNT_HAPPEN;
2030 2036 }
2031 2037
2032   -/* printf ("- reactive_conn_from_polling %p, multiple=%d del=%d\n", conn, conn->polling_multiple, del); */
2033   -
2034   - cherokee_fdpoll_add (thd->fdpoll, socket->socket, socket->status);
  2038 + ret = cherokee_fdpoll_add (thd->fdpoll, socket->socket, socket->status);
  2039 + if (ret != ret_ok) {
  2040 + return ret_error;
  2041 + }
2035 2042
2036 2043 /* Remove the polling fd from the connection
2037 2044 */
2038 2045 conn->polling_fd = -1;
2039 2046 conn->polling_multiple = false;
  2047 + conn->polling_mode = FDPOLL_MODE_NONE;
2040 2048
2041 2049 return move_connection_to_active (thd, conn);
2042 2050 }
2043 2051
2044 2052
2045 2053 ret_t
2046   -cherokee_thread_deactive_to_polling (cherokee_thread_t *thd, cherokee_connection_t *conn, int fd, int rw, char multiple)
  2054 +cherokee_thread_deactive_to_polling (cherokee_thread_t *thd,
  2055 + cherokee_connection_t *conn,
  2056 + int fd,
  2057 + int rw,
  2058 + char multiple)
2047 2059 {
2048   - ret_t ret;
2049   - cherokee_boolean_t add_fd = true;
2050   - cherokee_socket_t *socket = &conn->socket;
  2060 + ret_t ret;
  2061 + cherokee_boolean_t add_fd = true;
  2062 + cherokee_socket_t *socket = &conn->socket;
  2063 +
  2064 + TRACE (ENTRIES",polling", "conn=%p(fd=%d) (fd=%d, rw=%d)\n",
  2065 + conn, SOCKET_FD(socket), fd, rw);
2051 2066
2052 2067 /* Check for fds added more than once
2053 2068 */
2054 2069 if (multiple)
2055 2070 add_fd = check_addition_multiple_fd (thd, fd);
2056 2071
2057   -/* printf ("+ move_connection_to_polling %p, multiple=%d add=%d fd=%d\n", conn, multiple, add_fd, fd); */
2058   -
2059 2072 /* Remove the connection file descriptor and add the new one
2060 2073 */
2061 2074 ret = cherokee_fdpoll_del (thd->fdpoll, SOCKET_FD(socket));
2062 2075 if (ret != ret_ok)
2063 2076 SHOULDNT_HAPPEN;
2064 2077
2065   - if (add_fd)
2066   - cherokee_fdpoll_add (thd->fdpoll, fd, rw);
  2078 + if (add_fd) {
  2079 + ret = cherokee_fdpoll_add (thd->fdpoll, fd, rw);
  2080 + if (unlikely (ret != ret_ok)) {
  2081 + return ret_error;
  2082 + }
  2083 + }
2067 2084
2068 2085 /* Set the information in the connection
2069 2086 */
2070 2087 conn->polling_fd = fd;
  2088 + conn->polling_mode = rw;
2071 2089 conn->polling_multiple = multiple;
2072 2090
2073 2091 return move_connection_to_polling (thd, conn);
@@ -2092,8 +2110,13 @@ cherokee_thread_retire_active_connection (cherokee_thread_t *thd, cherokee_conne
2092 2110 ret_t
2093 2111 cherokee_thread_inject_active_connection (cherokee_thread_t *thd, cherokee_connection_t *conn)
2094 2112 {
2095   - cherokee_fdpoll_add (thd->fdpoll, SOCKET_FD(&conn->socket), FDPOLL_MODE_WRITE);
2096   - add_connection (thd, conn);
  2113 + ret_t ret;
2097 2114
  2115 + ret = cherokee_fdpoll_add (thd->fdpoll, SOCKET_FD(&conn->socket), FDPOLL_MODE_WRITE);
  2116 + if (ret != ret_ok) {
  2117 + return ret_error;
  2118 + }
  2119 +
  2120 + add_connection (thd, conn);
2098 2121 return ret_ok;
2099 2122 }
41 cherokee/util.c
@@ -33,6 +33,7 @@
33 33 #include <sys/stat.h>
34 34 #include <unistd.h>
35 35 #include <errno.h>
  36 +#include <fcntl.h>
36 37
37 38 #ifdef HAVE_SYS_TIME_H
38 39 # include <sys/time.h>
@@ -611,6 +612,8 @@ cherokee_estimate_va_length (char *fmt, va_list ap)
611 612 break;
612 613 case 'p':
613 614 len += 2; /* Pointer: "0x" + hex value */
  615 + if (sizeof(void *) > sizeof(int))
  616 + lflag = true;
614 617 case 'x':
615 618 ll = lflag ? va_arg(ap, clong_t) : va_arg(ap, int);
616 619 if (unlikely (ll < 0)) {
@@ -789,15 +792,23 @@ cherokee_tls_init (void)
789 792 ret_t
790 793 cherokee_fd_set_nonblocking (int fd)
791 794 {
792   - int tmp = 1;
  795 + int re;
  796 + int flags = 0;
793 797
794 798 #ifdef _WIN32
795 799 tmp = ioctlsocket (fd, FIONBIO, (u_long *)&tmp);
796 800 #else
797   - tmp = ioctl (fd, FIONBIO, &tmp);
  801 + flags = fcntl (fd, F_GETFL, 0);
  802 + if (flags < 0) {
  803 + PRINT_ERRNO (errno, "ERROR: fcntl/F_GETFL fd=%d: ${errno}\n", fd);
  804 + return ret_error;
  805 + }
  806 +
  807 + flags |= O_NONBLOCK;
  808 + re = fcntl (fd, F_SETFL, flags);
798 809 #endif
799   - if (tmp < 0) {
800   - PRINT_ERROR ("ERROR: Setting 'FIONBIO' in socked fd=%d\n", fd);
  810 + if (re < 0) {
  811 + PRINT_ERRNO (errno, "ERROR: Setting 'O_NONBLOCK' to socked fd=%d: ${errno}\n", fd);
801 812 return ret_error;
802 813 }
803 814
@@ -805,28 +816,6 @@ cherokee_fd_set_nonblocking (int fd)
805 816 }
806 817
807 818
808   -/* Return 1 if big-endian (Motorola and Sparc), not little-endian
809   - * (Intel and Vax). We do this work at run-time, rather than at
810   - * configuration time so cross-compilation and general embedded system
811   - * support is simpler.
812   - */
813   -
814   -int
815   -cherokee_isbigendian (void)
816   -{
817   - /* From Harbison & Steele.
818   - */
819   - union {
820   - long l;
821   - char c[sizeof(long)];
822   - } u;
823   -
824   - u.l = 1;
825   - return (u.c[sizeof(long) - 1] == 1);
826   -}
827   -
828   -
829   -
830 819 ret_t
831 820 cherokee_syslog (int priority, cherokee_buffer_t *buf)
832 821 {

0 comments on commit a18b345

Please sign in to comment.
Something went wrong with that request. Please try again.