aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Grin (Karlson2k) <k2k@narod.ru>2016-04-10 19:12:37 +0000
committerEvgeny Grin (Karlson2k) <k2k@narod.ru>2016-04-10 19:12:37 +0000
commitff21b86d1ae552add51867028d99e13dd0121810 (patch)
tree20599bc6bd468cdf88cd660411eb4456f135f9f2
parentcf295a42e24599a1e4b6e33afa58fa724d40eb76 (diff)
downloadlibmicrohttpd-ff21b86d1ae552add51867028d99e13dd0121810.tar.gz
libmicrohttpd-ff21b86d1ae552add51867028d99e13dd0121810.zip
Use less locking with MHD_USE_THREAD_PER_CONNECTION.
Do not maintain global list out timeouts as each thread use individual timeout. As result - global mutex is not acquired after each single send()/recv().
-rw-r--r--src/microhttpd/connection.c62
-rw-r--r--src/microhttpd/daemon.c79
-rw-r--r--src/microhttpd/internal.h5
3 files changed, 81 insertions, 65 deletions
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index 3aa0d16c..e1bc1f7e 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -2132,22 +2132,19 @@ update_last_activity (struct MHD_Connection *connection)
2132 struct MHD_Daemon *daemon = connection->daemon; 2132 struct MHD_Daemon *daemon = connection->daemon;
2133 2133
2134 connection->last_activity = MHD_monotonic_sec_counter(); 2134 connection->last_activity = MHD_monotonic_sec_counter();
2135 if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
2136 return; /* each connection has personal timeout */
2137
2135 if (connection->connection_timeout != daemon->connection_timeout) 2138 if (connection->connection_timeout != daemon->connection_timeout)
2136 return; /* custom timeout, no need to move it in "normal" DLL */ 2139 return; /* custom timeout, no need to move it in "normal" DLL */
2137 2140
2138 /* move connection to head of timeout list (by remove + add operation) */ 2141 /* move connection to head of timeout list (by remove + add operation) */
2139 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
2140 (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) )
2141 MHD_PANIC ("Failed to acquire cleanup mutex\n");
2142 XDLL_remove (daemon->normal_timeout_head, 2142 XDLL_remove (daemon->normal_timeout_head,
2143 daemon->normal_timeout_tail, 2143 daemon->normal_timeout_tail,
2144 connection); 2144 connection);
2145 XDLL_insert (daemon->normal_timeout_head, 2145 XDLL_insert (daemon->normal_timeout_head,
2146 daemon->normal_timeout_tail, 2146 daemon->normal_timeout_tail,
2147 connection); 2147 connection);
2148 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
2149 (MHD_YES != MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) )
2150 MHD_PANIC ("Failed to release cleanup mutex\n");
2151} 2148}
2152 2149
2153 2150
@@ -2397,17 +2394,22 @@ cleanup_connection (struct MHD_Connection *connection)
2397 MHD_destroy_response (connection->response); 2394 MHD_destroy_response (connection->response);
2398 connection->response = NULL; 2395 connection->response = NULL;
2399 } 2396 }
2400 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && 2397 if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
2401 (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) ) 2398 {
2402 MHD_PANIC ("Failed to acquire cleanup mutex\n"); 2399 if (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex))
2403 if (connection->connection_timeout == daemon->connection_timeout) 2400 MHD_PANIC ("Failed to acquire cleanup mutex\n");
2404 XDLL_remove (daemon->normal_timeout_head, 2401 }
2405 daemon->normal_timeout_tail,
2406 connection);
2407 else 2402 else
2408 XDLL_remove (daemon->manual_timeout_head, 2403 {
2409 daemon->manual_timeout_tail, 2404 if (connection->connection_timeout == daemon->connection_timeout)
2410 connection); 2405 XDLL_remove (daemon->normal_timeout_head,
2406 daemon->normal_timeout_tail,
2407 connection);
2408 else
2409 XDLL_remove (daemon->manual_timeout_head,
2410 daemon->manual_timeout_tail,
2411 connection);
2412 }
2411 if (MHD_YES == connection->suspended) 2413 if (MHD_YES == connection->suspended)
2412 DLL_remove (daemon->suspended_connections_head, 2414 DLL_remove (daemon->suspended_connections_head,
2413 daemon->suspended_connections_tail, 2415 daemon->suspended_connections_tail,
@@ -3040,37 +3042,33 @@ MHD_set_connection_option (struct MHD_Connection *connection,
3040 switch (option) 3042 switch (option)
3041 { 3043 {
3042 case MHD_CONNECTION_OPTION_TIMEOUT: 3044 case MHD_CONNECTION_OPTION_TIMEOUT:
3043 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && 3045 if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
3044 (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) ) 3046 (MHD_YES != connection->suspended) )
3045 MHD_PANIC ("Failed to acquire cleanup mutex\n");
3046 if (MHD_YES != connection->suspended)
3047 { 3047 {
3048 if (connection->connection_timeout == daemon->connection_timeout) 3048 if (connection->connection_timeout == daemon->connection_timeout)
3049 XDLL_remove (daemon->normal_timeout_head, 3049 XDLL_remove (daemon->normal_timeout_head,
3050 daemon->normal_timeout_tail, 3050 daemon->normal_timeout_tail,
3051 connection); 3051 connection);
3052 else 3052 else
3053 XDLL_remove (daemon->manual_timeout_head, 3053 XDLL_remove (daemon->manual_timeout_head,
3054 daemon->manual_timeout_tail, 3054 daemon->manual_timeout_tail,
3055 connection); 3055 connection);
3056 } 3056 }
3057 va_start (ap, option); 3057 va_start (ap, option);
3058 connection->connection_timeout = va_arg (ap, unsigned int); 3058 connection->connection_timeout = va_arg (ap, unsigned int);
3059 va_end (ap); 3059 va_end (ap);
3060 if (MHD_YES != connection->suspended) 3060 if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
3061 (MHD_YES != connection->suspended) )
3061 { 3062 {
3062 if (connection->connection_timeout == daemon->connection_timeout) 3063 if (connection->connection_timeout == daemon->connection_timeout)
3063 XDLL_insert (daemon->normal_timeout_head, 3064 XDLL_insert (daemon->normal_timeout_head,
3064 daemon->normal_timeout_tail, 3065 daemon->normal_timeout_tail,
3065 connection); 3066 connection);
3066 else 3067 else
3067 XDLL_insert (daemon->manual_timeout_head, 3068 XDLL_insert (daemon->manual_timeout_head,
3068 daemon->manual_timeout_tail, 3069 daemon->manual_timeout_tail,
3069 connection); 3070 connection);
3070 } 3071 }
3071 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
3072 (MHD_YES != MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) )
3073 MHD_PANIC ("Failed to release cleanup mutex\n");
3074 return MHD_YES; 3072 return MHD_YES;
3075 default: 3073 default:
3076 return MHD_NO; 3074 return MHD_NO;
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index ea958204..2c5d220d 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -842,7 +842,6 @@ MHD_handle_connection (void *data)
842 MHD_socket maxsock; 842 MHD_socket maxsock;
843 struct timeval tv; 843 struct timeval tv;
844 struct timeval *tvp; 844 struct timeval *tvp;
845 unsigned int timeout;
846 time_t now; 845 time_t now;
847#if WINDOWS 846#if WINDOWS
848 MHD_pipe spipe = con->daemon->wpipe[0]; 847 MHD_pipe spipe = con->daemon->wpipe[0];
@@ -857,10 +856,10 @@ MHD_handle_connection (void *data)
857 struct pollfd p[1 + EXTRA_SLOTS]; 856 struct pollfd p[1 + EXTRA_SLOTS];
858#endif 857#endif
859 858
860 timeout = con->daemon->connection_timeout;
861 while ( (MHD_YES != con->daemon->shutdown) && 859 while ( (MHD_YES != con->daemon->shutdown) &&
862 (MHD_CONNECTION_CLOSED != con->state) ) 860 (MHD_CONNECTION_CLOSED != con->state) )
863 { 861 {
862 unsigned const int timeout = con->daemon->connection_timeout;
864 tvp = NULL; 863 tvp = NULL;
865#if HTTPS_SUPPORT 864#if HTTPS_SUPPORT
866 if (MHD_YES == con->tls_read_ready) 865 if (MHD_YES == con->tls_read_ready)
@@ -1563,12 +1562,15 @@ internal_add_connection (struct MHD_Daemon *daemon,
1563 } 1562 }
1564#endif 1563#endif
1565 1564
1566 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && 1565 if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
1567 (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) ) 1566 {
1568 MHD_PANIC ("Failed to acquire cleanup mutex\n"); 1567 if (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex))
1569 XDLL_insert (daemon->normal_timeout_head, 1568 MHD_PANIC ("Failed to acquire cleanup mutex\n");
1570 daemon->normal_timeout_tail, 1569 }
1571 connection); 1570 else
1571 XDLL_insert (daemon->normal_timeout_head,
1572 daemon->normal_timeout_tail,
1573 connection);
1572 DLL_insert (daemon->connections_head, 1574 DLL_insert (daemon->connections_head,
1573 daemon->connections_tail, 1575 daemon->connections_tail,
1574 connection); 1576 connection);
@@ -1655,15 +1657,18 @@ internal_add_connection (struct MHD_Daemon *daemon,
1655 if (0 != MHD_socket_close_ (client_socket)) 1657 if (0 != MHD_socket_close_ (client_socket))
1656 MHD_PANIC ("close failed\n"); 1658 MHD_PANIC ("close failed\n");
1657 MHD_ip_limit_del (daemon, addr, addrlen); 1659 MHD_ip_limit_del (daemon, addr, addrlen);
1658 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && 1660 if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
1659 (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) ) 1661 {
1660 MHD_PANIC ("Failed to acquire cleanup mutex\n"); 1662 if (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex))
1663 MHD_PANIC ("Failed to acquire cleanup mutex\n");
1664 }
1665 else
1666 XDLL_remove (daemon->normal_timeout_head,
1667 daemon->normal_timeout_tail,
1668 connection);
1661 DLL_remove (daemon->connections_head, 1669 DLL_remove (daemon->connections_head,
1662 daemon->connections_tail, 1670 daemon->connections_tail,
1663 connection); 1671 connection);
1664 XDLL_remove (daemon->normal_timeout_head,
1665 daemon->normal_timeout_tail,
1666 connection);
1667 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && 1672 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
1668 (MHD_YES != MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) ) 1673 (MHD_YES != MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) )
1669 MHD_PANIC ("Failed to release cleanup mutex\n"); 1674 MHD_PANIC ("Failed to release cleanup mutex\n");
@@ -1712,23 +1717,28 @@ MHD_suspend_connection (struct MHD_Connection *connection)
1712 daemon = connection->daemon; 1717 daemon = connection->daemon;
1713 if (MHD_USE_SUSPEND_RESUME != (daemon->options & MHD_USE_SUSPEND_RESUME)) 1718 if (MHD_USE_SUSPEND_RESUME != (daemon->options & MHD_USE_SUSPEND_RESUME))
1714 MHD_PANIC ("Cannot suspend connections without enabling MHD_USE_SUSPEND_RESUME!\n"); 1719 MHD_PANIC ("Cannot suspend connections without enabling MHD_USE_SUSPEND_RESUME!\n");
1715 if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) && 1720 if (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
1716 (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) ) 1721 {
1717 MHD_PANIC ("Failed to acquire cleanup mutex\n"); 1722 if (MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex))
1723 MHD_PANIC ("Failed to acquire cleanup mutex\n");
1724 }
1725 else
1726 {
1727 if (connection->connection_timeout == daemon->connection_timeout)
1728 XDLL_remove (daemon->normal_timeout_head,
1729 daemon->normal_timeout_tail,
1730 connection);
1731 else
1732 XDLL_remove (daemon->manual_timeout_head,
1733 daemon->manual_timeout_tail,
1734 connection);
1735 }
1718 DLL_remove (daemon->connections_head, 1736 DLL_remove (daemon->connections_head,
1719 daemon->connections_tail, 1737 daemon->connections_tail,
1720 connection); 1738 connection);
1721 DLL_insert (daemon->suspended_connections_head, 1739 DLL_insert (daemon->suspended_connections_head,
1722 daemon->suspended_connections_tail, 1740 daemon->suspended_connections_tail,
1723 connection); 1741 connection);
1724 if (connection->connection_timeout == daemon->connection_timeout)
1725 XDLL_remove (daemon->normal_timeout_head,
1726 daemon->normal_timeout_tail,
1727 connection);
1728 else
1729 XDLL_remove (daemon->manual_timeout_head,
1730 daemon->manual_timeout_tail,
1731 connection);
1732#if EPOLL_SUPPORT 1742#if EPOLL_SUPPORT
1733 if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) 1743 if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
1734 { 1744 {
@@ -1826,14 +1836,17 @@ resume_suspended_connections (struct MHD_Daemon *daemon)
1826 DLL_insert (daemon->connections_head, 1836 DLL_insert (daemon->connections_head,
1827 daemon->connections_tail, 1837 daemon->connections_tail,
1828 pos); 1838 pos);
1829 if (pos->connection_timeout == daemon->connection_timeout) 1839 if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
1830 XDLL_insert (daemon->normal_timeout_head, 1840 {
1831 daemon->normal_timeout_tail, 1841 if (pos->connection_timeout == daemon->connection_timeout)
1832 pos); 1842 XDLL_insert (daemon->normal_timeout_head,
1833 else 1843 daemon->normal_timeout_tail,
1834 XDLL_insert (daemon->manual_timeout_head, 1844 pos);
1835 daemon->manual_timeout_tail, 1845 else
1836 pos); 1846 XDLL_insert (daemon->manual_timeout_head,
1847 daemon->manual_timeout_tail,
1848 pos);
1849 }
1837#if EPOLL_SUPPORT 1850#if EPOLL_SUPPORT
1838 if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY)) 1851 if (0 != (daemon->options & MHD_USE_EPOLL_LINUX_ONLY))
1839 { 1852 {
diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h
index 3856a623..58317040 100644
--- a/src/microhttpd/internal.h
+++ b/src/microhttpd/internal.h
@@ -976,12 +976,15 @@ struct MHD_Daemon
976 * All connections by default start in this list; if a custom 976 * All connections by default start in this list; if a custom
977 * timeout that does not match @e connection_timeout is set, they 977 * timeout that does not match @e connection_timeout is set, they
978 * are moved to the @e manual_timeout_head-XDLL. 978 * are moved to the @e manual_timeout_head-XDLL.
979 * Not used in MHD_USE_THREAD_PER_CONNECTION mode as each thread
980 * needs only one connection-specific timeout.
979 */ 981 */
980 struct MHD_Connection *normal_timeout_head; 982 struct MHD_Connection *normal_timeout_head;
981 983
982 /** 984 /**
983 * Tail of the XDLL of ALL connections with a default timeout, 985 * Tail of the XDLL of ALL connections with a default timeout,
984 * sorted by timeout (earliest timeout at the tail). 986 * sorted by timeout (earliest timeout at the tail).
987 * Not used in MHD_USE_THREAD_PER_CONNECTION mode.
985 */ 988 */
986 struct MHD_Connection *normal_timeout_tail; 989 struct MHD_Connection *normal_timeout_tail;
987 990
@@ -989,12 +992,14 @@ struct MHD_Daemon
989 * Head of the XDLL of ALL connections with a non-default/custom 992 * Head of the XDLL of ALL connections with a non-default/custom
990 * timeout, unsorted. MHD will do a O(n) scan over this list to 993 * timeout, unsorted. MHD will do a O(n) scan over this list to
991 * determine the current timeout. 994 * determine the current timeout.
995 * Not used in MHD_USE_THREAD_PER_CONNECTION mode.
992 */ 996 */
993 struct MHD_Connection *manual_timeout_head; 997 struct MHD_Connection *manual_timeout_head;
994 998
995 /** 999 /**
996 * Tail of the XDLL of ALL connections with a non-default/custom 1000 * Tail of the XDLL of ALL connections with a non-default/custom
997 * timeout, unsorted. 1001 * timeout, unsorted.
1002 * Not used in MHD_USE_THREAD_PER_CONNECTION mode.
998 */ 1003 */
999 struct MHD_Connection *manual_timeout_tail; 1004 struct MHD_Connection *manual_timeout_tail;
1000 1005