aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2013-03-31 18:28:43 +0000
committerChristian Grothoff <christian@grothoff.org>2013-03-31 18:28:43 +0000
commit39affe6c5629b78e418f33787ec7a9556b287832 (patch)
treec7951f6ec566334705e1a78ef0ba9bdba368ce8c
parent5b45f52e777fafb65fe9e4a53d202e38e3accdc9 (diff)
downloadlibmicrohttpd-39affe6c5629b78e418f33787ec7a9556b287832.tar.gz
libmicrohttpd-39affe6c5629b78e418f33787ec7a9556b287832.zip
adding MHD_run_from_select to API
-rw-r--r--ChangeLog5
-rw-r--r--doc/libmicrohttpd.texi42
-rw-r--r--src/daemon/EXPORT.sym1
-rw-r--r--src/daemon/daemon.c97
-rw-r--r--src/include/microhttpd.h33
5 files changed, 146 insertions, 32 deletions
diff --git a/ChangeLog b/ChangeLog
index 12edcf68..474c398a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
1Sun Mar 31 20:27:48 CEST 2013
2 Adding new API call 'MHD_run_from_select' to allow programs
3 running in 'external select mode' to reduce the number of
4 'select' calls by a factor of two. -CG
5
1Sun Mar 31 20:03:48 CEST 2013 6Sun Mar 31 20:03:48 CEST 2013
2 Performance improvements, updated documentation. 7 Performance improvements, updated documentation.
3 Make better use of available memory pool memory for 8 Make better use of available memory pool memory for
diff --git a/doc/libmicrohttpd.texi b/doc/libmicrohttpd.texi
index b5284c3c..d82ebeb3 100644
--- a/doc/libmicrohttpd.texi
+++ b/doc/libmicrohttpd.texi
@@ -1095,11 +1095,53 @@ Shutdown an HTTP daemon.
1095Run webserver operations (without blocking unless in client callbacks). 1095Run webserver operations (without blocking unless in client callbacks).
1096This method should be called by clients in combination with 1096This method should be called by clients in combination with
1097@code{MHD_get_fdset()} if the client-controlled @code{select}-method is used. 1097@code{MHD_get_fdset()} if the client-controlled @code{select}-method is used.
1098@cindex select
1099@cindex poll
1100
1101This function will work for external @code{poll} and @code{select} mode.
1102However, if using external @code{select} mode, you may want to
1103instead use @code{MHD_run_from_select}, as it is more efficient.
1104
1105@table @var
1106@item daemon
1107daemon to process connections of
1108@end table
1098 1109
1099Return @code{MHD_YES} on success, @code{MHD_NO} if this daemon was not 1110Return @code{MHD_YES} on success, @code{MHD_NO} if this daemon was not
1100started with the right options for this call. 1111started with the right options for this call.
1101@end deftypefun 1112@end deftypefun
1102 1113
1114@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)
1115Run webserver operations given sets of ready socket handles.
1116@cindex select
1117
1118This method should be called by clients in combination with
1119@code{MHD_get_fdset} if the client-controlled (external)
1120select method is used.
1121
1122You can use this function instead of @code{MHD_run} if you called
1123@code{select} on the result from @code{MHD_get_fdset}. File descriptors in
1124the sets that are not controlled by MHD will be ignored. Calling
1125this function instead of @code{MHD_run} is more efficient as MHD will
1126not have to call @code{select} again to determine which operations are
1127ready.
1128
1129@table @var
1130@item daemon
1131daemon to process connections of
1132@item read_fd_set
1133set of descriptors that must be ready for reading without blocking
1134@item write_fd_set
1135set of descriptors that must be ready for writing without blocking
1136@item except_fd_set
1137ignored, can be NULL
1138@end table
1139
1140Return @code{MHD_YES} on success, @code{MHD_NO} on serious internal
1141errors.
1142
1143@end deftypefun
1144
1103 1145
1104@deftypefun void MHD_add_connection (struct MHD_Daemon *daemon, int client_socket, const struct sockaddr *addr, socklen_t addrlen) 1146@deftypefun void MHD_add_connection (struct MHD_Daemon *daemon, int client_socket, const struct sockaddr *addr, socklen_t addrlen)
1105Add another client connection to the set of connections 1147Add another client connection to the set of connections
diff --git a/src/daemon/EXPORT.sym b/src/daemon/EXPORT.sym
index 01418626..5c499b0b 100644
--- a/src/daemon/EXPORT.sym
+++ b/src/daemon/EXPORT.sym
@@ -4,6 +4,7 @@ MHD_stop_daemon
4MHD_get_fdset 4MHD_get_fdset
5MHD_get_timeout 5MHD_get_timeout
6MHD_run 6MHD_run
7MHD_run_from_select
7MHD_get_connection_values 8MHD_get_connection_values
8MHD_set_connection_value 9MHD_set_connection_value
9MHD_lookup_connection_value 10MHD_lookup_connection_value
diff --git a/src/daemon/daemon.c b/src/daemon/daemon.c
index 72619c3d..bdd9f87b 100644
--- a/src/daemon/daemon.c
+++ b/src/daemon/daemon.c
@@ -1329,7 +1329,66 @@ MHD_get_timeout (struct MHD_Daemon *daemon,
1329 1329
1330 1330
1331/** 1331/**
1332 * Main select call. 1332 * Run webserver operations. This method should be called by clients
1333 * in combination with MHD_get_fdset if the client-controlled select
1334 * method is used.
1335 *
1336 * You can use this function instead of "MHD_run" if you called
1337 * 'select' on the result from "MHD_get_fdset". File descriptors in
1338 * the sets that are not controlled by MHD will be ignored. Calling
1339 * this function instead of "MHD_run" is more efficient as MHD will
1340 * not have to call 'select' again to determine which operations are
1341 * ready.
1342 *
1343 * @param daemon daemon to run select loop for
1344 * @param read_fd_set read set
1345 * @param write_fd_set write set
1346 * @param except_fd_set except set (not used, can be NULL)
1347 * @return MHD_NO on serious errors, MHD_YES on success
1348 */
1349int
1350MHD_run_from_select (struct MHD_Daemon *daemon,
1351 const fd_set *read_fd_set,
1352 const fd_set *write_fd_set,
1353 const fd_set *except_fd_set)
1354{
1355 int ds;
1356 struct MHD_Connection *pos;
1357 struct MHD_Connection *next;
1358
1359 /* select connection thread handling type */
1360 if ( (-1 != (ds = daemon->socket_fd)) &&
1361 (FD_ISSET (ds, read_fd_set)) )
1362 MHD_accept_connection (daemon);
1363 if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
1364 {
1365 /* do not have a thread per connection, process all connections now */
1366 next = daemon->connections_head;
1367 while (NULL != (pos = next))
1368 {
1369 next = pos->next;
1370 ds = pos->socket_fd;
1371 if (ds != -1)
1372 {
1373 if ( (FD_ISSET (ds, read_fd_set))
1374#if HTTPS_SUPPORT
1375 || (MHD_YES == pos->tls_read_ready)
1376#endif
1377 )
1378 pos->read_handler (pos);
1379 if (FD_ISSET (ds, write_fd_set))
1380 pos->write_handler (pos);
1381 pos->idle_handler (pos);
1382 }
1383 }
1384 }
1385 return MHD_YES;
1386}
1387
1388
1389/**
1390 * Main internal select call. Will compute select sets, call 'select'
1391 * and then MHD_run_from_select with the result.
1333 * 1392 *
1334 * @param daemon daemon to run select loop for 1393 * @param daemon daemon to run select loop for
1335 * @param may_block YES if blocking, NO if non-blocking 1394 * @param may_block YES if blocking, NO if non-blocking
@@ -1339,8 +1398,6 @@ static int
1339MHD_select (struct MHD_Daemon *daemon, 1398MHD_select (struct MHD_Daemon *daemon,
1340 int may_block) 1399 int may_block)
1341{ 1400{
1342 struct MHD_Connection *pos;
1343 struct MHD_Connection *next;
1344 int num_ready; 1401 int num_ready;
1345 fd_set rs; 1402 fd_set rs;
1346 fd_set ws; 1403 fd_set ws;
@@ -1349,7 +1406,6 @@ MHD_select (struct MHD_Daemon *daemon,
1349 struct timeval timeout; 1406 struct timeval timeout;
1350 struct timeval *tv; 1407 struct timeval *tv;
1351 MHD_UNSIGNED_LONG_LONG ltimeout; 1408 MHD_UNSIGNED_LONG_LONG ltimeout;
1352 int ds;
1353 1409
1354 timeout.tv_sec = 0; 1410 timeout.tv_sec = 0;
1355 timeout.tv_usec = 0; 1411 timeout.tv_usec = 0;
@@ -1404,7 +1460,6 @@ MHD_select (struct MHD_Daemon *daemon,
1404 tv = &timeout; 1460 tv = &timeout;
1405 } 1461 }
1406 num_ready = SELECT (max + 1, &rs, &ws, &es, tv); 1462 num_ready = SELECT (max + 1, &rs, &ws, &es, tv);
1407
1408 if (MHD_YES == daemon->shutdown) 1463 if (MHD_YES == daemon->shutdown)
1409 return MHD_NO; 1464 return MHD_NO;
1410 if (num_ready < 0) 1465 if (num_ready < 0)
@@ -1416,33 +1471,7 @@ MHD_select (struct MHD_Daemon *daemon,
1416#endif 1471#endif
1417 return MHD_NO; 1472 return MHD_NO;
1418 } 1473 }
1419 /* select connection thread handling type */ 1474 return MHD_run_from_select (daemon, &rs, &ws, &es);
1420 if ( (-1 != (ds = daemon->socket_fd)) &&
1421 (FD_ISSET (ds, &rs)) )
1422 MHD_accept_connection (daemon);
1423 if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
1424 {
1425 /* do not have a thread per connection, process all connections now */
1426 next = daemon->connections_head;
1427 while (NULL != (pos = next))
1428 {
1429 next = pos->next;
1430 ds = pos->socket_fd;
1431 if (ds != -1)
1432 {
1433 if ( (FD_ISSET (ds, &rs))
1434#if HTTPS_SUPPORT
1435 || (MHD_YES == pos->tls_read_ready)
1436#endif
1437 )
1438 pos->read_handler (pos);
1439 if (FD_ISSET (ds, &ws))
1440 pos->write_handler (pos);
1441 pos->idle_handler (pos);
1442 }
1443 }
1444 }
1445 return MHD_YES;
1446} 1475}
1447 1476
1448 1477
@@ -1647,6 +1676,10 @@ MHD_poll (struct MHD_Daemon *daemon,
1647 * by clients in combination with MHD_get_fdset 1676 * by clients in combination with MHD_get_fdset
1648 * if the client-controlled select method is used. 1677 * if the client-controlled select method is used.
1649 * 1678 *
1679 * This function will work for external 'poll' and 'select' mode.
1680 * However, if using external 'select' mode, you may want to
1681 * instead use 'MHD_run_from_select', as it is more efficient.
1682 *
1650 * @return MHD_YES on success, MHD_NO if this 1683 * @return MHD_YES on success, MHD_NO if this
1651 * daemon was not started with the right 1684 * daemon was not started with the right
1652 * options for this call. 1685 * options for this call.
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
index 3d406c2e..4da26191 100644
--- a/src/include/microhttpd.h
+++ b/src/include/microhttpd.h
@@ -1182,6 +1182,14 @@ int MHD_get_timeout (struct MHD_Daemon *daemon,
1182 * by clients in combination with MHD_get_fdset 1182 * by clients in combination with MHD_get_fdset
1183 * if the client-controlled select method is used. 1183 * if the client-controlled select method is used.
1184 * 1184 *
1185 * This function is a convenience method, which is useful if the
1186 * fd_sets from "MHD_get_fdset" were not directly passed to 'select';
1187 * with this function, MHD will internally do the appropriate 'select'
1188 * call itself again. While it is always safe to call 'MHD_run' (in
1189 * external select mode), you should call 'MHD_run_from_select' if
1190 * performance is important (as it saves an expensive call to
1191 * 'select').
1192 *
1185 * @param daemon daemon to run 1193 * @param daemon daemon to run
1186 * @return MHD_YES on success, MHD_NO if this 1194 * @return MHD_YES on success, MHD_NO if this
1187 * daemon was not started with the right 1195 * daemon was not started with the right
@@ -1191,6 +1199,31 @@ int
1191MHD_run (struct MHD_Daemon *daemon); 1199MHD_run (struct MHD_Daemon *daemon);
1192 1200
1193 1201
1202/**
1203 * Run webserver operations. This method should be called by clients
1204 * in combination with MHD_get_fdset if the client-controlled select
1205 * method is used.
1206 *
1207 * You can use this function instead of "MHD_run" if you called
1208 * 'select' on the result from "MHD_get_fdset". File descriptors in
1209 * the sets that are not controlled by MHD will be ignored. Calling
1210 * this function instead of "MHD_run" is more efficient as MHD will
1211 * not have to call 'select' again to determine which operations are
1212 * ready.
1213 *
1214 * @param daemon daemon to run select loop for
1215 * @param read_fd_set read set
1216 * @param write_fd_set write set
1217 * @param except_fd_set except set (not used, can be NULL)
1218 * @return MHD_NO on serious errors, MHD_YES on success
1219 */
1220int
1221MHD_run_from_select (struct MHD_Daemon *daemon,
1222 const fd_set *read_fd_set,
1223 const fd_set *write_fd_set,
1224 const fd_set *except_fd_set);
1225
1226
1194/* **************** Connection handling functions ***************** */ 1227/* **************** Connection handling functions ***************** */
1195 1228
1196/** 1229/**