Permalink
Browse files

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

…7f1-0310-9951-d761b3857238
  • Loading branch information...
1 parent b6e3098 commit a18b3459db37e68429fe2b616bc332db83956f13 @alobbs alobbs committed Aug 1, 2008
View
24 ChangeLog
@@ -1,8 +1,26 @@
+2008-08-01 Alvaro Lopez Ortega <alvaro@alobbs.com>
+
+ * cherokee/socket.c, cherokee/buffer.c, cherokee/connection.c,
+ cherokee/handler_cgi_base.h, cherokee/source.c, cherokee/thread.c,
+ cherokee/handler_fcgi.c, cherokee/util.c, cherokee/handler_cgi.c,
+ cherokee/connection-protected.h, cherokee/handler_scgi.h,
+ cherokee/handler_fcgi.h, cherokee/handler_scgi.c: This jumbo-patch
+ fixes a really nasty bug (and a few other minor issues I found
+ along the way) that caused Cherokee to fail to handle PHP FastCGI
+ overloads "nicely". Actually, the main problem is the lousy
+ FastCGI implementation of php-cgi, which due a design flaw, does
+ not notify when it run out of resources (child processes). This
+ patch makes Cherokee perform much better when the PHP interpreter
+ starts misbehaving. (It would be grand if the PHP crowd would have
+ fixed the php-cgi design problem.. but, well, after 5 years I have
+ lost my faith). At least now Cherokee knows how to deal with such
+ a broken implementation. <sigh!!>
+
2008-07-31 Taher Shihadeh <taher@unixwars.com>
+
* spawn-fastcgi.1: fixed a minor glitch unknowinlgy introduced in
the past.
-2008-07-31 Taher Shihadeh <taher@unixwars.com>
* doc/build/TODO: plan for improved documentation is needed.
2008-07-31 Alvaro Lopez Ortega <alvaro@alobbs.com>
@@ -12,17 +30,21 @@
http://code.google.com/p/cherokee/issues/detail?id=61
2008-07-29 Taher Shihadeh <taher@unixwars.com>
+
* doc/cherokee_tweak.txt: added some documentation.
2008-07-29 Milo van der Linden <milovanderlinden@gmail.com>
+
* doc/admin.txt, doc/compiling_and_installing_unix.txt: some
documentation patches.
2008-07-28 Taher Shihadeh <taher@unixwars.com>
+
* cherokee-tweak.1, cherokee-admin.1, cherokee.1: manpages needed
an update.
2008-07-28 Taher Shihadeh <taher@unixwars.com>
+
* admin/PageEntry.py, admin/PageEncoders.py, admin/PageAdvanced.py,
admin/PageVServers.py, admin/PageGeneral.py, admin/PageMime.py,
admin/PageVServer.py, admin/Form.py, admin/PageFeedback.py,
View
3 cherokee/buffer.c
@@ -554,7 +554,8 @@ cherokee_buffer_add_va_list (cherokee_buffer_t *buf, char *format, va_list args)
/* At this point buf-size is always greater than buf-len, thus size > 0.
*/
if (len >= size) {
- TRACE(ENTRIES, "Failed estimation=%d, needed=%d available size=%d\n", estimation, len, size);
+ PRINT_ERROR ("Failed estimation=%d, needed=%d available size=%d: %s\n",
+ estimation, len, size, format);
cherokee_buffer_ensure_size (buf, buf->len + len + 2);
size = buf->size - buf->len;
View
1 cherokee/connection-protected.h
@@ -173,6 +173,7 @@ struct cherokee_connection {
/* Polling
*/
int polling_fd;
+ int polling_mode;
cherokee_boolean_t polling_multiple;
off_t range_start;
View
14 cherokee/connection.c
@@ -117,6 +117,7 @@ cherokee_connection_new (cherokee_connection_t **conn)
n->timeout = -1;
n->polling_fd = -1;
n->polling_multiple = false;
+ n->polling_mode = FDPOLL_MODE_NONE;
cherokee_buffer_init (&n->buffer);
cherokee_buffer_init (&n->header_buffer);
@@ -196,7 +197,8 @@ cherokee_connection_free (cherokee_connection_t *conn)
if (conn->polling_fd != -1) {
close (conn->polling_fd);
- conn->polling_fd = -1;
+ conn->polling_fd = -1;
+ conn->polling_mode = FDPOLL_MODE_NONE;
}
free (conn);
@@ -234,6 +236,7 @@ cherokee_connection_clean (cherokee_connection_t *conn)
conn->tx_partial = 0;
conn->traffic_next = 0;
conn->polling_multiple = false;
+ conn->polling_mode = FDPOLL_MODE_NONE;
memset (conn->regex_ovector, OVECTOR_LEN * sizeof(int), 0);
conn->regex_ovecsize = 0;
@@ -1898,9 +1901,14 @@ cherokee_connection_print (cherokee_connection_t *conn)
cherokee_buffer_t *buf = &conn->self_trace;
const char *phase;
- phase = cherokee_connection_get_phase_str (conn);
-
cherokee_buffer_clean (buf);
+
+ if (conn == NULL) {
+ cherokee_buffer_add_str (buf, "Connection is NULL\n");
+ return ret_ok;
+ }
+
+ phase = cherokee_connection_get_phase_str (conn);
cherokee_buffer_add_va (buf, "Connection %p info\n", conn);
#define print_buf(title,name) \
View
3 cherokee/handler_cgi.c
@@ -415,6 +415,9 @@ cherokee_handler_cgi_init (cherokee_handler_cgi_t *cgi)
*/
conn->timeout = CONN_THREAD(conn)->bogo_now + CGI_TIMEOUT;
+ cgi_base->init_phase = hcgi_phase_connect;
+
+ case hcgi_phase_connect:
/* Launch the CGI
*/
ret = fork_and_execute_cgi(cgi);
View
1 cherokee/handler_cgi_base.h
@@ -61,6 +61,7 @@ typedef ret_t (* cherokee_handler_cgi_base_read_from_cgi_t) (cherokee_handler_cg
typedef enum {
hcgi_phase_build_headers,
+ hcgi_phase_connect,
hcgi_phase_send_headers,
hcgi_phase_send_post
} cherokee_handler_cgi_base_phase_t;
View
98 cherokee/handler_fcgi.c
@@ -23,12 +23,16 @@
*/
#include "common-internal.h"
+
+#include <fcntl.h>
+
#include "handler_fcgi.h"
#include "header.h"
#include "connection-protected.h"
#include "util.h"
#include "thread.h"
#include "source_interpreter.h"
+#include "bogotime.h"
#include "fastcgi.h"
@@ -285,10 +289,10 @@ cherokee_handler_fcgi_new (cherokee_handler_t **hdl, void *cnt, cherokee_module_
*/
n->post_phase = fcgi_post_init;
n->post_len = 0;
-
- cherokee_socket_init (&n->socket);
- cherokee_socket_set_nodelay (&n->socket);
+ n->src_ref = NULL;
+ n->spawned = 0;
+ cherokee_socket_init (&n->socket);
cherokee_buffer_init (&n->write_buffer);
cherokee_buffer_ensure_size (&n->write_buffer, 512);
@@ -497,46 +501,73 @@ static ret_t
connect_to_server (cherokee_handler_fcgi_t *hdl)
{
ret_t ret;
- int try = 0;
- cherokee_source_t *src = NULL;
- cherokee_connection_t *conn = HANDLER_CONN(hdl);
- cherokee_handler_fcgi_props_t *props = HANDLER_FCGI_PROPS(hdl);
+ cherokee_connection_t *conn = HANDLER_CONN(hdl);
+ cherokee_handler_fcgi_props_t *props = HANDLER_FCGI_PROPS(hdl);
+ cherokee_source_interpreter_t *src_int = SOURCE_INT(hdl->src_ref);
- ret = cherokee_balancer_dispatch (props->balancer, conn, &src);
- if (ret != ret_ok)
- return ret;
+ /* Get a reference to the target host
+ */
+ if (hdl->src_ref == NULL) {
+ ret = cherokee_balancer_dispatch (props->balancer, conn, &hdl->src_ref);
+ if (ret != ret_ok)
+ return ret;
+ }
- ret = cherokee_source_connect (src, &hdl->socket);
- if (ret != ret_ok) {
- cherokee_source_interpreter_t *src_int = SOURCE_INT(src);
+ /* Try to connect
+ */
+ ret = cherokee_source_connect (hdl->src_ref, &hdl->socket);
+ switch (ret) {
+ case ret_ok:
+ goto out;
+ case ret_deny:
+ break;
+ case ret_eagain:
+ ret = cherokee_thread_deactive_to_polling (HANDLER_THREAD(hdl),
+ conn,
+ SOCKET_FD(&hdl->socket),
+ FDPOLL_MODE_WRITE,
+ false);
+ if (ret != ret_ok) {
+ return ret_deny;
+ }
+ return ret_eagain;
+ case ret_error:
+ return ret_error;
+ default:
+ break;
+ }
+
+ /* In case it did not success, launch a interpreter
+ */
+ if (hdl->spawned == 0) {
+ /* Launch a new interpreter */
ret = cherokee_source_interpreter_spawn (src_int);
if (ret != ret_ok) {
if (src_int->interpreter.buf)
- TRACE (ENTRIES, "Couldn't spawn: %s\n", src_int->interpreter.buf);
+ TRACE (ENTRIES, "Couldn't spawn: %s\n",
+ src_int->interpreter.buf);
else
- TRACE (ENTRIES, "There was no interpreter to be spawned %s", "\n");
+ TRACE (ENTRIES, "No interpreter to be spawned %s", "\n");
return ret_error;
}
- while (true) {
- ret = cherokee_source_connect (src, &hdl->socket);
- if (ret == ret_ok)
- break;
+ hdl->spawned = cherokee_bogonow_now;
- TRACE (ENTRIES, "Couldn't connect: %s, try %d\n", src->host.buf ? src->host.buf : src->unix_socket.buf, try);
+ /* Reset the internal socket */
+ cherokee_socket_close (&hdl->socket);
- if (try++ >= 3)
- return ret;
+ } else if (cherokee_bogonow_now > hdl->spawned + 3) {
+ TRACE (ENTRIES, "Giving up; spawned 3 secs ago: %s\n",
+ src_int->interpreter.buf);
+ return ret_error;
- sleep (1);
- }
-
}
- TRACE (ENTRIES, "Connected successfully try=%d, fd=%d\n", try, hdl->socket.socket);
+ return ret_eagain;
- cherokee_fd_set_nonblocking (SOCKET_FD(&hdl->socket));
+out:
+ TRACE (ENTRIES, "Connected successfully fd=%d\n", hdl->socket.socket);
return ret_ok;
}
@@ -707,7 +738,7 @@ cherokee_handler_fcgi_init (cherokee_handler_fcgi_t *hdl)
switch (HDL_CGI_BASE(hdl)->init_phase) {
case hcgi_phase_build_headers:
- TRACE (ENTRIES, "Init %s\n", "begins");
+ TRACE (ENTRIES, "Init: %s\n", "begins");
/* Prepare Post
*/
@@ -726,12 +757,19 @@ cherokee_handler_fcgi_init (cherokee_handler_fcgi_t *hdl)
ret = build_header (hdl, &hdl->write_buffer);
if (unlikely (ret != ret_ok)) return ret;
- /* Connect
+ HDL_CGI_BASE(hdl)->init_phase = hcgi_phase_connect;
+
+ case hcgi_phase_connect:
+ TRACE (ENTRIES, "Init: %s\n", "connect");
+
+ /* Connect
*/
ret = connect_to_server (hdl);
switch (ret) {
case ret_ok:
break;
+ case ret_eagain:
+ return ret_eagain;
case ret_deny:
conn->error_code = http_gateway_timeout;
return ret_error;
@@ -743,7 +781,7 @@ cherokee_handler_fcgi_init (cherokee_handler_fcgi_t *hdl)
HDL_CGI_BASE(hdl)->init_phase = hcgi_phase_send_headers;
case hcgi_phase_send_headers:
- TRACE (ENTRIES, "Init %s\n", "send_headers");
+ TRACE (ENTRIES, "Init: %s\n", "send_headers");
/* Send the header
*/
View
2 cherokee/handler_fcgi.h
@@ -45,6 +45,8 @@ typedef enum {
*/
typedef struct {
cherokee_handler_cgi_base_t base;
+ cherokee_source_t *src_ref;
+ time_t spawned;
cherokee_socket_t socket;
cherokee_handler_fcgi_post_t post_phase;
off_t post_len;
View
101 cherokee/handler_scgi.c
@@ -30,6 +30,7 @@
#include "thread.h"
#include "util.h"
#include "connection-protected.h"
+#include "bogotime.h"
#define ENTRIES "handler,cgi"
@@ -180,6 +181,8 @@ cherokee_handler_scgi_new (cherokee_handler_t **hdl, void *cnt, cherokee_module_
/* Properties
*/
n->post_len = 0;
+ n->spawned = 0;
+ n->src_ref = NULL;
cherokee_buffer_init (&n->header);
cherokee_socket_init (&n->socket);
@@ -248,49 +251,79 @@ build_header (cherokee_handler_scgi_t *hdl)
}
-static ret_t
+
+static ret_t
connect_to_server (cherokee_handler_scgi_t *hdl)
{
ret_t ret;
- cherokee_source_t *src = NULL;
- cherokee_connection_t *conn = HANDLER_CONN(hdl);
- cherokee_handler_scgi_props_t *props = HDL_SCGI_PROPS(hdl);
+ cherokee_connection_t *conn = HANDLER_CONN(hdl);
+ cherokee_handler_scgi_props_t *props = HANDLER_SCGI_PROPS(hdl);
+ cherokee_source_interpreter_t *src_int = SOURCE_INT(hdl->src_ref);
- ret = cherokee_balancer_dispatch (props->balancer, conn, &src);
- if (ret != ret_ok) return ret;
+ /* Get a reference to the target host
+ */
+ if (hdl->src_ref == NULL) {
+ ret = cherokee_balancer_dispatch (props->balancer, conn, &hdl->src_ref);
+ if (ret != ret_ok)
+ return ret;
+ }
- ret = cherokee_source_connect (src, &hdl->socket);
- if (ret != ret_ok) {
- int try = 0;
- cherokee_source_interpreter_t *src_int = SOURCE_INT(src);
+ /* Try to connect
+ */
+ ret = cherokee_source_connect (hdl->src_ref, &hdl->socket);
+ switch (ret) {
+ case ret_ok:
+ goto out;
+ case ret_deny:
+ break;
+ case ret_eagain:
+ ret = cherokee_thread_deactive_to_polling (HANDLER_THREAD(hdl),
+ conn,
+ SOCKET_FD(&hdl->socket),
+ FDPOLL_MODE_WRITE,
+ false);
+ if (ret != ret_ok) {
+ return ret_deny;
+ }
+
+ return ret_eagain;
+ case ret_error:
+ return ret_error;
+ default:
+ break;
+ }
+ /* In case it did not success, launch a interpreter
+ */
+ if (hdl->spawned == 0) {
+ /* Launch a new interpreter */
ret = cherokee_source_interpreter_spawn (src_int);
if (ret != ret_ok) {
if (src_int->interpreter.buf)
- TRACE (ENTRIES, "Couldn't spawn: %s\n", src_int->interpreter.buf);
+ TRACE (ENTRIES, "Couldn't spawn: %s\n",
+ src_int->interpreter.buf);
else
- TRACE (ENTRIES, "There was no interpreter to be spawned %s", "\n");
+ TRACE (ENTRIES, "No interpreter to be spawned %s", "\n");
return ret_error;
}
-
- while (true) {
- ret = cherokee_source_connect (src, &hdl->socket);
- if (ret == ret_ok) break;
- TRACE (ENTRIES, "Couldn't connect: %s, try %d\n", src->host.buf ? src->host.buf : src->unix_socket.buf, try);
+ hdl->spawned = cherokee_bogonow_now;
- if (try++ >= 3)
- return ret;
+ /* Reset the internal socket */
+ cherokee_socket_close (&hdl->socket);
+
+ } else if (cherokee_bogonow_now > hdl->spawned + 3) {
+ TRACE (ENTRIES, "Giving up; spawned 3 secs ago: %s\n",
+ src_int->interpreter.buf);
+ return ret_error;
- sleep (1);
- }
-
}
-
- TRACE (ENTRIES, "connected fd=%d\n", hdl->socket.socket);
- cherokee_fd_set_nonblocking (SOCKET_FD(&hdl->socket));
- return ret_ok;
+ return ret_eagain;
+
+out:
+ TRACE (ENTRIES, "Connected successfully fd=%d\n", hdl->socket.socket);
+ return ret_ok;
}
@@ -306,9 +339,10 @@ send_header (cherokee_handler_scgi_t *hdl)
conn->error_code = http_bad_gateway;
return ret;
}
-
-// cherokee_buffer_print_debug (&hdl->header, -1);
+#if 0
+ cherokee_buffer_print_debug (&hdl->header, -1);
+#endif
cherokee_buffer_move_to_begin (&hdl->header, written);
TRACE (ENTRIES, "sent remaining=%d\n", hdl->header.len);
@@ -354,6 +388,8 @@ cherokee_handler_scgi_init (cherokee_handler_scgi_t *hdl)
switch (HDL_CGI_BASE(hdl)->init_phase) {
case hcgi_phase_build_headers:
+ TRACE (ENTRIES, "Init: %s\n", "begins");
+
/* Extracts PATH_INFO and filename from request uri
*/
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)
return ret_error;
}
+ HDL_CGI_BASE(hdl)->init_phase = hcgi_phase_connect;
+
+ case hcgi_phase_connect:
+ TRACE (ENTRIES, "Init: %s\n", "connect");
+
/* Connect
*/
ret = connect_to_server (hdl);
switch (ret) {
case ret_ok:
break;
+ case ret_eagain:
+ return ret_eagain;
case ret_deny:
conn->error_code = http_gateway_timeout;
return ret_error;
@@ -394,6 +437,8 @@ cherokee_handler_scgi_init (cherokee_handler_scgi_t *hdl)
HDL_CGI_BASE(hdl)->init_phase = hcgi_phase_send_headers;
case hcgi_phase_send_headers:
+ TRACE (ENTRIES, "Init: %s\n", "send_headers");
+
/* Send the header
*/
ret = send_header (hdl);
View
8 cherokee/handler_scgi.h
@@ -46,12 +46,14 @@ typedef struct {
cherokee_handler_cgi_base_t base;
cherokee_buffer_t header;
cherokee_socket_t socket;
+ cherokee_source_t *src_ref;
+ time_t spawned;
off_t post_len;
} cherokee_handler_scgi_t;
-#define HDL_SCGI(x) ((cherokee_handler_scgi_t *)(x))
-#define PROP_SCGI(x) ((cherokee_handler_scgi_props_t *)(x))
-#define HDL_SCGI_PROPS(x) (PROP_SCGI(MODULE(x)->props))
+#define HDL_SCGI(x) ((cherokee_handler_scgi_t *)(x))
+#define PROP_SCGI(x) ((cherokee_handler_scgi_props_t *)(x))
+#define HANDLER_SCGI_PROPS(x) (PROP_SCGI(MODULE(x)->props))
/* Library init function
View
25 cherokee/socket.c
@@ -507,13 +507,11 @@ cherokee_socket_close (cherokee_socket_t *socket)
#ifdef HAVE_TLS
if (socket->is_tls == TLS && socket->session != NULL) {
#if defined (HAVE_GNUTLS)
-
gnutls_bye (socket->session, GNUTLS_SHUT_WR);
gnutls_deinit (socket->session);
socket->session = NULL;
#elif defined (HAVE_OPENSSL)
-
SSL_shutdown (socket->session);
#endif
@@ -522,7 +520,8 @@ cherokee_socket_close (cherokee_socket_t *socket)
ret = cherokee_close_fd (socket->socket);
- TRACE (ENTRIES",close", "fd=%d is_tls=%d re=%d\n", socket->socket, socket->is_tls, (int) ret);
+ TRACE (ENTRIES",close", "fd=%d is_tls=%d re=%d\n",
+ socket->socket, socket->is_tls, (int) ret);
socket->socket = -1;
socket->status = socket_closed;
@@ -1085,6 +1084,9 @@ cherokee_socket_read (cherokee_socket_t *socket, char *buf, int buf_size, size_t
{ /* len < 0 */
int err = SOCK_ERRNO();
+ TRACE(ENTRIES",read", "Socket read error fd=%d: '%s'\n",
+ SOCKET_FD(socket), strerror(errno));
+
switch (err) {
#if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN)
case EWOULDBLOCK:
@@ -1371,7 +1373,8 @@ cherokee_socket_bufread (cherokee_socket_t *socket, cherokee_buffer_t *buf, size
buf->buf[buf->len] = '\0';
}
- TRACE (ENTRIES",bufread", "read fd=%d count=%d ret=%d read=%d\n", socket->socket, count, ret, *pcnt_read);
+ TRACE (ENTRIES",bufread", "read fd=%d count=%d ret=%d read=%d\n",
+ socket->socket, count, ret, *pcnt_read);
return ret;
}
@@ -1669,15 +1672,23 @@ cherokee_socket_connect (cherokee_socket_t *sock)
return ret_no_sys;
}
- TRACE (ENTRIES, "connect type=%d ret=%d\n", SOCKET_AF(sock), r);
-
if (r < 0) {
int err = SOCK_ERRNO();
+ TRACE (ENTRIES",connect", "connect error type=%d errno='%s'\n",
+ SOCKET_AF(sock), strerror(err));
+
switch (err) {
+ case EISCONN:
+ break;
case ECONNREFUSED:
+ case EADDRNOTAVAIL:
return ret_deny;
+ case ETIMEDOUT:
+ return ret_error;
case EAGAIN:
+ case EALREADY:
+ case EINPROGRESS:
#if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN)
case EWOULDBLOCK:
#endif
@@ -1688,6 +1699,8 @@ cherokee_socket_connect (cherokee_socket_t *sock)
}
}
+ TRACE (ENTRIES",connect", "successful connect (type=%d)\n", SOCKET_AF(sock));
+
sock->status = socket_reading;
return ret_ok;
}
View
35 cherokee/source.c
@@ -72,39 +72,58 @@ cherokee_source_connect (cherokee_source_t *src, cherokee_socket_t *sock)
ret_t ret;
cherokee_resolv_cache_t *resolv;
cherokee_connector_t *connector;
-
- ret = cherokee_resolv_cache_get_default (&resolv);
+
+ ret = cherokee_connector_get_default (&connector);
if (unlikely (ret!=ret_ok))
return ret;
- ret = cherokee_connector_get_default (&connector);
+ /* Short path
+ */
+ if (sock->socket >= 0)
+ goto out;
+
+ /* Get required objects
+ */
+ ret = cherokee_resolv_cache_get_default (&resolv);
if (unlikely (ret!=ret_ok))
return ret;
/* UNIX socket
*/
if (! cherokee_buffer_is_empty (&src->unix_socket)) {
- ret = cherokee_socket_close (sock);
ret = cherokee_socket_set_client (sock, AF_UNIX);
if (ret != ret_ok) return ret;
ret = cherokee_resolv_cache_get_host (resolv, src->unix_socket.buf, sock);
if (ret != ret_ok) return ret;
- return cherokee_connector_connect (connector, sock);
+ /* Set non-blocking */
+ ret = cherokee_fd_set_nonblocking (sock->socket);
+ if (ret != ret_ok)
+ PRINT_ERRNO (errno, "Failed to set nonblocking (fd=%d): ${errno}\n",
+ sock->socket);
+
+ goto out;
}
/* INET socket
*/
- ret = cherokee_socket_close (sock);
ret = cherokee_socket_set_client (sock, AF_INET);
if (ret != ret_ok) return ret;
-
+
+ /* Query the host */
ret = cherokee_resolv_cache_get_host (resolv, src->host.buf, sock);
if (ret != ret_ok) return ret;
SOCKET_ADDR_IPv4(sock)->sin_port = htons(src->port);
-
+
+ /* Set non-blocking */
+ ret = cherokee_fd_set_nonblocking (sock->socket);
+ if (ret != ret_ok)
+ PRINT_ERRNO (errno, "Failed to set nonblocking (fd=%d): ${errno}\n",
+ sock->socket);
+
+out:
return cherokee_connector_connect (connector, sock);
}
View
55 cherokee/thread.c
@@ -521,7 +521,8 @@ process_polling_connections (cherokee_thread_t *thd)
/* Has it been too much without any work?
*/
if (conn->timeout < thd->bogo_now) {
- TRACE (ENTRIES, "thread (%p) processing polling conn (%p): Time out\n", thd, conn);
+ TRACE (ENTRIES",polling", "conn %p(fd=%d): Time out\n",
+ conn, SOCKET_FD(&conn->socket));
purge_closed_polling_connection (thd, conn);
continue;
}
@@ -535,11 +536,14 @@ process_polling_connections (cherokee_thread_t *thd)
/* Check the "extra" file descriptor
*/
- re = cherokee_fdpoll_check (thd->fdpoll, conn->polling_fd, FDPOLL_MODE_READ);
+ re = cherokee_fdpoll_check (thd->fdpoll, conn->polling_fd, conn->polling_mode);
switch (re) {
case -1:
/* Error, move back the connection
*/
+ TRACE (ENTRIES",polling", "conn %p(fd=%d): status is Error\n",
+ conn, SOCKET_FD(&conn->socket));
+
purge_closed_polling_connection (thd, conn);
continue;
case 0:
@@ -1995,7 +1999,7 @@ static ret_t
move_connection_to_polling (cherokee_thread_t *thd, cherokee_connection_t *conn)
{
del_connection (thd, conn);
- add_connection_polling (thd, conn);
+ add_connection_polling (thd, conn);
return ret_ok;
}
@@ -2018,6 +2022,8 @@ reactive_conn_from_polling (cherokee_thread_t *thd, cherokee_connection_t *conn)
cherokee_socket_t *socket = &conn->socket;
cherokee_boolean_t del = true;
+ TRACE (ENTRIES",polling", "conn=%p(fd=%d)\n", conn, SOCKET_FD(socket));
+
/* Set the connection file descriptor and remove the old one
*/
if (conn->polling_multiple)
@@ -2029,45 +2035,57 @@ reactive_conn_from_polling (cherokee_thread_t *thd, cherokee_connection_t *conn)
SHOULDNT_HAPPEN;
}
-/* printf ("- reactive_conn_from_polling %p, multiple=%d del=%d\n", conn, conn->polling_multiple, del); */
-
- cherokee_fdpoll_add (thd->fdpoll, socket->socket, socket->status);
+ ret = cherokee_fdpoll_add (thd->fdpoll, socket->socket, socket->status);
+ if (ret != ret_ok) {
+ return ret_error;
+ }
/* Remove the polling fd from the connection
*/
conn->polling_fd = -1;
conn->polling_multiple = false;
+ conn->polling_mode = FDPOLL_MODE_NONE;
return move_connection_to_active (thd, conn);
}
ret_t
-cherokee_thread_deactive_to_polling (cherokee_thread_t *thd, cherokee_connection_t *conn, int fd, int rw, char multiple)
+cherokee_thread_deactive_to_polling (cherokee_thread_t *thd,
+ cherokee_connection_t *conn,
+ int fd,
+ int rw,
+ char multiple)
{
- ret_t ret;
- cherokee_boolean_t add_fd = true;
- cherokee_socket_t *socket = &conn->socket;
+ ret_t ret;
+ cherokee_boolean_t add_fd = true;
+ cherokee_socket_t *socket = &conn->socket;
+
+ TRACE (ENTRIES",polling", "conn=%p(fd=%d) (fd=%d, rw=%d)\n",
+ conn, SOCKET_FD(socket), fd, rw);
/* Check for fds added more than once
*/
if (multiple)
add_fd = check_addition_multiple_fd (thd, fd);
-/* printf ("+ move_connection_to_polling %p, multiple=%d add=%d fd=%d\n", conn, multiple, add_fd, fd); */
-
/* Remove the connection file descriptor and add the new one
*/
ret = cherokee_fdpoll_del (thd->fdpoll, SOCKET_FD(socket));
if (ret != ret_ok)
SHOULDNT_HAPPEN;
- if (add_fd)
- cherokee_fdpoll_add (thd->fdpoll, fd, rw);
+ if (add_fd) {
+ ret = cherokee_fdpoll_add (thd->fdpoll, fd, rw);
+ if (unlikely (ret != ret_ok)) {
+ return ret_error;
+ }
+ }
/* Set the information in the connection
*/
conn->polling_fd = fd;
+ conn->polling_mode = rw;
conn->polling_multiple = multiple;
return move_connection_to_polling (thd, conn);
@@ -2092,8 +2110,13 @@ cherokee_thread_retire_active_connection (cherokee_thread_t *thd, cherokee_conne
ret_t
cherokee_thread_inject_active_connection (cherokee_thread_t *thd, cherokee_connection_t *conn)
{
- cherokee_fdpoll_add (thd->fdpoll, SOCKET_FD(&conn->socket), FDPOLL_MODE_WRITE);
- add_connection (thd, conn);
+ ret_t ret;
+ ret = cherokee_fdpoll_add (thd->fdpoll, SOCKET_FD(&conn->socket), FDPOLL_MODE_WRITE);
+ if (ret != ret_ok) {
+ return ret_error;
+ }
+
+ add_connection (thd, conn);
return ret_ok;
}
View
41 cherokee/util.c
@@ -33,6 +33,7 @@
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
+#include <fcntl.h>
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
@@ -611,6 +612,8 @@ cherokee_estimate_va_length (char *fmt, va_list ap)
break;
case 'p':
len += 2; /* Pointer: "0x" + hex value */
+ if (sizeof(void *) > sizeof(int))
+ lflag = true;
case 'x':
ll = lflag ? va_arg(ap, clong_t) : va_arg(ap, int);
if (unlikely (ll < 0)) {
@@ -789,44 +792,30 @@ cherokee_tls_init (void)
ret_t
cherokee_fd_set_nonblocking (int fd)
{
- int tmp = 1;
+ int re;
+ int flags = 0;
#ifdef _WIN32
tmp = ioctlsocket (fd, FIONBIO, (u_long *)&tmp);
#else
- tmp = ioctl (fd, FIONBIO, &tmp);
+ flags = fcntl (fd, F_GETFL, 0);
+ if (flags < 0) {
+ PRINT_ERRNO (errno, "ERROR: fcntl/F_GETFL fd=%d: ${errno}\n", fd);
+ return ret_error;
+ }
+
+ flags |= O_NONBLOCK;
+ re = fcntl (fd, F_SETFL, flags);
#endif
- if (tmp < 0) {
- PRINT_ERROR ("ERROR: Setting 'FIONBIO' in socked fd=%d\n", fd);
+ if (re < 0) {
+ PRINT_ERRNO (errno, "ERROR: Setting 'O_NONBLOCK' to socked fd=%d: ${errno}\n", fd);
return ret_error;
}
return ret_ok;
}
-/* Return 1 if big-endian (Motorola and Sparc), not little-endian
- * (Intel and Vax). We do this work at run-time, rather than at
- * configuration time so cross-compilation and general embedded system
- * support is simpler.
- */
-
-int
-cherokee_isbigendian (void)
-{
- /* From Harbison & Steele.
- */
- union {
- long l;
- char c[sizeof(long)];
- } u;
-
- u.l = 1;
- return (u.c[sizeof(long) - 1] == 1);
-}
-
-
-
ret_t
cherokee_syslog (int priority, cherokee_buffer_t *buf)
{

0 comments on commit a18b345

Please sign in to comment.