diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-06-25 13:13:46 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-06-25 13:13:46 +0000 |
commit | 79f2eea2629367ca402671cf7d033e52de0f9e8a (patch) | |
tree | 7eca7a10fe366c77681ee7f897b4f6483d3f736b /doc | |
parent | 2c646f956fe2fbd926a1413ed4e3db5abf4dc51e (diff) | |
download | libmicrohttpd-79f2eea2629367ca402671cf7d033e52de0f9e8a.tar.gz libmicrohttpd-79f2eea2629367ca402671cf7d033e52de0f9e8a.zip |
-documentation updates for epoll
Diffstat (limited to 'doc')
-rw-r--r-- | doc/libmicrohttpd.texi | 136 | ||||
-rw-r--r-- | doc/performance_data.png | bin | 0 -> 9169 bytes |
2 files changed, 130 insertions, 6 deletions
diff --git a/doc/libmicrohttpd.texi b/doc/libmicrohttpd.texi index 882431a4..377302ef 100644 --- a/doc/libmicrohttpd.texi +++ b/doc/libmicrohttpd.texi | |||
@@ -142,6 +142,72 @@ Examples based on reports we've received from developers include: | |||
142 | @c If you have other interesting examples, please let us know | 142 | @c If you have other interesting examples, please let us know |
143 | @end itemize | 143 | @end itemize |
144 | 144 | ||
145 | @section Thread modes and event loops | ||
146 | @cindex poll | ||
147 | @cindex epoll | ||
148 | @cindex select | ||
149 | |||
150 | MHD supports four basic thread modes and up to three event loop | ||
151 | styes. | ||
152 | |||
153 | The four basic thread modes are external (MHD creates no threads, | ||
154 | event loop is fully managed by the application), internal (MHD creates | ||
155 | one thread for all connections), thread pool (MHD creates a thread | ||
156 | pool which is used to process all connections) and | ||
157 | thread-per-connection (MHD creates one listen thread and then one | ||
158 | thread per accepted connection). | ||
159 | |||
160 | These thread modes are then combined with the event loop styles. | ||
161 | MHD support select, poll and epoll. epoll is only available on | ||
162 | Linux, poll may not be available on some platforms. Note that | ||
163 | it is possible to combine MHD using epoll with an external | ||
164 | select-based event loop. | ||
165 | |||
166 | The default (if no other option is passed) is ``external select''. | ||
167 | The highest performance can typically be obtained with a thread pool | ||
168 | using @code{epoll}. Apache Benchmark (ab) was used to compare the | ||
169 | performance of @code{select} and @code{epoll} when using a thread pool | ||
170 | and a large number of connections. @ref{fig:performance} shows the | ||
171 | resulting plot from the @code{benchmark.c} example, which measures the | ||
172 | latency between an incoming request and the completion of the | ||
173 | transmission of the response. In this setting, the @code{epoll} | ||
174 | thread pool with four threads was able to handle more than 45,000 | ||
175 | connections per second on loopback (with Apache Benchmark running | ||
176 | three processes on the same machine). | ||
177 | @cindex performance | ||
178 | |||
179 | |||
180 | @float Figure,fig:performance | ||
181 | @image{performance_data,400pt,300pt,Data,.png} | ||
182 | @caption{Performance measurements for select vs. epoll (with thread-pool).} | ||
183 | @end float | ||
184 | |||
185 | |||
186 | Not all combinations of thread modes and event loop styles are | ||
187 | supported. This is partially to keep the API simple, and partially | ||
188 | because some combinations simply make no sense as others are strictly | ||
189 | superior. Note that the choice of style depends fist of all on the | ||
190 | application logic, and then on the performance requirements. | ||
191 | Applications that perform a blocking operation while handling a | ||
192 | request within the callbacks from MHD must use a thread per | ||
193 | connection. This is typically rather costly. Applications that do | ||
194 | not support threads or that must run on embedded devices without | ||
195 | thread-support must use the external mode. Using @code{epoll} is only | ||
196 | supported on Linux, thus portable applications must at least have a | ||
197 | fallback option available. @ref{tbl:supported} lists the sane | ||
198 | combinations. | ||
199 | |||
200 | @float Table,tbl:supported | ||
201 | @multitable {@b{thread-per-connection}} {@b{select}} {@b{poll}} {@b{epoll}} | ||
202 | @item @tab @b{select} @tab @b{poll} @tab @b{epoll} | ||
203 | @item @b{external} @tab yes @tab no @tab yes | ||
204 | @item @b{internal} @tab yes @tab yes @tab yes | ||
205 | @item @b{thread pool} @tab yes @tab yes @tab yes | ||
206 | @item @b{thread-per-connection} @tab yes @tab yes @tab no | ||
207 | @end multitable | ||
208 | @caption{Supported combinations of event styles and thread modes.} | ||
209 | @end float | ||
210 | |||
145 | 211 | ||
146 | @section Compiling GNU libmicrohttpd | 212 | @section Compiling GNU libmicrohttpd |
147 | @cindex compilation | 213 | @cindex compilation |
@@ -188,6 +254,9 @@ do not include the post processor API (results in binary incompatibility) | |||
188 | @item ``--disable-dauth'' | 254 | @item ``--disable-dauth'' |
189 | do not include the authentication APIs (results in binary incompatibility) | 255 | do not include the authentication APIs (results in binary incompatibility) |
190 | 256 | ||
257 | @item ``--disable-epoll | ||
258 | do not include epoll support, even on Linux (minimally smaller binary size, good for testing portability to non-Linux systems) | ||
259 | |||
191 | @item ``--enable-coverage'' | 260 | @item ``--enable-coverage'' |
192 | set flags for analysis of code-coverage with gcc/gcov (results in slow, large binaries) | 261 | set flags for analysis of code-coverage with gcc/gcov (results in slow, large binaries) |
193 | 262 | ||
@@ -341,6 +410,16 @@ Run using the IPv6 protocol (otherwise, MHD will just support IPv4). | |||
341 | If you specify @code{MHD_USE_IPV6} and the local platform does not | 410 | If you specify @code{MHD_USE_IPV6} and the local platform does not |
342 | support it, @code{MHD_start_daemon} will return NULL. | 411 | support it, @code{MHD_start_daemon} will return NULL. |
343 | 412 | ||
413 | If you want MHD to support IPv4 and IPv6 using a single socket, pass | ||
414 | MHD_USE_DUAL_STACK, otherwise, if you only pass this option, MHD will | ||
415 | try to bind to IPv6-only (resulting in no IPv4 support). | ||
416 | |||
417 | @item MHD_USE_DUAL_STACK | ||
418 | @cindex IPv6 | ||
419 | Use a single socket for IPv4 and IPv6. Note that this will mean | ||
420 | that IPv4 addresses are returned by MHD in the IPv6-mapped format | ||
421 | (the 'struct sockaddr_in6' format will be used for IPv4 and IPv6). | ||
422 | |||
344 | @item MHD_USE_PEDANTIC_CHECKS | 423 | @item MHD_USE_PEDANTIC_CHECKS |
345 | Be pedantic about the protocol (as opposed to as tolerant as possible). | 424 | Be pedantic about the protocol (as opposed to as tolerant as possible). |
346 | Specifically, at the moment, this flag causes MHD to reject HTTP | 425 | Specifically, at the moment, this flag causes MHD to reject HTTP |
@@ -355,10 +434,26 @@ production. | |||
355 | @cindex poll | 434 | @cindex poll |
356 | @cindex select | 435 | @cindex select |
357 | Use poll instead of select. This allows sockets with descriptors | 436 | Use poll instead of select. This allows sockets with descriptors |
358 | @code{>= FD_SETSIZE}. This option only works in conjunction with | 437 | @code{>= FD_SETSIZE}. This option currently only works in conjunction |
359 | @code{MHD_USE_THREAD_PER_CONNECTION} (at this point). If you | 438 | with @code{MHD_USE_THREAD_PER_CONNECTION} or |
360 | specify @code{MHD_USE_POLL} and the local platform does not support | 439 | @code{MHD_USE_INTERNAL_SELECT} (at this point). If you specify |
361 | it, @code{MHD_start_daemon} will return NULL. | 440 | @code{MHD_USE_POLL} and the local platform does not support it, |
441 | @code{MHD_start_daemon} will return NULL. | ||
442 | |||
443 | @item MHD_USE_EPOLL_LINUX_ONLY | ||
444 | @cindex FD_SETSIZE | ||
445 | @cindex epoll | ||
446 | @cindex select | ||
447 | Use epoll instead of poll or select. This allows sockets with | ||
448 | descriptors @code{>= FD_SETSIZE}. This option is only available on | ||
449 | Linux systems and only works in conjunction with | ||
450 | @code{MHD_USE_THREAD_PER_CONNECTION} (at this point). If you specify | ||
451 | @code{MHD_USE_EPOLL_LINUX_ONLY} and the local platform does not | ||
452 | support it, @code{MHD_start_daemon} will return NULL. Using epoll | ||
453 | instead of select or poll can in some situations result in significantly | ||
454 | higher performance as the system call has fundamentally lower complexity | ||
455 | (O(1) for epoll vs. O(n) for select/poll where n is the number of | ||
456 | open connections). | ||
362 | 457 | ||
363 | @item MHD_SUPPRESS_DATE_NO_CLOCK | 458 | @item MHD_SUPPRESS_DATE_NO_CLOCK |
364 | @cindex date | 459 | @cindex date |
@@ -380,6 +475,18 @@ connect HTTP clients to the HTTP server. This option is incompatible | |||
380 | with using a thread pool; if it is used, | 475 | with using a thread pool; if it is used, |
381 | @code{MHD_OPTION_THREAD_POOL_SIZE} is ignored. | 476 | @code{MHD_OPTION_THREAD_POOL_SIZE} is ignored. |
382 | 477 | ||
478 | @item MHD_USE_PIPE_FOR_SHUTDOWN | ||
479 | @cindex quiesce | ||
480 | Force MHD to use a signal pipe to notify the event loop (of threads) | ||
481 | of our shutdown. This is required if an appliction uses | ||
482 | @code{MHD_USE_INTERNAL_SELECT} or @code{MHD_USE_THREAD_PER_CONNECTION} | ||
483 | and then performs @code{MHD_quiesce_daemon} (which eliminates our | ||
484 | ability to signal termination via the listen socket). In these modes, | ||
485 | @code{MHD_quiesce_daemon} will fail if this option was not set. Also, | ||
486 | use of this option is automatic (as in, you do not even have to | ||
487 | specify it), if @code{MHD_USE_NO_LISTEN_SOCKET} is specified. In | ||
488 | "external" select mode, this option is always simply ignored. | ||
489 | |||
383 | @end table | 490 | @end table |
384 | @end deftp | 491 | @end deftp |
385 | 492 | ||
@@ -1087,6 +1194,7 @@ Return @code{NULL} on error, handle to daemon on success. | |||
1087 | 1194 | ||
1088 | 1195 | ||
1089 | @deftypefun int MHD_quiesce_daemon (struct MHD_Daemon *daemon) | 1196 | @deftypefun int MHD_quiesce_daemon (struct MHD_Daemon *daemon) |
1197 | @cindex quiesce | ||
1090 | Stop accepting connections from the listening socket. Allows clients | 1198 | Stop accepting connections from the listening socket. Allows clients |
1091 | to continue processing, but stops accepting new connections. Note | 1199 | to continue processing, but stops accepting new connections. Note |
1092 | that the caller is responsible for closing the returned socket; | 1200 | that the caller is responsible for closing the returned socket; |
@@ -1102,6 +1210,7 @@ processed until they are finished. | |||
1102 | 1210 | ||
1103 | Return @code{-1} on error (daemon not listening), the handle to the | 1211 | Return @code{-1} on error (daemon not listening), the handle to the |
1104 | listen socket otherwise. | 1212 | listen socket otherwise. |
1213 | |||
1105 | @end deftypefun | 1214 | @end deftypefun |
1106 | 1215 | ||
1107 | 1216 | ||
@@ -1130,6 +1239,7 @@ Return @code{MHD_YES} on success, @code{MHD_NO} if this daemon was not | |||
1130 | started with the right options for this call. | 1239 | started with the right options for this call. |
1131 | @end deftypefun | 1240 | @end deftypefun |
1132 | 1241 | ||
1242 | |||
1133 | @deftypefun int MHD_run_from_select (struct MHD_Daemon *daemon, const fd_set *read_fd_set, const fd_set *write_fd_set, const fd_set *except_fd_set) | 1243 | @deftypefun int MHD_run_from_select (struct MHD_Daemon *daemon, const fd_set *read_fd_set, const fd_set *write_fd_set, const fd_set *except_fd_set) |
1134 | Run webserver operations given sets of ready socket handles. | 1244 | Run webserver operations given sets of ready socket handles. |
1135 | @cindex select | 1245 | @cindex select |
@@ -1162,6 +1272,7 @@ errors. | |||
1162 | @end deftypefun | 1272 | @end deftypefun |
1163 | 1273 | ||
1164 | 1274 | ||
1275 | |||
1165 | @deftypefun void MHD_add_connection (struct MHD_Daemon *daemon, int client_socket, const struct sockaddr *addr, socklen_t addrlen) | 1276 | @deftypefun void MHD_add_connection (struct MHD_Daemon *daemon, int client_socket, const struct sockaddr *addr, socklen_t addrlen) |
1166 | Add another client connection to the set of connections | 1277 | Add another client connection to the set of connections |
1167 | managed by MHD. This API is usually not needed (since | 1278 | managed by MHD. This API is usually not needed (since |
@@ -2055,12 +2166,14 @@ information about a daemon is desired. | |||
2055 | @item MHD_DAEMON_INFO_KEY_SIZE | 2166 | @item MHD_DAEMON_INFO_KEY_SIZE |
2056 | Request information about the key size for a particular cipher | 2167 | Request information about the key size for a particular cipher |
2057 | algorithm. The cipher algorithm should be passed as an extra argument | 2168 | algorithm. The cipher algorithm should be passed as an extra argument |
2058 | (of type 'enum MHD_GNUTLS_CipherAlgorithm'). | 2169 | (of type 'enum MHD_GNUTLS_CipherAlgorithm'). No longer supported, |
2170 | using this value will cause MHD_get_daemon_info to return NULL. | ||
2059 | 2171 | ||
2060 | @item MHD_DAEMON_INFO_MAC_KEY_SIZE | 2172 | @item MHD_DAEMON_INFO_MAC_KEY_SIZE |
2061 | Request information about the key size for a particular cipher | 2173 | Request information about the key size for a particular cipher |
2062 | algorithm. The cipher algorithm should be passed as an extra argument | 2174 | algorithm. The cipher algorithm should be passed as an extra argument |
2063 | (of type 'enum MHD_GNUTLS_HashAlgorithm'). | 2175 | (of type 'enum MHD_GNUTLS_HashAlgorithm'). No longer supported, |
2176 | using this value will cause MHD_get_daemon_info to return NULL. | ||
2064 | 2177 | ||
2065 | @item MHD_DAEMON_INFO_LISTEN_FD | 2178 | @item MHD_DAEMON_INFO_LISTEN_FD |
2066 | @cindex listen | 2179 | @cindex listen |
@@ -2070,6 +2183,17 @@ was specified and a client needs to learn what port | |||
2070 | is actually being used by MHD. | 2183 | is actually being used by MHD. |
2071 | No extra arguments should be passed. | 2184 | No extra arguments should be passed. |
2072 | 2185 | ||
2186 | @item MHD_DAEMON_INFO_EPOLL_FD_LINUX_ONLY | ||
2187 | @cindex epoll | ||
2188 | Request the file-descriptor number that MHD is using for epoll. If | ||
2189 | the build is not supporting epoll, NULL is returned; if we are using a | ||
2190 | thread pool or this daemon was not started with | ||
2191 | MHD_USE_EPOLL_LINUX_ONLY, (a pointer to) -1 is returned. If we are | ||
2192 | using MHD_USE_SELECT_INTERNALLY or are in 'external' select mode, the | ||
2193 | internal epoll FD is returned. This function must be used in external | ||
2194 | select mode with epoll to obtain the FD to call epoll on. No extra | ||
2195 | arguments should be passed. | ||
2196 | |||
2073 | @end table | 2197 | @end table |
2074 | @end deftp | 2198 | @end deftp |
2075 | 2199 | ||
diff --git a/doc/performance_data.png b/doc/performance_data.png new file mode 100644 index 00000000..0e447c24 --- /dev/null +++ b/doc/performance_data.png | |||
Binary files differ | |||