[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[libmicrohttpd] branch master updated: Further clarified requirement to
From: |
gnunet |
Subject: |
[libmicrohttpd] branch master updated: Further clarified requirement to use MHD_get_timeout() |
Date: |
Wed, 12 May 2021 19:14:16 +0200 |
This is an automated email from the git hooks/post-receive script.
karlson2k pushed a commit to branch master
in repository libmicrohttpd.
The following commit(s) were added to refs/heads/master by this push:
new 9ac7492b Further clarified requirement to use MHD_get_timeout()
9ac7492b is described below
commit 9ac7492bb57e5545b7ca3d6f840b47b2b90c33a0
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
AuthorDate: Wed May 12 20:11:32 2021 +0300
Further clarified requirement to use MHD_get_timeout()
Emphasise that it is necessary to use MHD_get_timeout() with any
external sockets polling function.
---
src/include/microhttpd.h | 102 +++++++++++++++++++++++++++++++++--------------
src/microhttpd/daemon.c | 81 ++++++++++++++++++++++++++-----------
2 files changed, 130 insertions(+), 53 deletions(-)
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
index 54a3afa7..44156aab 100644
--- a/src/include/microhttpd.h
+++ b/src/include/microhttpd.h
@@ -2121,8 +2121,13 @@ enum MHD_DaemonInfoType
/**
* Request the file descriptor for the external epoll.
* No extra arguments should be passed.
+ *
* Waiting on epoll FD must not block longer than value
- * returned by #MHD_get_timeout().
+ * returned by #MHD_get_timeout() otherwise connections
+ * will "hung" with unprocessed data in network buffers
+ * and timed-out connections will not be closed.
+ *
+ * @sa #MHD_get_timeout(), #MHD_run()
*/
MHD_DAEMON_INFO_EPOLL_FD_LINUX_ONLY,
MHD_DAEMON_INFO_EPOLL_FD = MHD_DAEMON_INFO_EPOLL_FD_LINUX_ONLY,
@@ -2557,10 +2562,12 @@ MHD_add_connection (struct MHD_Daemon *daemon,
*
* This function should only be called in when MHD is configured to
* use external select with 'select()' or with 'epoll'.
- * In the latter case, it will only add the single 'epoll()' file
+ * In the latter case, it will only add the single 'epoll' file
* descriptor used by MHD to the sets.
- * It's necessary to use #MHD_get_timeout() in combination with
- * this function.
+ * It's necessary to use #MHD_get_timeout() to get maximum timeout
+ * value for `select()`. Usage of `select()` with indefinite timeout
+ * (or timeout larger than returned by #MHD_get_timeout()) will
+ * violate MHD API and may results in pending unprocessed data.
*
* This function must be called only for daemon started
* without #MHD_USE_INTERNAL_POLLING_THREAD flag.
@@ -2598,8 +2605,10 @@ MHD_get_fdset (struct MHD_Daemon *daemon,
* use external select with 'select()' or with 'epoll'.
* In the latter case, it will only add the single 'epoll' file
* descriptor used by MHD to the sets.
- * It's necessary to use #MHD_get_timeout() in combination with
- * this function.
+ * It's necessary to use #MHD_get_timeout() to get maximum timeout
+ * value for `select()`. Usage of `select()` with indefinite timeout
+ * (or timeout larger than returned by #MHD_get_timeout()) will
+ * violate MHD API and may results in pending unprocessed data.
*
* This function must be called only for daemon started
* without #MHD_USE_INTERNAL_POLLING_THREAD flag.
@@ -2632,10 +2641,17 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon,
* daemon FDs in fd_sets, call FD_ZERO for each fd_set
* before calling this function. Size of fd_set is
* determined by current value of FD_SETSIZE.
- * It's necessary to use #MHD_get_timeout() in combination with
- * this function.
*
- * This function could be called only for daemon started
+ * This function should only be called in when MHD is configured to
+ * use external select with 'select()' or with 'epoll'.
+ * In the latter case, it will only add the single 'epoll' file
+ * descriptor used by MHD to the sets.
+ * It's necessary to use #MHD_get_timeout() to get maximum timeout
+ * value for `select()`. Usage of `select()` with indefinite timeout
+ * (or timeout larger than returned by #MHD_get_timeout()) will
+ * violate MHD API and may results in pending unprocessed data.
+ *
+ * This function must be called only for daemon started
* without #MHD_USE_INTERNAL_POLLING_THREAD flag.
*
* @param daemon daemon to get sets from
@@ -2657,20 +2673,31 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon,
/**
* Obtain timeout value for polling function for this daemon.
- * This function set value to amount of milliseconds for which polling
- * function (`select()` or `poll()`) should at most block, not the
+ *
+ * This function set value to the amount of milliseconds for which polling
+ * function (`select()`, `poll()` or epoll) should at most block, not the
* timeout value set for connections.
- * It is important to always use this function, even if connection
- * timeout is not set, as in some cases MHD may already have more
- * data to process on next turn (data pending in TLS buffers,
- * connections are already ready with epoll etc.) and returned timeout
- * will be zero.
+ *
+ * Any external polling function must be called with the timeout value
+ * provided by this function. Smaller timeout values can be used for polling
+ * function if it is required for any reason, but using larger timeout value
+ * or no timeout (indefinite timeout) when this function return #MHD_YES
+ * will break MHD processing logic and result in "hung" connections with
+ * data pending in network buffers and other problems.
+ *
+ * It is important to always use this function when external polling is
+ * used. If this function returns #MHD_YES then #MHD_run() (or
+ * #MHD_run_from_select()) must be called right after return from polling
+ * function, regardless of the states of MHD fds.
+ *
+ * In practice, if #MHD_YES is returned then #MHD_run() (or
+ * #MHD_run_from_select()) must be called not later than @a timeout
+ * millisecond.
*
* @param daemon daemon to query for timeout
* @param timeout set to the timeout (in milliseconds)
* @return #MHD_YES on success, #MHD_NO if timeouts are
- * not used (or no connections exist that would
- * necessitate the use of a timeout right now).
+ * not used and no data is pending.
* @ingroup event
*/
_MHD_EXTERN enum MHD_Result
@@ -2679,19 +2706,26 @@ MHD_get_timeout (struct MHD_Daemon *daemon,
/**
- * Run webserver operations (without blocking unless in client
- * callbacks). This method should be called by clients in combination
- * with #MHD_get_fdset if the client-controlled select method is used and
- * #MHD_get_timeout().
+ * Run webserver operations (without blocking unless in client callbacks).
+ *
+ * This method should be called by clients in combination with
+ * #MHD_get_fdset() (or #MHD_get_daemon_info() with MHD_DAEMON_INFO_EPOLL_FD
+ * if epoll is used) and #MHD_get_timeout() if the client-controlled
+ * connection polling method is used (i.e. daemon was started without
+ * #MHD_USE_INTERNAL_POLLING_THREAD flag).
*
* This function is a convenience method, which is useful if the
* fd_sets from #MHD_get_fdset were not directly passed to `select()`;
* with this function, MHD will internally do the appropriate `select()`
- * call itself again. While it is always safe to call #MHD_run (if
- * #MHD_USE_INTERNAL_POLLING_THREAD is not set), you should call
- * #MHD_run_from_select if performance is important (as it saves an
+ * call itself again. While it is acceptable to call #MHD_run (if
+ * #MHD_USE_INTERNAL_POLLING_THREAD is not set) at any moment, you should
+ * call #MHD_run_from_select() if performance is important (as it saves an
* expensive call to `select()`).
*
+ * If #MHD_get_timeout() returned #MHD_YES, than this function must be called
+ * right after polling function returns regardless of detected activity on
+ * the daemon's FDs.
+ *
* @param daemon daemon to run
* @return #MHD_YES on success, #MHD_NO if this
* daemon was not started with the right
@@ -2704,14 +2738,20 @@ MHD_run (struct MHD_Daemon *daemon);
/**
* Run websever operation with possible blocking.
- * This function do the following: waits for any network event not more than
- * specified number of milliseconds, processes all incoming and outgoing
- * data, processes new connections, processes any timed-out connection, and
- * do other things required to run webserver.
+ *
+ * This function does the following: waits for any network event not more
+ * than specified number of milliseconds, processes all incoming and
+ * outgoing data, processes new connections, processes any timed-out
+ * connection, and does other things required to run webserver.
* Once all connections are processed, function returns.
+ *
* This function is useful for quick and simple webserver implementation if
* application needs to run a single thread only and does not have any other
* network activity.
+ *
+ * It is expected that the external socket polling function is not used in
+ * conjunction with this function unless the @a millisec is set to zero.
+ *
* @param daemon the daemon to run
* @param millisec the maximum time in milliseconds to wait for network and
* other events. Note: there is no guarantee that function
@@ -2747,6 +2787,10 @@ MHD_run_wait (struct MHD_Daemon *daemon,
* not have to call `select()` again to determine which operations are
* ready.
*
+ * If #MHD_get_timeout() returned #MHD_YES, than this function must be
+ * called right after `select()` returns regardless of detected activity
+ * on the daemon's FDs.
+ *
* This function cannot be used with daemon started with
* #MHD_USE_INTERNAL_POLLING_THREAD flag.
*
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index 5e7bd384..d6042356 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -703,8 +703,10 @@ MHD_TLS_init (struct MHD_Daemon *daemon)
* use external select with 'select()' or with 'epoll'.
* In the latter case, it will only add the single 'epoll' file
* descriptor used by MHD to the sets.
- * It's necessary to use #MHD_get_timeout() in combination with
- * this function.
+ * It's necessary to use #MHD_get_timeout() to get maximum timeout
+ * value for `select()`. Usage of `select()` with indefinite timeout
+ * (or timeout larger than returned by #MHD_get_timeout()) will
+ * violate MHD API and may results in pending unprocessed data.
*
* This function must be called only for daemon started
* without #MHD_USE_INTERNAL_POLLING_THREAD flag.
@@ -1104,8 +1106,10 @@ internal_get_fdset2 (struct MHD_Daemon *daemon,
* use external select with 'select()' or with 'epoll'.
* In the latter case, it will only add the single 'epoll' file
* descriptor used by MHD to the sets.
- * It's necessary to use #MHD_get_timeout() in combination with
- * this function.
+ * It's necessary to use #MHD_get_timeout() to get maximum timeout
+ * value for `select()`. Usage of `select()` with indefinite timeout
+ * (or timeout larger than returned by #MHD_get_timeout()) will
+ * violate MHD API and may results in pending unprocessed data.
*
* This function must be called only for daemon started
* without #MHD_USE_INTERNAL_POLLING_THREAD flag.
@@ -3772,14 +3776,26 @@ MHD_cleanup_connections (struct MHD_Daemon *daemon)
/**
* Obtain timeout value for polling function for this daemon.
- * This function set value to amount of milliseconds for which polling
- * function (`select()` or `poll()`) should at most block, not the
+ *
+ * This function set value to the amount of milliseconds for which polling
+ * function (`select()`, `poll()` or epoll) should at most block, not the
* timeout value set for connections.
- * It is important to always use this function, even if connection
- * timeout is not set as in some cases MHD may already have more
- * data to process on next turn (data pending in TLS buffers,
- * connections are already ready with epoll etc.) and returned timeout
- * will be zero.
+ *
+ * Any external polling function must be called with the timeout value
+ * provided by this function. Smaller timeout values can be used for polling
+ * function if it is required for any reason, but using larger timeout value
+ * or no timeout (indefinite timeout) when this function return #MHD_YES
+ * will break MHD processing logic and result in "hung" connections with
+ * data pending in network buffers and other problems.
+ *
+ * It is important to always use this function when external polling is
+ * used. If this function returns #MHD_YES then #MHD_run() (or
+ * #MHD_run_from_select()) must be called right after return from polling
+ * function, regardless of the states of MHD fds.
+ *
+ * In practice, if #MHD_YES is returned then #MHD_run() (or
+ * #MHD_run_from_select()) must be called not later than @a timeout
+ * millisecond.
* @remark To be called only from thread that process
* daemon's select()/poll()/etc.
*
@@ -4010,8 +4026,12 @@ internal_run_from_select (struct MHD_Daemon *daemon,
* not have to call `select()` again to determine which operations are
* ready.
*
+ * If #MHD_get_timeout() returned #MHD_YES, than this function must be
+ * called right after `select()` returns regardless of detected activity
+ * on the daemon's FDs.
+ *
* This function cannot be used with daemon started with
- * MHD_USE_INTERNAL_POLLING_THREAD flag.
+ * #MHD_USE_INTERNAL_POLLING_THREAD flag.
*
* @param daemon daemon to run select loop for
* @param read_fd_set read set
@@ -5073,18 +5093,25 @@ MHD_epoll (struct MHD_Daemon *daemon,
/**
- * Run webserver operations (without blocking unless in client
- * callbacks). This method should be called by clients in combination
- * with #MHD_get_fdset if the client-controlled select method is used and
- * #MHD_get_timeout().
+ * Run webserver operations (without blocking unless in client callbacks).
+ *
+ * This method should be called by clients in combination with
+ * #MHD_get_fdset() (or #MHD_get_daemon_info() with MHD_DAEMON_INFO_EPOLL_FD
+ * if epoll is used) and #MHD_get_timeout() if the client-controlled
+ * connection polling method is used (i.e. daemon was started without
+ * #MHD_USE_INTERNAL_POLLING_THREAD flag).
*
* This function is a convenience method, which is useful if the
* fd_sets from #MHD_get_fdset were not directly passed to `select()`;
* with this function, MHD will internally do the appropriate `select()`
- * call itself again. While it is always safe to call #MHD_run (in
- * external select mode), you should call #MHD_run_from_select if
- * performance is important (as it saves an expensive call to
- * `select()`).
+ * call itself again. While it is acceptable to call #MHD_run (if
+ * #MHD_USE_INTERNAL_POLLING_THREAD is not set) at any moment, you should
+ * call #MHD_run_from_select() if performance is important (as it saves an
+ * expensive call to `select()`).
+ *
+ * If #MHD_get_timeout() returned #MHD_YES, than this function must be called
+ * right after polling function returns regardless of detected activity on
+ * the daemon's FDs.
*
* @param daemon daemon to run
* @return #MHD_YES on success, #MHD_NO if this
@@ -5106,14 +5133,20 @@ MHD_run (struct MHD_Daemon *daemon)
/**
* Run websever operation with possible blocking.
- * This function do the following: waits for any network event not more than
- * specified number of milliseconds, processes all incoming and outgoing
- * data, processes new connections, processes any timed-out connection, and
- * do other things required to run webserver.
+ *
+ * This function does the following: waits for any network event not more
+ * than specified number of milliseconds, processes all incoming and
+ * outgoing data, processes new connections, processes any timed-out
+ * connection, and does other things required to run webserver.
* Once all connections are processed, function returns.
+ *
* This function is useful for quick and simple webserver implementation if
* application needs to run a single thread only and does not have any other
* network activity.
+ *
+ * It is expected that the external socket polling function is not used in
+ * conjunction with this function unless the @a millisec is set to zero.
+ *
* @param daemon the daemon to run
* @param millisec the maximum time in milliseconds to wait for network and
* other events. Note: there is no guarantee that function
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [libmicrohttpd] branch master updated: Further clarified requirement to use MHD_get_timeout(),
gnunet <=