gnunet-svn
[Top][All Lists]
Advanced

[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.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]