mirror of
https://git.gnunet.org/libmicrohttpd.git
synced 2026-09-26 04:09:30 +03:00
adding experimental turbo mode
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
Fri Jul 19 09:57:27 CEST 2013
|
||||
Fix issue where connections were not cleaned up when
|
||||
'MHD_run_from_select' was used.
|
||||
'MHD_run_from_select' was used. Adding experimental
|
||||
TURBO mode.
|
||||
Releasing libmicrohttpd 0.9.28. -CG
|
||||
|
||||
Sun Jul 14 19:57:56 CEST 2013
|
||||
|
||||
@@ -122,10 +122,12 @@ main (int argc, char *const *argv)
|
||||
response = MHD_create_response_from_buffer (strlen (PAGE),
|
||||
(void *) PAGE,
|
||||
MHD_RESPMEM_PERSISTENT);
|
||||
|
||||
d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY
|
||||
#if ! EPOLL_SUPPORT
|
||||
| MHD_USE_EPOLL_LINUX_ONLY
|
||||
(void) MHD_add_response_header (response,
|
||||
MHD_HTTP_HEADER_CONNECTION,
|
||||
"close");
|
||||
d = MHD_start_daemon (MHD_USE_SELECT_INTERNALLY | MHD_SUPPRESS_DATE_NO_CLOCK
|
||||
#if EPOLL_SUPPORT
|
||||
| MHD_USE_EPOLL_LINUX_ONLY | MHD_USE_EPOLL_TURBO
|
||||
#endif
|
||||
,
|
||||
atoi (argv[1]),
|
||||
@@ -134,6 +136,7 @@ main (int argc, char *const *argv)
|
||||
MHD_OPTION_THREAD_POOL_SIZE, (unsigned int) NUMBER_OF_THREADS,
|
||||
MHD_OPTION_URI_LOG_CALLBACK, &uri_logger_cb, NULL,
|
||||
MHD_OPTION_NOTIFY_COMPLETED, &completed_callback, NULL,
|
||||
MHD_OPTION_CONNECTION_LIMIT, (unsigned int) 1000,
|
||||
MHD_OPTION_END);
|
||||
if (d == NULL)
|
||||
return 1;
|
||||
|
||||
@@ -436,7 +436,13 @@ enum MHD_FLAG
|
||||
/**
|
||||
* Use a single socket for IPv4 and IPv6.
|
||||
*/
|
||||
MHD_USE_DUAL_STACK = MHD_USE_IPv6 | 2048
|
||||
MHD_USE_DUAL_STACK = MHD_USE_IPv6 | 2048,
|
||||
|
||||
/**
|
||||
* Enable EPOLL turbo. Only useful with MHD_USE_EPOLL_LINUX_ONLY.
|
||||
* Highly experimental, do not use in production yet.
|
||||
*/
|
||||
MHD_USE_EPOLL_TURBO = 4096
|
||||
|
||||
};
|
||||
|
||||
|
||||
+96
-43
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
This file is part of libmicrohttpd
|
||||
(C) 2007, 2008, 2009, 2010, 2011, 2012 Daniel Pittman and Christian Grothoff
|
||||
(C) 2007-2013 Daniel Pittman and Christian Grothoff
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
@@ -266,8 +266,9 @@ MHD_connection_close (struct MHD_Connection *connection,
|
||||
struct MHD_Daemon *daemon;
|
||||
|
||||
daemon = connection->daemon;
|
||||
SHUTDOWN (connection->socket_fd,
|
||||
(MHD_YES == connection->read_closed) ? SHUT_WR : SHUT_RDWR);
|
||||
if (0 == (connection->daemon->options & MHD_USE_EPOLL_TURBO))
|
||||
SHUTDOWN (connection->socket_fd,
|
||||
(MHD_YES == connection->read_closed) ? SHUT_WR : SHUT_RDWR);
|
||||
connection->state = MHD_CONNECTION_CLOSED;
|
||||
connection->event_loop_info = MHD_EVENT_LOOP_INFO_CLEANUP;
|
||||
if ( (NULL != daemon->notify_completed) &&
|
||||
@@ -1485,7 +1486,7 @@ do_read (struct MHD_Connection *connection)
|
||||
if (bytes_read < 0)
|
||||
{
|
||||
if ((EINTR == errno) || (EAGAIN == errno))
|
||||
return MHD_NO;
|
||||
return MHD_NO;
|
||||
#if HAVE_MESSAGES
|
||||
#if HTTPS_SUPPORT
|
||||
if (0 != (connection->daemon->options & MHD_USE_SSL))
|
||||
@@ -2032,6 +2033,7 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
|
||||
int rend;
|
||||
char *line;
|
||||
|
||||
connection->in_idle = MHD_YES;
|
||||
while (1)
|
||||
{
|
||||
#if DEBUG_STATES
|
||||
@@ -2376,32 +2378,7 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
|
||||
}
|
||||
continue;
|
||||
case MHD_CONNECTION_CLOSED:
|
||||
if (connection->response != NULL)
|
||||
{
|
||||
MHD_destroy_response (connection->response);
|
||||
connection->response = NULL;
|
||||
}
|
||||
if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
|
||||
(0 != pthread_mutex_lock (&daemon->cleanup_connection_mutex)) )
|
||||
MHD_PANIC ("Failed to acquire cleanup mutex\n");
|
||||
if (connection->connection_timeout == daemon->connection_timeout)
|
||||
XDLL_remove (daemon->normal_timeout_head,
|
||||
daemon->normal_timeout_tail,
|
||||
connection);
|
||||
else
|
||||
XDLL_remove (daemon->manual_timeout_head,
|
||||
daemon->manual_timeout_tail,
|
||||
connection);
|
||||
DLL_remove (daemon->connections_head,
|
||||
daemon->connections_tail,
|
||||
connection);
|
||||
DLL_insert (daemon->cleanup_head,
|
||||
daemon->cleanup_tail,
|
||||
connection);
|
||||
if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
|
||||
(0 != pthread_mutex_unlock(&daemon->cleanup_connection_mutex)) )
|
||||
MHD_PANIC ("Failed to release cleanup mutex\n");
|
||||
return MHD_NO;
|
||||
goto cleanup_connection;
|
||||
default:
|
||||
EXTRA_CHECK (0);
|
||||
break;
|
||||
@@ -2413,35 +2390,109 @@ MHD_connection_handle_idle (struct MHD_Connection *connection)
|
||||
(timeout <= (MHD_monotonic_time() - connection->last_activity)) )
|
||||
{
|
||||
MHD_connection_close (connection, MHD_REQUEST_TERMINATED_TIMEOUT_REACHED);
|
||||
connection->in_idle = MHD_NO;
|
||||
return MHD_YES;
|
||||
}
|
||||
MHD_connection_update_event_loop_info (connection);
|
||||
switch (connection->event_loop_info)
|
||||
{
|
||||
case MHD_EVENT_LOOP_INFO_READ:
|
||||
if (0 != (connection->epoll_state & MHD_EPOLL_STATE_READ_READY))
|
||||
EDLL_insert (daemon->eready_head,
|
||||
daemon->eready_tail,
|
||||
connection);
|
||||
if ( (0 != (connection->epoll_state & MHD_EPOLL_STATE_READ_READY)) &&
|
||||
(0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) )
|
||||
{
|
||||
EDLL_insert (daemon->eready_head,
|
||||
daemon->eready_tail,
|
||||
connection);
|
||||
connection->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
|
||||
}
|
||||
break;
|
||||
case MHD_EVENT_LOOP_INFO_WRITE:
|
||||
if (0 != (connection->epoll_state & MHD_EPOLL_STATE_WRITE_READY))
|
||||
EDLL_insert (daemon->eready_head,
|
||||
daemon->eready_tail,
|
||||
connection);
|
||||
if ( (0 != (connection->epoll_state & MHD_EPOLL_STATE_WRITE_READY)) &&
|
||||
(0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL)) )
|
||||
{
|
||||
EDLL_insert (daemon->eready_head,
|
||||
daemon->eready_tail,
|
||||
connection);
|
||||
connection->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
|
||||
}
|
||||
break;
|
||||
case MHD_EVENT_LOOP_INFO_BLOCK:
|
||||
/* we should look at this connection again in the next iteration
|
||||
of the event loop, as we're waiting on the application */
|
||||
EDLL_insert (daemon->eready_head,
|
||||
daemon->eready_tail,
|
||||
connection);
|
||||
if (0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
|
||||
{
|
||||
EDLL_insert (daemon->eready_head,
|
||||
daemon->eready_tail,
|
||||
connection);
|
||||
connection->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL;
|
||||
}
|
||||
break;
|
||||
case MHD_EVENT_LOOP_INFO_CLEANUP:
|
||||
/* This connection is finished, nothing left to do */
|
||||
break;
|
||||
}
|
||||
|
||||
#if EPOLL_SUPPORT
|
||||
if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
|
||||
(0 == (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) &&
|
||||
( (0 == (connection->epoll_state & MHD_EPOLL_STATE_WRITE_READY)) ||
|
||||
( (0 == (connection->epoll_state & MHD_EPOLL_STATE_READ_READY)) &&
|
||||
(MHD_EVENT_LOOP_INFO_READ == connection->event_loop_info) &&
|
||||
(MHD_NO == connection->read_closed) ) ) )
|
||||
{
|
||||
/* add to epoll set */
|
||||
struct epoll_event event;
|
||||
|
||||
event.events = EPOLLIN | EPOLLOUT | EPOLLET;
|
||||
event.data.ptr = connection;
|
||||
if (0 != epoll_ctl (daemon->epoll_fd,
|
||||
EPOLL_CTL_ADD,
|
||||
connection->socket_fd,
|
||||
&event))
|
||||
{
|
||||
#if HAVE_MESSAGES
|
||||
if (0 != (daemon->options & MHD_USE_DEBUG))
|
||||
MHD_DLOG (daemon,
|
||||
"Call to epoll_ctl failed: %s\n",
|
||||
STRERROR (errno));
|
||||
#endif
|
||||
connection->state = MHD_CONNECTION_CLOSED;
|
||||
goto cleanup_connection;
|
||||
}
|
||||
connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET;
|
||||
}
|
||||
#endif
|
||||
connection->in_idle = MHD_NO;
|
||||
return MHD_YES;
|
||||
|
||||
cleanup_connection:
|
||||
if (NULL != connection->response)
|
||||
{
|
||||
MHD_destroy_response (connection->response);
|
||||
connection->response = NULL;
|
||||
}
|
||||
if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
|
||||
(0 != pthread_mutex_lock (&daemon->cleanup_connection_mutex)) )
|
||||
MHD_PANIC ("Failed to acquire cleanup mutex\n");
|
||||
if (connection->connection_timeout == daemon->connection_timeout)
|
||||
XDLL_remove (daemon->normal_timeout_head,
|
||||
daemon->normal_timeout_tail,
|
||||
connection);
|
||||
else
|
||||
XDLL_remove (daemon->manual_timeout_head,
|
||||
daemon->manual_timeout_tail,
|
||||
connection);
|
||||
DLL_remove (daemon->connections_head,
|
||||
daemon->connections_tail,
|
||||
connection);
|
||||
DLL_insert (daemon->cleanup_head,
|
||||
daemon->cleanup_tail,
|
||||
connection);
|
||||
if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
|
||||
(0 != pthread_mutex_unlock(&daemon->cleanup_connection_mutex)) )
|
||||
MHD_PANIC ("Failed to release cleanup mutex\n");
|
||||
connection->in_idle = MHD_NO;
|
||||
return MHD_NO;
|
||||
}
|
||||
|
||||
|
||||
@@ -2589,11 +2640,13 @@ MHD_queue_response (struct MHD_Connection *connection,
|
||||
/* response was queued "early",
|
||||
refuse to read body / footers or further
|
||||
requests! */
|
||||
(void) SHUTDOWN (connection->socket_fd, SHUT_RD);
|
||||
if (0 == (connection->daemon->options & MHD_USE_EPOLL_TURBO))
|
||||
(void) SHUTDOWN (connection->socket_fd, SHUT_RD);
|
||||
connection->read_closed = MHD_YES;
|
||||
connection->state = MHD_CONNECTION_FOOTERS_RECEIVED;
|
||||
}
|
||||
(void) MHD_connection_handle_idle (connection);
|
||||
if (MHD_NO == connection->in_idle)
|
||||
(void) MHD_connection_handle_idle (connection);
|
||||
return MHD_YES;
|
||||
}
|
||||
|
||||
|
||||
+98
-50
@@ -809,7 +809,7 @@ recv_param_adapter (struct MHD_Connection *connection,
|
||||
}
|
||||
ret = RECV (connection->socket_fd, other, i, MSG_NOSIGNAL);
|
||||
#if EPOLL_SUPPORT
|
||||
if (ret < i)
|
||||
if (ret < (ssize_t) i)
|
||||
{
|
||||
/* partial read --- no longer read-ready */
|
||||
connection->epoll_state &= ~MHD_EPOLL_STATE_READ_READY;
|
||||
@@ -884,7 +884,7 @@ send_param_adapter (struct MHD_Connection *connection,
|
||||
#endif
|
||||
ret = SEND (connection->socket_fd, other, i, MSG_NOSIGNAL);
|
||||
#if EPOLL_SUPPORT
|
||||
if (ret < i)
|
||||
if (ret < (ssize_t) i)
|
||||
{
|
||||
/* partial write --- no longer write-ready */
|
||||
connection->epoll_state &= ~MHD_EPOLL_STATE_WRITE_READY;
|
||||
@@ -1121,37 +1121,43 @@ MHD_add_connection (struct MHD_Daemon *daemon,
|
||||
MHD_set_http_callbacks_ (connection);
|
||||
connection->recv_cls = &recv_param_adapter;
|
||||
connection->send_cls = &send_param_adapter;
|
||||
/* non-blocking sockets are required on most systems and for GNUtls;
|
||||
however, they somehow cause serious problems on CYGWIN (#1824) */
|
||||
|
||||
if (0 == (connection->daemon->options & MHD_USE_EPOLL_TURBO))
|
||||
{
|
||||
/* non-blocking sockets are required on most systems and for GNUtls;
|
||||
however, they somehow cause serious problems on CYGWIN (#1824);
|
||||
in turbo mode, we assume that non-blocking was already set
|
||||
by 'accept4' or whoever calls 'MHD_add_connection' */
|
||||
#ifdef CYGWIN
|
||||
if (0 != (daemon->options & MHD_USE_SSL))
|
||||
if (0 != (daemon->options & MHD_USE_SSL))
|
||||
#endif
|
||||
{
|
||||
/* make socket non-blocking */
|
||||
{
|
||||
/* make socket non-blocking */
|
||||
#ifndef MINGW
|
||||
int flags = fcntl (connection->socket_fd, F_GETFL);
|
||||
if ( (-1 == flags) ||
|
||||
(0 != fcntl (connection->socket_fd, F_SETFL, flags | O_NONBLOCK)) )
|
||||
{
|
||||
int flags = fcntl (connection->socket_fd, F_GETFL);
|
||||
if ( (-1 == flags) ||
|
||||
(0 != fcntl (connection->socket_fd, F_SETFL, flags | O_NONBLOCK)) )
|
||||
{
|
||||
#if HAVE_MESSAGES
|
||||
MHD_DLOG (daemon,
|
||||
"Failed to make socket %d non-blocking: %s\n",
|
||||
connection->socket_fd,
|
||||
STRERROR (errno));
|
||||
MHD_DLOG (daemon,
|
||||
"Failed to make socket %d non-blocking: %s\n",
|
||||
connection->socket_fd,
|
||||
STRERROR (errno));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#else
|
||||
unsigned long flags = 1;
|
||||
if (0 != ioctlsocket (connection->socket_fd, FIONBIO, &flags))
|
||||
{
|
||||
unsigned long flags = 1;
|
||||
if (0 != ioctlsocket (connection->socket_fd, FIONBIO, &flags))
|
||||
{
|
||||
#if HAVE_MESSAGES
|
||||
MHD_DLOG (daemon,
|
||||
"Failed to make socket non-blocking: %s\n",
|
||||
STRERROR (errno));
|
||||
MHD_DLOG (daemon,
|
||||
"Failed to make socket non-blocking: %s\n",
|
||||
STRERROR (errno));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if HTTPS_SUPPORT
|
||||
if (0 != (daemon->options & MHD_USE_SSL))
|
||||
@@ -1228,25 +1234,35 @@ MHD_add_connection (struct MHD_Daemon *daemon,
|
||||
#if EPOLL_SUPPORT
|
||||
if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
|
||||
{
|
||||
struct epoll_event event;
|
||||
|
||||
event.events = EPOLLIN | EPOLLOUT | EPOLLET;
|
||||
event.data.ptr = connection;
|
||||
if (0 != epoll_ctl (daemon->epoll_fd,
|
||||
EPOLL_CTL_ADD,
|
||||
client_socket,
|
||||
&event))
|
||||
if (0 == (daemon->options & MHD_USE_EPOLL_TURBO))
|
||||
{
|
||||
struct epoll_event event;
|
||||
|
||||
event.events = EPOLLIN | EPOLLOUT | EPOLLET;
|
||||
event.data.ptr = connection;
|
||||
if (0 != epoll_ctl (daemon->epoll_fd,
|
||||
EPOLL_CTL_ADD,
|
||||
client_socket,
|
||||
&event))
|
||||
{
|
||||
#if HAVE_MESSAGES
|
||||
if (0 != (daemon->options & MHD_USE_DEBUG))
|
||||
MHD_DLOG (daemon,
|
||||
"Call to epoll_ctl failed: %s\n",
|
||||
STRERROR (errno));
|
||||
if (0 != (daemon->options & MHD_USE_DEBUG))
|
||||
MHD_DLOG (daemon,
|
||||
"Call to epoll_ctl failed: %s\n",
|
||||
STRERROR (errno));
|
||||
#endif
|
||||
goto cleanup;
|
||||
goto cleanup;
|
||||
}
|
||||
connection->epoll_state |= MHD_EPOLL_STATE_IN_EPOLL_SET;
|
||||
}
|
||||
else
|
||||
{
|
||||
connection->epoll_state |= MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY
|
||||
| MHD_EPOLL_STATE_IN_EREADY_EDLL;
|
||||
EDLL_insert (daemon->eready_head,
|
||||
daemon->eready_tail,
|
||||
connection);
|
||||
}
|
||||
daemon->listen_socket_in_epoll = MHD_YES;
|
||||
|
||||
}
|
||||
#endif
|
||||
daemon->max_connections--;
|
||||
@@ -1300,13 +1316,19 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
|
||||
socklen_t addrlen;
|
||||
int s;
|
||||
int fd;
|
||||
int nonblock;
|
||||
|
||||
addrlen = sizeof (addrstorage);
|
||||
memset (addr, 0, sizeof (addrstorage));
|
||||
if (-1 == (fd = daemon->socket_fd))
|
||||
return MHD_NO;
|
||||
nonblock = SOCK_NONBLOCK;
|
||||
#ifdef CYGWIN
|
||||
if (0 == (daemon->options & MHD_USE_SSL))
|
||||
nonblock = 0;
|
||||
#endif
|
||||
#if HAVE_ACCEPT4
|
||||
s = accept4 (fd, addr, &addrlen, SOCK_CLOEXEC);
|
||||
s = accept4 (fd, addr, &addrlen, SOCK_CLOEXEC | nonblock);
|
||||
#else
|
||||
s = ACCEPT (fd, addr, &addrlen);
|
||||
#endif
|
||||
@@ -1329,9 +1351,19 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
|
||||
}
|
||||
#if !HAVE_ACCEPT4
|
||||
{
|
||||
/* make socket non-inheritable */
|
||||
/* make socket non-inheritable and non-blocking */
|
||||
#ifdef WINDOWS
|
||||
DWORD dwFlags;
|
||||
unsigned long flags = 1;
|
||||
|
||||
if (0 != ioctlsocket (s, FIONBIO, &flags))
|
||||
{
|
||||
#if HAVE_MESSAGES
|
||||
MHD_DLOG (daemon,
|
||||
"Failed to make socket non-blocking: %s\n",
|
||||
STRERROR (errno));
|
||||
#endif
|
||||
}
|
||||
if (!GetHandleInformation ((HANDLE) s, &dwFlags) ||
|
||||
((dwFlags != dwFlags & ~HANDLE_FLAG_INHERIT) &&
|
||||
!SetHandleInformation ((HANDLE) s, HANDLE_FLAG_INHERIT, 0)))
|
||||
@@ -1342,14 +1374,19 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
|
||||
"Failed to make socket non-inheritable: %s\n",
|
||||
STRERROR (errno));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#else
|
||||
int flags;
|
||||
|
||||
nonblock = O_NONBLOCK;
|
||||
#ifdef CYGWIN
|
||||
if (0 == (daemon->options & MHD_USE_SSL))
|
||||
nonblock = 0;
|
||||
#endif
|
||||
flags = fcntl (s, F_GETFD);
|
||||
if ( ( (-1 == flags) ||
|
||||
( (flags != (flags | FD_CLOEXEC)) &&
|
||||
(0 != fcntl (s, F_SETFD, flags | FD_CLOEXEC)) ) ) )
|
||||
(0 != fcntl (s, F_SETFD, flags | nonblock | FD_CLOEXEC)) ) ) )
|
||||
{
|
||||
#if HAVE_MESSAGES
|
||||
MHD_DLOG (daemon,
|
||||
@@ -1358,7 +1395,10 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
/* make socket non-blocking */
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
#if HAVE_MESSAGES
|
||||
#if DEBUG_CONNECT
|
||||
@@ -1406,10 +1446,13 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon)
|
||||
if (pos->tls_session != NULL)
|
||||
gnutls_deinit (pos->tls_session);
|
||||
#endif
|
||||
MHD_ip_limit_del (daemon, (struct sockaddr*)pos->addr, pos->addr_len);
|
||||
MHD_ip_limit_del (daemon,
|
||||
(struct sockaddr *) pos->addr,
|
||||
pos->addr_len);
|
||||
#if EPOLL_SUPPORT
|
||||
if ( (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) &&
|
||||
(-1 != daemon->epoll_fd) )
|
||||
(-1 != daemon->epoll_fd) &&
|
||||
(0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET)) )
|
||||
{
|
||||
/* epoll documentation suggests that closing a FD
|
||||
automatically removes it from the epoll set; however,
|
||||
@@ -1422,6 +1465,7 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon)
|
||||
pos->socket_fd,
|
||||
NULL))
|
||||
MHD_PANIC ("Failed to remove FD from epoll set\n");
|
||||
pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
|
||||
}
|
||||
#endif
|
||||
if (NULL != pos->response)
|
||||
@@ -1949,10 +1993,10 @@ MHD_poll (struct MHD_Daemon *daemon,
|
||||
|
||||
/**
|
||||
* Do 'epoll'-based processing (this function is allowed to
|
||||
* block).
|
||||
* block if 'may_block' is set to MHD_YES).
|
||||
*
|
||||
* @param daemon daemon to run poll loop for
|
||||
* @param may_block YES if blocking, NO if non-blocking
|
||||
* @param may_block MHD_YES if blocking, MHD_NO if non-blocking
|
||||
* @return MHD_NO on serious errors, MHD_YES on success
|
||||
*/
|
||||
static int
|
||||
@@ -1966,7 +2010,8 @@ MHD_epoll (struct MHD_Daemon *daemon,
|
||||
int timeout_ms;
|
||||
MHD_UNSIGNED_LONG_LONG timeout_ll;
|
||||
int num_events;
|
||||
unsigned int i;
|
||||
unsigned int i;
|
||||
unsigned int series_length;
|
||||
|
||||
if (-1 == daemon->epoll_fd)
|
||||
return MHD_NO; /* we're down! */
|
||||
@@ -2082,8 +2127,11 @@ MHD_epoll (struct MHD_Daemon *daemon,
|
||||
{
|
||||
/* run 'accept' until it fails or we are not allowed to take
|
||||
on more connections */
|
||||
series_length = 0;
|
||||
while ( (MHD_YES == MHD_accept_connection (daemon)) &&
|
||||
(0 != daemon->max_connections) ) ;
|
||||
(0 != daemon->max_connections) &&
|
||||
(series_length < 128) )
|
||||
series_length++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2094,7 +2142,7 @@ MHD_epoll (struct MHD_Daemon *daemon,
|
||||
EDLL_remove (daemon->eready_head,
|
||||
daemon->eready_tail,
|
||||
pos);
|
||||
pos->epoll_state -= MHD_EPOLL_STATE_IN_EREADY_EDLL;
|
||||
pos->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
|
||||
if (MHD_EVENT_LOOP_INFO_READ == pos->event_loop_info)
|
||||
pos->read_handler (pos);
|
||||
if (MHD_EVENT_LOOP_INFO_WRITE == pos->event_loop_info)
|
||||
|
||||
@@ -111,7 +111,12 @@ enum MHD_EpollState
|
||||
/**
|
||||
* Is this connection currently in the 'eready' EDLL?
|
||||
*/
|
||||
MHD_EPOLL_STATE_IN_EREADY_EDLL = 4
|
||||
MHD_EPOLL_STATE_IN_EREADY_EDLL = 4,
|
||||
|
||||
/**
|
||||
* Is this connection currently in the 'epoll' set?
|
||||
*/
|
||||
MHD_EPOLL_STATE_IN_EPOLL_SET = 8
|
||||
|
||||
};
|
||||
|
||||
@@ -719,6 +724,11 @@ struct MHD_Connection
|
||||
*/
|
||||
int thread_joined;
|
||||
|
||||
/**
|
||||
* Are we currently inside the "idle" handler (to avoid recursively invoking it).
|
||||
*/
|
||||
int in_idle;
|
||||
|
||||
#if EPOLL_SUPPORT
|
||||
/**
|
||||
* What is the state of this socket in relation to epoll?
|
||||
|
||||
Reference in New Issue
Block a user