Changeset 1912
- Timestamp:
- 08/29/08 18:08:46 (3 months ago)
- Files:
-
- cherokee/trunk/ChangeLog (modified) (1 diff)
- cherokee/trunk/cherokee/connection-protected.h (modified) (1 diff)
- cherokee/trunk/cherokee/connection.c (modified) (2 diffs)
- cherokee/trunk/cherokee/handler_scgi.c (modified) (2 diffs)
- cherokee/trunk/cherokee/server-protected.h (modified) (2 diffs)
- cherokee/trunk/cherokee/server.c (modified) (7 diffs)
- cherokee/trunk/cherokee/socket.c (modified) (1 diff)
- cherokee/trunk/cherokee/socket.h (modified) (1 diff)
- cherokee/trunk/cherokee/source.c (modified) (3 diffs)
- cherokee/trunk/cherokee/thread.c (modified) (10 diffs)
- cherokee/trunk/cherokee/thread.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
cherokee/trunk/ChangeLog
r1911 r1912 1 2008-08-29 Alvaro Lopez Ortega <alvaro@alobbs.com> 2 3 * cherokee/socket.c, cherokee/connection-protected.h, 4 cherokee/socket.h, cherokee/source.c, cherokee/thread.c, 5 cherokee/thread.h, cherokee/handler_scgi.c, cherokee/server.c, 6 cherokee/server-protected.h, cherokee/connection.c: This patch 7 fixes a problem with Keep-Alive connections. It also cleans up a 8 few related methods. 9 1 10 2008-08-28 Alvaro Lopez Ortega <alvaro@alobbs.com> 2 11 cherokee/trunk/cherokee/connection-protected.h
r1880 r1912 86 86 #define conn_op_tcp_cork (1 << 2) 87 87 #define conn_op_document_root (1 << 3) 88 #define conn_op_was_polling (1 << 4) 88 89 89 90 typedef cuint_t cherokee_connection_options_t; cherokee/trunk/cherokee/connection.c
r1909 r1912 1784 1784 /* Check the Max concurrent Keep-Alive limit on this thread 1785 1785 */ 1786 if (thread->conns_ max > srv->conns_keepalive_max) {1786 if (thread->conns_num >= thread->conns_keepalive_max) { 1787 1787 conn->keepalive = 0; 1788 1788 return; … … 1795 1795 if (strncasecmp (ptr, "close", 5) == 0) { 1796 1796 conn->keepalive = 0; 1797 } else {1797 } else if (conn->keepalive == 0) { 1798 1798 conn->keepalive = CONN_SRV(conn)->keepalive_max; 1799 1799 } 1800 } else { 1801 conn->keepalive = 0; 1802 } 1800 return; 1801 } 1802 1803 /* When in doubt, disable keep-alive 1804 */ 1805 conn->keepalive = 0; 1803 1806 } 1804 1807 cherokee/trunk/cherokee/handler_scgi.c
r1879 r1912 270 270 /* Try to connect 271 271 */ 272 if (hdl->src_ref->type == source_host) 273 return cherokee_source_connect_polling (hdl->src_ref, &hdl->socket, conn); 274 275 return cherokee_source_interpreter_connect_polling (SOURCE_INT(hdl->src_ref), 276 &hdl->socket, conn, 277 &hdl->spawned); 272 if (hdl->src_ref->type == source_host) { 273 ret = cherokee_source_connect_polling (hdl->src_ref, 274 &hdl->socket, conn); 275 } else { 276 ret = cherokee_source_interpreter_connect_polling (SOURCE_INT(hdl->src_ref), 277 &hdl->socket, conn, 278 &hdl->spawned); 279 } 280 281 return ret; 278 282 } 279 283 … … 394 398 */ 395 399 ret = send_header (hdl); 396 if (ret != ret_ok) return ret; 400 if (ret != ret_ok) 401 return ret; 397 402 398 403 HDL_CGI_BASE(hdl)->init_phase = hcgi_phase_send_post; cherokee/trunk/cherokee/server-protected.h
r1799 r1912 106 106 int fdlimit_custom; 107 107 int fdlimit_available; 108 int fdlimit_per_thread;109 108 cherokee_poll_type_t fdpoll_method; 110 109 … … 113 112 cuint_t conns_max; 114 113 cint_t conns_reuse_max; 115 cuint_t conns_keepalive_max;116 114 cuint_t conns_num_bogo; 117 115 cherokee/trunk/cherokee/server.c
r1812 r1912 148 148 n->fdlimit_custom = -1; 149 149 n->fdlimit_available = -1; 150 n->fdlimit_per_thread = -1;151 150 152 151 n->conns_max = 0; 153 152 n->conns_reuse_max = -1; 154 n->conns_keepalive_max = 0;155 153 n->conns_num_bogo = 0; 156 154 … … 596 594 if (srv->thread_num <= 1) { 597 595 cherokee_buffer_add_str (&n, ", single thread"); 598 cherokee_buffer_add_va (&n, ", %d fds", srv->fdlimit_per_thread);599 596 } else { 600 597 cherokee_buffer_add_va (&n, ", %d threads", srv->thread_num); 601 cherokee_buffer_add_va (&n, ", %d fds per thread", srv->fdlimit_per_thread);598 cherokee_buffer_add_va (&n, ", %d connections per thread", srv->main_thread->conns_max); 602 599 603 600 switch (srv->thread_policy) { … … 677 674 cint_t i; 678 675 cuint_t fds_per_thread; 679 cuint_t fds_per_thread1;680 676 cuint_t conns_per_thread; 681 682 #ifdef HAVE_PTHREAD 683 cuint_t thr_fds; 684 cuint_t spare_fds; 685 #endif 677 cuint_t keepalive_per_thread; 678 cuint_t conns_keepalive_max; 686 679 687 680 /* Reset max. conns value 688 681 */ 689 srv->conns_max = 0; 690 srv->conns_num_bogo = 0; 691 srv->conns_keepalive_max = 0; 682 srv->conns_max = 0; 683 srv->conns_num_bogo = 0; 692 684 693 685 /* Set fd upper limit for threads. … … 703 695 #endif 704 696 705 fds_per_thread1 = fds_per_thread = srv->fdlimit_available / srv->thread_num; 706 707 #ifdef HAVE_PTHREAD 708 thr_fds = fds_per_thread * srv->thread_num; 709 spare_fds = srv->fdlimit_available - thr_fds; 710 711 /* Add a couple more fds to this thread, 712 * this is useful if we are using a huge number of threads 713 * (i.e. 1000 or more) and we don't want to leave lots of 714 * unused fds. 715 */ 716 if (spare_fds >= 2) { 717 spare_fds -= 2; 718 fds_per_thread1 += 2; 719 } 720 #else 721 fds_per_thread1 -= MAX_LISTEN_FDS; 722 #endif 697 /* Set fds and connections limits 698 */ 699 fds_per_thread = (srv->fdlimit_available / srv->thread_num); 700 fds_per_thread -= MAX_LISTEN_FDS; 701 723 702 /* Get fdpoll limits. 724 703 */ … … 729 708 ret = cherokee_fdpoll_get_fdlimits (srv->fdpoll_method, &sys_fd_limit, &poll_fd_limit); 730 709 if (ret != ret_ok) { 731 PRINT_ERROR ("cherokee_fdpoll_get_fdlimits: failed %d (poll_type %d)\n", (int)ret, (int) srv->fdpoll_method); 710 PRINT_ERROR ("cherokee_fdpoll_get_fdlimits: failed %d (poll_type %d)\n", 711 (int)ret, (int) srv->fdpoll_method); 732 712 return ret_error; 733 713 } 734 714 735 /* Test system fd limit (no autotune here) .715 /* Test system fd limit (no autotune here) 736 716 */ 737 717 if ((sys_fd_limit > 0) && 738 718 (cherokee_fdlimit > sys_fd_limit)) { 739 PRINT_ERROR ("system_fd_limit %d > %d sys_fd_limit\n", cherokee_fdlimit, sys_fd_limit); 719 PRINT_ERROR ("system_fd_limit %d > %d sys_fd_limit\n", 720 cherokee_fdlimit, sys_fd_limit); 740 721 return ret_error; 741 722 } 742 723 743 /* If polling set limit has too many fds, 744 * thendecrease that number.724 /* If polling set limit has too many fds, then 725 * decrease that number. 745 726 */ 746 if (poll_fd_limit > 0 && 747 fds_per_thread1 > poll_fd_limit) { 748 PRINT_ERROR ("fds_per_thread1 %d > %d poll_fd_limit (reduce that limit)\n", fds_per_thread1, poll_fd_limit); 749 fds_per_thread1 = poll_fd_limit - MAX_LISTEN_FDS; 750 } 751 } 752 753 /* Max. number of connections is halved because opening a new file 754 * or using a socket to connect to an external helper 755 * might be required to satisfy a request coming from an accepted 756 * and thus already open connection. 757 */ 758 conns_per_thread = fds_per_thread1 / 2; 759 srv->conns_max += conns_per_thread; 760 fds_per_thread1 += MAX_LISTEN_FDS; 761 762 /* Set mean fds per thread. 763 */ 764 srv->fdlimit_per_thread = fds_per_thread1; 727 if ((poll_fd_limit > 0) && 728 (fds_per_thread > poll_fd_limit)) 729 { 730 PRINT_ERROR ("fds_per_thread %d > %d poll_fd_limit (reduce that limit)\n", 731 fds_per_thread, poll_fd_limit); 732 fds_per_thread = poll_fd_limit - MAX_LISTEN_FDS; 733 } 734 } 735 736 /* Max conn number: Supposes two fds per connection 737 */ 738 srv->conns_max = ((srv->fdlimit_available - MAX_LISTEN_FDS) / 2); 739 if (srv->conns_max > 2) 740 srv->conns_max -= 1; 741 742 /* Max keep-alive connections: 743 * Limit over which a thread doesn't allow keepalive 744 */ 745 conns_keepalive_max = srv->conns_max - (srv->conns_max / 16); 746 if (conns_keepalive_max + 6 > srv->conns_max) 747 conns_keepalive_max = srv->conns_max - 6; 748 749 /* Per thread limits 750 */ 751 conns_per_thread = (srv->conns_max / srv->thread_num); 752 keepalive_per_thread = (conns_keepalive_max / srv->thread_num); 765 753 766 754 /* Create the main thread (only structures, not a real thread) 767 755 */ 768 756 ret = cherokee_thread_new (&srv->main_thread, srv, thread_sync, 769 srv->fdpoll_method, cherokee_fdlimit, 770 fds_per_thread1, conns_per_thread); 757 srv->fdpoll_method, 758 cherokee_fdlimit, 759 fds_per_thread, 760 conns_per_thread, 761 keepalive_per_thread); 771 762 if (unlikely(ret < ret_ok)) { 772 763 PRINT_ERROR("cherokee_thread_new (main_thread) failed %d\n", ret); … … 796 787 cherokee_thread_t *thread; 797 788 798 /* Add a couple more fds to this thread,799 * this is useful if we are using a huge number of threads800 * (i.e. 1000 or more) and we don't want to leave lots of801 * unused fds.802 */803 fds_per_thread1 = fds_per_thread;804 if (spare_fds >= 2) {805 spare_fds -= 2;806 fds_per_thread1 += 2;807 }808 conns_per_thread = fds_per_thread1 / 2;809 srv->conns_max += conns_per_thread;810 fds_per_thread1 += MAX_LISTEN_FDS;811 812 /* NOTE: mean fds per thread has already been set above.813 */814 815 789 /* Create a real thread. 816 790 */ 817 ret = cherokee_thread_new (&thread, srv, thread_async, 818 srv->fdpoll_method, cherokee_fdlimit, 819 fds_per_thread1, conns_per_thread); 791 ret = cherokee_thread_new (&thread, srv, thread_async, 792 srv->fdpoll_method, 793 cherokee_fdlimit, 794 fds_per_thread, 795 conns_per_thread, 796 keepalive_per_thread); 820 797 if (unlikely(ret < ret_ok)) { 821 798 PRINT_ERROR("cherokee_thread_new() failed %d\n", ret); … … 828 805 } 829 806 #endif 830 831 /* Set keepalive limit for open connections.832 * NOTE: this limit has to be lower (93%)833 * than conns_accept limit (95% - 99%) used for threads.834 */835 srv->conns_keepalive_max = srv->conns_max - (srv->conns_max / 16);836 if (srv->conns_keepalive_max + 6 > srv->conns_max)837 srv->conns_keepalive_max = srv->conns_max - 6;838 807 839 808 return ret_ok; cherokee/trunk/cherokee/socket.c
r1893 r1912 1259 1259 1260 1260 1261 ret_t 1262 cherokee_socket_flush (cherokee_socket_t *socket) 1263 { 1264 int re; 1265 int op = 1; 1266 1267 re = setsockopt (SOCKET_FD(socket), IPPROTO_TCP, TCP_NODELAY, 1268 (const void *) &op, sizeof(int)); 1269 if (unlikely(re != 0)) 1270 return ret_error; 1271 1272 return ret_ok; 1273 } 1274 1275 1261 1276 /* WARNING: all parameters MUST be valid, 1262 1277 * NULL pointers lead to a crash. 1263 1278 */ 1264 1279 ret_t 1265 cherokee_socket_writev (cherokee_socket_t *socket, const struct iovec *vector, uint16_t vector_len, size_t *pcnt_written) 1280 cherokee_socket_writev (cherokee_socket_t *socket, 1281 const struct iovec *vector, 1282 uint16_t vector_len, 1283 size_t *pcnt_written) 1266 1284 { 1267 1285 *pcnt_written = 0; cherokee/trunk/cherokee/socket.h
r1890 r1912 192 192 ret_t cherokee_socket_accept (cherokee_socket_t *socket, int server_socket); 193 193 int cherokee_socket_pending_read (cherokee_socket_t *socket); 194 ret_t cherokee_socket_flush (cherokee_socket_t *socket); 194 195 195 196 ret_t cherokee_socket_set_client (cherokee_socket_t *socket, unsigned short int type); cherokee/trunk/cherokee/source.c
r1849 r1912 75 75 cherokee_resolv_cache_t *resolv; 76 76 77 /* Short path 78 */ 79 if (sock->socket >= 0) 77 /* Short path: it's already connecting 78 */ 79 if (sock->socket >= 0) 80 80 goto out; 81 81 … … 100 100 /* Set non-blocking */ 101 101 ret = cherokee_fd_set_nonblocking (sock->socket, true); 102 if (ret != ret_ok) 102 if (ret != ret_ok) { 103 103 PRINT_ERRNO (errno, "Failed to set nonblocking (fd=%d): ${errno}\n", 104 104 sock->socket); 105 } 105 106 106 107 goto out; … … 120 121 /* Set non-blocking */ 121 122 ret = cherokee_fd_set_nonblocking (sock->socket, true); 122 if (ret != ret_ok) 123 if (ret != ret_ok) { 123 124 PRINT_ERRNO (errno, "Failed to set nonblocking (fd=%d): ${errno}\n", 124 125 sock->socket); 126 } 125 127 126 128 out: cherokee/trunk/cherokee/thread.c
r1859 r1912 78 78 79 79 80 #ifdef HAVE_PTHREAD 80 #ifdef HAVE_PTHREAD 81 81 static void * 82 82 thread_routine (void *data) … … 130 130 cherokee_thread_type_t type, 131 131 cherokee_poll_type_t fdpoll_type, 132 int system_fd_num, 133 int fd_num, 134 int conns_max) 132 cint_t system_fd_num, 133 cint_t fd_num, 134 cint_t conns_max, 135 cint_t keepalive_max) 135 136 { 136 137 ret_t ret; … … 145 146 INIT_LIST_HEAD (LIST(&n->polling_list)); 146 147 147 n->exit = false; 148 n->server = server; 149 n->thread_type = type; 150 151 n->conns_num = 0; 152 n->conns_max = conns_max; 153 154 n->active_list_num = 0; 155 n->polling_list_num = 0; 156 n->reuse_list_num = 0; 157 158 n->pending_conns_num = 0; 159 n->pending_read_num = 0; 160 161 n->fastcgi_servers = NULL; 162 n->fastcgi_free_func = NULL; 148 n->exit = false; 149 n->server = server; 150 n->thread_type = type; 151 152 n->conns_num = 0; 153 n->conns_max = conns_max; 154 n->conns_keepalive_max = keepalive_max; 155 156 n->active_list_num = 0; 157 n->polling_list_num = 0; 158 n->reuse_list_num = 0; 159 160 n->pending_conns_num = 0; 161 n->pending_read_num = 0; 162 163 n->fastcgi_servers = NULL; 164 n->fastcgi_free_func = NULL; 163 165 164 166 /* Event poll object … … 492 494 conn_set_mode (thread, conn, socket_reading); 493 495 496 /* Flush any buffered data 497 */ 498 cherokee_socket_flush (&conn->socket); 499 494 500 /* Update the timeout value 495 501 */ … … 592 598 * and it's not reading header or there is no more buffered data. 593 599 */ 594 if ((conn->phase != phase_shutdown) && 600 if ((! (conn->options & conn_op_was_polling)) && 601 (conn->phase != phase_shutdown) && 595 602 (conn->phase != phase_lingering) && 596 603 (conn->phase != phase_reading_header || conn->incoming_header.len <= 0)) … … 598 605 re = cherokee_fdpoll_check (thd->fdpoll, 599 606 SOCKET_FD(&conn->socket), 600 SOCKET_STATUS(&conn->socket));607 conn->socket.status); 601 608 switch (re) { 602 609 case -1: … … 608 615 continue; 609 616 } 617 } 618 619 /* This connection was polling a moment ago 620 */ 621 if (conn->options & conn_op_was_polling) { 622 BIT_UNSET (conn->options, conn_op_was_polling); 610 623 } 611 624 … … 657 670 */ 658 671 if (conn->error_code == http_switching_protocols) { 659 conn->phase = phase_setup_connection; 672 conn->phase = phase_setup_connection; 660 673 conn->error_code = http_ok; 661 674 continue; … … 726 739 /* Maybe the buffer has a request (previous pipelined) 727 740 */ 728 if (! cherokee_buffer_is_empty (&conn->incoming_header)) { 741 if (! cherokee_buffer_is_empty (&conn->incoming_header)) 742 { 729 743 ret = cherokee_header_has_header (&conn->header, 730 744 &conn->incoming_header, … … 2078 2092 conn->polling_mode = FDPOLL_MODE_NONE; 2079 2093 2094 BIT_SET (conn->options, conn_op_was_polling); 2095 2080 2096 return move_connection_to_active (thd, conn); 2081 2097 } cherokee/trunk/cherokee/thread.h
r1838 r1912 75 75 cherokee_boolean_t exit; 76 76 77 cuint_t conns_num; /* open connections */ 78 cuint_t conns_max; /* max opened conns */ 77 cuint_t conns_num; /* open connections */ 78 cuint_t conns_max; /* max opened conns */ 79 cuint_t conns_keepalive_max; /* max opened conns */ 79 80 80 int active_list_num; /* active connections */81 int active_list_num; /* active connections */ 81 82 cherokee_list_t active_list; 82 int polling_list_num; /* polling connections */83 int polling_list_num; /* polling connections */ 83 84 cherokee_list_t polling_list; 84 85 cherokee_list_t reuse_list; 85 int reuse_list_num; /* reusable connections objs */86 int reuse_list_num; /* reusable connections objs */ 86 87 87 int pending_conns_num; /* Waiting pipelining connections */88 int pending_read_num; /* Conns with SSL deping read */88 int pending_conns_num; /* Waiting pipelining connections */ 89 int pending_read_num; /* Conns with SSL deping read */ 89 90 90 91 struct { … … 114 115 115 116 116 ret_t cherokee_thread_new (cherokee_thread_t **thd, void *server, cherokee_thread_type_t type, cherokee_poll_type_t fdtype, int system_fd_num, int fd_num, int conns_max); 117 ret_t cherokee_thread_free (cherokee_thread_t *thd); 117 ret_t cherokee_thread_new (cherokee_thread_t **thd, 118 void *server, 119 cherokee_thread_type_t type, 120 cherokee_poll_type_t fdtype, 121 cint_t system_fd_num, 122 cint_t fds_max, 123 cint_t conns_max, 124 cint_t keepalive_max); 125 126 ret_t cherokee_thread_free (cherokee_thread_t *thd); 118 127 119 128 ret_t cherokee_thread_accept_on (cherokee_thread_t *thd);