[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[libmicrohttpd] branch master updated: Implemented new API function MHD_
From: |
gnunet |
Subject: |
[libmicrohttpd] branch master updated: Implemented new API function MHD_run_wait(). |
Date: |
Thu, 01 Apr 2021 16:54:24 +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 bf25ee3a Implemented new API function MHD_run_wait().
bf25ee3a is described below
commit bf25ee3a3220596b83b6530b06d4106f2f0bfda1
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
AuthorDate: Thu Apr 1 17:52:08 2021 +0300
Implemented new API function MHD_run_wait().
---
ChangeLog | 5 +
src/include/microhttpd.h | 35 ++++++-
src/microhttpd/daemon.c | 201 +++++++++++++++++++++++++-----------
src/testcurl/.gitignore | 2 +
src/testcurl/Makefile.am | 20 ++++
src/testcurl/test_get_wait.c | 238 +++++++++++++++++++++++++++++++++++++++++++
6 files changed, 439 insertions(+), 62 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 0a0ddf39..e9a8a28f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Thu 01 Apr 2021 17:46:00 MSK
+ Added new function MHD_run_wait() useful for single-threaded applications
+ without other network activity.
+ Added tests for the new function. -EG
+
Wed 17 Mar 2021 20:53:33 MSK
Re-factored startup log parameters processing. Warn user if wrong logger
could be used potentially.
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
index 59170dfe..a4ba9bf1 100644
--- a/src/include/microhttpd.h
+++ b/src/include/microhttpd.h
@@ -135,7 +135,7 @@ typedef intptr_t ssize_t;
* they are parsed as decimal numbers.
* Example: 0x01093001 = 1.9.30-1.
*/
-#define MHD_VERSION 0x00097205
+#define MHD_VERSION 0x00097206
/**
* Operational results from MHD calls.
@@ -2698,6 +2698,39 @@ _MHD_EXTERN enum MHD_Result
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.
+ * 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.
+ * @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
+ * blocks for specified amount of time. The real processing
+ * time can be shorter (if some data comes earlier) or
+ * longer (if data processing requires more time, especially
+ * in the user callbacks).
+ * If set to '0' then function does not block and processes
+ * only already available data (if any).
+ * If set to '-1' then function waits for events
+ * indefinitely (blocks until next network activity).
+ * @return #MHD_YES on success, #MHD_NO if this
+ * daemon was not started with the right
+ * options for this call or some serious
+ * unrecoverable error occurs.
+ * @note Available since #MHD_VERSION 0x00097206
+ * @ingroup event
+ */
+enum MHD_Result
+MHD_run_wait (struct MHD_Daemon *daemon,
+ int32_t millisec);
+
+
/**
* Run webserver operations. This method should be called by clients
* in combination with #MHD_get_fdset and #MHD_get_timeout() if the
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index 0fe47228..59eaf953 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -101,16 +101,17 @@ close_all_connections (struct MHD_Daemon *daemon);
#ifdef EPOLL_SUPPORT
/**
- * Do epoll()-based processing (this function is allowed to
- * block if @a may_block is set to #MHD_YES).
+ * Do epoll()-based processing.
*
* @param daemon daemon to run poll loop for
- * @param may_block #MHD_YES if blocking, #MHD_NO if non-blocking
+ * @param millisec the maximum time in milliseconds to wait for events,
+ * set to '0' for non-blocking processing,
+ * set to '-1' to wait indefinitely.
* @return #MHD_NO on serious errors, #MHD_YES on success
*/
static enum MHD_Result
MHD_epoll (struct MHD_Daemon *daemon,
- int may_block);
+ int32_t millisec);
#endif /* EPOLL_SUPPORT */
@@ -3834,6 +3835,35 @@ MHD_get_timeout (struct MHD_Daemon *daemon,
}
+/**
+ * Obtain timeout value for polling function for this daemon.
+ * @remark To be called only from the thread that processes
+ * daemon's select()/poll()/etc.
+ *
+ * @param daemon the daemon to query for timeout
+ * @param max_timeout the maximum return value (in milliseconds),
+ * ignored if set to '-1'
+ * @return timeout value in milliseconds or -1 if no timeout is expected.
+ */
+static int
+get_timeout_millisec_ (struct MHD_Daemon *daemon,
+ int32_t max_timeout)
+{
+ MHD_UNSIGNED_LONG_LONG ulltimeout;
+ if (0 == max_timeout)
+ return 0;
+
+ if (MHD_NO == MHD_get_timeout (daemon, &ulltimeout))
+ return (INT_MAX < max_timeout) ? INT_MAX : (int) max_timeout;
+
+ if ( (0 > max_timeout) ||
+ ((uint32_t) max_timeout > ulltimeout) )
+ return (INT_MAX < ulltimeout) ? INT_MAX : (int) ulltimeout;
+
+ return (INT_MAX < max_timeout) ? INT_MAX : (int) max_timeout;
+}
+
+
/**
* Internal version of #MHD_run_from_select().
*
@@ -3978,7 +4008,7 @@ MHD_run_from_select (struct MHD_Daemon *daemon,
{
#ifdef EPOLL_SUPPORT
enum MHD_Result ret = MHD_epoll (daemon,
- MHD_NO);
+ 0);
MHD_cleanup_connections (daemon);
return ret;
@@ -4003,12 +4033,14 @@ MHD_run_from_select (struct MHD_Daemon *daemon,
* and then #internal_run_from_select with the result.
*
* @param daemon daemon to run select() loop for
- * @param may_block #MHD_YES if blocking, #MHD_NO if non-blocking
+ * @param millisec the maximum time in milliseconds to wait for events,
+ * set to '0' for non-blocking processing,
+ * set to '-1' to wait indefinitely.
* @return #MHD_NO on serious errors, #MHD_YES on success
*/
static enum MHD_Result
MHD_select (struct MHD_Daemon *daemon,
- int may_block)
+ int32_t millisec)
{
int num_ready;
fd_set rs;
@@ -4017,7 +4049,6 @@ MHD_select (struct MHD_Daemon *daemon,
MHD_socket maxsock;
struct timeval timeout;
struct timeval *tv;
- MHD_UNSIGNED_LONG_LONG ltimeout;
int err_state;
MHD_socket ls;
@@ -4033,7 +4064,7 @@ MHD_select (struct MHD_Daemon *daemon,
if ( (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) &&
(MHD_NO != resume_suspended_connections (daemon)) &&
(0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) )
- may_block = MHD_NO;
+ millisec = 0;
if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
{
@@ -4118,25 +4149,47 @@ MHD_select (struct MHD_Daemon *daemon,
FD_CLR (ls,
&rs);
}
- tv = NULL;
+
if (MHD_NO != err_state)
- may_block = MHD_NO;
- if (MHD_NO == may_block)
+ millisec = 0;
+ tv = NULL;
+ if (0 == millisec)
{
timeout.tv_usec = 0;
timeout.tv_sec = 0;
tv = &timeout;
}
- else if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
- (MHD_NO != MHD_get_timeout (daemon, <imeout)) )
+ else
{
- /* ltimeout is in ms */
- timeout.tv_usec = (ltimeout % 1000) * 1000;
- if (ltimeout / 1000 > TIMEVAL_TV_SEC_MAX)
- timeout.tv_sec = TIMEVAL_TV_SEC_MAX;
- else
- timeout.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE) (ltimeout / 1000);
- tv = &timeout;
+ MHD_UNSIGNED_LONG_LONG ltimeout;
+
+ if ( (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
+ (MHD_NO != MHD_get_timeout (daemon, <imeout)) )
+ {
+ tv = &timeout; /* have timeout value */
+ if ( (0 < millisec) &&
+ (ltimeout > (MHD_UNSIGNED_LONG_LONG) millisec) )
+ ltimeout = (MHD_UNSIGNED_LONG_LONG) millisec;
+ }
+ else if (0 < millisec)
+ {
+ tv = &timeout; /* have timeout value */
+ ltimeout = (MHD_UNSIGNED_LONG_LONG) millisec;
+ }
+
+ if (NULL != tv)
+ { /* have timeout value */
+ if (ltimeout / 1000 > TIMEVAL_TV_SEC_MAX)
+ {
+ timeout.tv_sec = TIMEVAL_TV_SEC_MAX;
+ timeout.tv_usec = 0;
+ }
+ else
+ {
+ timeout.tv_sec = (_MHD_TIMEVAL_TV_SEC_TYPE) (ltimeout / 1000);
+ timeout.tv_usec = (ltimeout % 1000) * 1000;
+ }
+ }
}
num_ready = MHD_SYS_select_ (maxsock + 1,
&rs,
@@ -4172,12 +4225,14 @@ MHD_select (struct MHD_Daemon *daemon,
* socket using poll().
*
* @param daemon daemon to run poll loop for
- * @param may_block #MHD_YES if blocking, #MHD_NO if non-blocking
+ * @param millisec the maximum time in milliseconds to wait for events,
+ * set to '0' for non-blocking processing,
+ * set to '-1' to wait indefinitely.
* @return #MHD_NO on serious errors, #MHD_YES on success
*/
static enum MHD_Result
MHD_poll_all (struct MHD_Daemon *daemon,
- int may_block)
+ int32_t millisec)
{
unsigned int num_connections;
struct MHD_Connection *pos;
@@ -4189,7 +4244,7 @@ MHD_poll_all (struct MHD_Daemon *daemon,
if ( (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) &&
(MHD_NO != resume_suspended_connections (daemon)) )
- may_block = MHD_NO;
+ millisec = 0;
/* count number of connections and thus determine poll set size */
num_connections = 0;
@@ -4200,7 +4255,6 @@ MHD_poll_all (struct MHD_Daemon *daemon,
num_connections += 2;
#endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
{
- MHD_UNSIGNED_LONG_LONG ltimeout;
unsigned int i;
int timeout;
unsigned int poll_server;
@@ -4243,14 +4297,8 @@ MHD_poll_all (struct MHD_Daemon *daemon,
poll_itc_idx = (int) poll_server;
poll_server++;
}
- if (may_block == MHD_NO)
- timeout = 0;
- else if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) ||
- (MHD_NO == MHD_get_timeout (daemon,
- <imeout)) )
- timeout = -1;
- else
- timeout = (ltimeout > INT_MAX) ? INT_MAX : (int) ltimeout;
+
+ timeout = get_timeout_millisec_ (daemon, millisec);
i = 0;
for (pos = daemon->connections_tail; NULL != pos; pos = pos->prev)
@@ -4494,7 +4542,7 @@ MHD_poll (struct MHD_Daemon *daemon,
return MHD_NO;
if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
return MHD_poll_all (daemon,
- may_block);
+ may_block ? -1 : 0);
return MHD_poll_listen_socket (daemon,
may_block);
#else
@@ -4685,16 +4733,17 @@ static const char *const epoll_itc_marker =
"itc_marker";
/**
- * Do epoll()-based processing (this function is allowed to
- * block if @a may_block is set to #MHD_YES).
+ * Do epoll()-based processing.
*
* @param daemon daemon to run poll loop for
- * @param may_block #MHD_YES if blocking, #MHD_NO if non-blocking
+ * @param millisec the maximum time in milliseconds to wait for events,
+ * set to '0' for non-blocking processing,
+ * set to '-1' to wait indefinitely.
* @return #MHD_NO on serious errors, #MHD_YES on success
*/
static enum MHD_Result
MHD_epoll (struct MHD_Daemon *daemon,
- int may_block)
+ int32_t millisec)
{
#if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
static const char *const upgrade_marker = "upgrade_ptr";
@@ -4704,7 +4753,6 @@ MHD_epoll (struct MHD_Daemon *daemon,
struct epoll_event events[MAX_EVENTS];
struct epoll_event event;
int timeout_ms;
- MHD_UNSIGNED_LONG_LONG timeout_ll;
int num_events;
unsigned int i;
MHD_socket ls;
@@ -4790,23 +4838,9 @@ MHD_epoll (struct MHD_Daemon *daemon,
if ( (0 != (daemon->options & MHD_TEST_ALLOW_SUSPEND_RESUME)) &&
(MHD_NO != resume_suspended_connections (daemon)) )
- may_block = MHD_NO;
+ millisec = 0;
- if (MHD_NO != may_block)
- {
- if (MHD_NO != MHD_get_timeout (daemon,
- &timeout_ll))
- {
- if (timeout_ll >= (MHD_UNSIGNED_LONG_LONG) INT_MAX)
- timeout_ms = INT_MAX;
- else
- timeout_ms = (int) timeout_ll;
- }
- else
- timeout_ms = -1;
- }
- else
- timeout_ms = 0;
+ timeout_ms = get_timeout_millisec_ (daemon, millisec);
/* Reset. New value will be set when connections are processed. */
/* Note: Used mostly for uniformity here as same situation is
@@ -5026,24 +5060,69 @@ MHD_run (struct MHD_Daemon *daemon)
if ( (daemon->shutdown) ||
(0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) )
return MHD_NO;
+
+ (void) MHD_run_wait (daemon, 0);
+ return MHD_YES;
+}
+
+
+/**
+ * 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.
+ * 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.
+ * @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
+ * blocks for specified amount of time. The real processing
+ * time can be shorter (if some data comes earlier) or
+ * longer (if data processing requires more time, especially
+ * in the user callbacks).
+ * If set to '0' then function does not block and processes
+ * only already available data (if any).
+ * If set to '-1' then function waits for events
+ * indefinitely (blocks until next network activity).
+ * @return #MHD_YES on success, #MHD_NO if this
+ * daemon was not started with the right
+ * options for this call or some serious
+ * unrecoverable error occurs.
+ * @note Available since #MHD_VERSION 0x00097206
+ * @ingroup event
+ */
+enum MHD_Result
+MHD_run_wait (struct MHD_Daemon *daemon,
+ int32_t millisec)
+{
+ enum MHD_Result res;
+ if ( (daemon->shutdown) ||
+ (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) )
+ return MHD_NO;
+
+ if (0 > millisec)
+ millisec = -1;
if (0 != (daemon->options & MHD_USE_POLL))
{
- MHD_poll (daemon, MHD_NO);
+ res = MHD_poll_all (daemon, millisec);
MHD_cleanup_connections (daemon);
}
#ifdef EPOLL_SUPPORT
else if (0 != (daemon->options & MHD_USE_EPOLL))
{
- MHD_epoll (daemon, MHD_NO);
+ res = MHD_epoll (daemon, millisec);
MHD_cleanup_connections (daemon);
}
#endif
else
{
- MHD_select (daemon, MHD_NO);
+ res = MHD_select (daemon, millisec);
/* MHD_select does MHD_cleanup_connections already */
}
- return MHD_YES;
+ return res;
}
@@ -5139,10 +5218,10 @@ MHD_polling_thread (void *cls)
MHD_poll (daemon, MHD_YES);
#ifdef EPOLL_SUPPORT
else if (0 != (daemon->options & MHD_USE_EPOLL))
- MHD_epoll (daemon, MHD_YES);
+ MHD_epoll (daemon, -1);
#endif
else
- MHD_select (daemon, MHD_YES);
+ MHD_select (daemon, -1);
MHD_cleanup_connections (daemon);
}
diff --git a/src/testcurl/.gitignore b/src/testcurl/.gitignore
index 008262bd..bbc1b2a9 100644
--- a/src/testcurl/.gitignore
+++ b/src/testcurl/.gitignore
@@ -118,3 +118,5 @@ test_patch11
core
/test_get_iovec
/test_get_iovec11
+/test_get_wait
+/test_get_wait11
diff --git a/src/testcurl/Makefile.am b/src/testcurl/Makefile.am
index d0580554..66aebe3e 100644
--- a/src/testcurl/Makefile.am
+++ b/src/testcurl/Makefile.am
@@ -46,6 +46,8 @@ THREAD_ONLY_TESTS += \
endif
THREAD_ONLY_TESTS += \
+ test_get_wait \
+ test_get_wait11 \
test_quiesce \
$(EMPTY_ITEM)
@@ -232,6 +234,24 @@ test_get_sendfile_LDADD = \
$(top_builddir)/src/microhttpd/libmicrohttpd.la \
@LIBCURL@
+test_get_wait_SOURCES = \
+ test_get_wait.c \
+ mhd_has_in_name.h
+test_get_wait_CFLAGS = \
+ $(PTHREAD_CFLAGS) $(AM_CFLAGS)
+test_get_wait_LDADD = \
+ $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+ $(PTHREAD_LIBS) @LIBCURL@
+
+test_get_wait11_SOURCES = \
+ test_get_wait.c \
+ mhd_has_in_name.h
+test_get_wait11_CFLAGS = \
+ $(PTHREAD_CFLAGS) $(AM_CFLAGS)
+test_get_wait11_LDADD = \
+ $(top_builddir)/src/microhttpd/libmicrohttpd.la \
+ $(PTHREAD_LIBS) @LIBCURL@
+
test_urlparse_SOURCES = \
test_urlparse.c mhd_has_in_name.h
test_urlparse_LDADD = \
diff --git a/src/testcurl/test_get_wait.c b/src/testcurl/test_get_wait.c
new file mode 100644
index 00000000..cfabd2d1
--- /dev/null
+++ b/src/testcurl/test_get_wait.c
@@ -0,0 +1,238 @@
+/*
+ This file is part of libmicrohttpd
+ Copyright (C) 2007, 2009, 2011 Christian Grothoff
+ Copyright (C) 2016-2021 Karlson2k (Evgeny Grin)
+
+ libmicrohttpd is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ libmicrohttpd is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with libmicrohttpd; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+/**
+ * @file test_get_wait.c
+ * @brief Test 'MHD_run_wait()' function.
+ * @author Christian Grothoff
+ * @author Karlson2k (Evgeny Grin)
+ */
+
+#include "MHD_config.h"
+#include "platform.h"
+#include <curl/curl.h>
+#include <microhttpd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <pthread.h>
+#include "mhd_has_in_name.h"
+
+#if defined(MHD_CPU_COUNT) && (MHD_CPU_COUNT + 0) < 2
+#undef MHD_CPU_COUNT
+#endif
+#if ! defined(MHD_CPU_COUNT)
+#define MHD_CPU_COUNT 2
+#endif
+
+/**
+ * How many rounds of operations do we do for each
+ * test.
+ * Check all three types of requests for HTTP/1.1:
+ * * first request, new connection;
+ * * "middle" request, existing connection with stay-alive;
+ * * final request, no data processed after.
+ */
+#define ROUNDS 3
+
+/**
+ * Do we use HTTP 1.1?
+ */
+static int oneone;
+
+/**
+ * Response to return (re-used).
+ */
+static struct MHD_Response *response;
+
+/**
+ * Set to 1 if the worker threads are done.
+ */
+static volatile int signal_done;
+
+
+static size_t
+copyBuffer (void *ptr,
+ size_t size, size_t nmemb,
+ void *ctx)
+{
+ (void) ptr; (void) ctx; /* Unused. Silent compiler warning. */
+ return size * nmemb;
+}
+
+
+static enum MHD_Result
+ahc_echo (void *cls,
+ struct MHD_Connection *connection,
+ const char *url,
+ const char *method,
+ const char *version,
+ const char *upload_data, size_t *upload_data_size,
+ void **unused)
+{
+ static int ptr;
+ const char *me = cls;
+ enum MHD_Result ret;
+ (void) url; (void) version; /* Unused. Silent compiler
warning. */
+ (void) upload_data; (void) upload_data_size; /* Unused. Silent compiler
warning. */
+
+ if (0 != strcmp (me, method))
+ return MHD_NO; /* unexpected method */
+ if (&ptr != *unused)
+ {
+ *unused = &ptr;
+ return MHD_YES;
+ }
+ *unused = NULL;
+ ret = MHD_queue_response (connection, MHD_HTTP_OK, response);
+ if (ret == MHD_NO)
+ abort ();
+ return ret;
+}
+
+
+static void *
+thread_gets (void *param)
+{
+ CURL *c;
+ CURLcode errornum;
+ unsigned int i;
+ char url[64];
+ int port = (int) (intptr_t) param;
+
+ snprintf (url,
+ sizeof (url),
+ "http://127.0.0.1:%d/hello_world",
+ port);
+
+ c = curl_easy_init ();
+ if (NULL == c)
+ _exit (99);
+ curl_easy_setopt (c, CURLOPT_URL, url);
+ curl_easy_setopt (c, CURLOPT_WRITEFUNCTION, ©Buffer);
+ curl_easy_setopt (c, CURLOPT_WRITEDATA, NULL);
+ curl_easy_setopt (c, CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt (c, CURLOPT_TIMEOUT, 15L);
+ if (oneone)
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ else
+ curl_easy_setopt (c, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
+ curl_easy_setopt (c, CURLOPT_CONNECTTIMEOUT, 15L);
+ curl_easy_setopt (c, CURLOPT_NOSIGNAL, 1L);
+ for (i = 0; i < ROUNDS; i++)
+ {
+ if (CURLE_OK != (errornum = curl_easy_perform (c)))
+ {
+ signal_done = 1;
+ fprintf (stderr,
+ "curl_easy_perform failed: `%s'\n",
+ curl_easy_strerror (errornum));
+ curl_easy_cleanup (c);
+ abort ();
+ }
+ }
+ curl_easy_cleanup (c);
+ signal_done = 1;
+
+ return NULL;
+}
+
+
+static int
+testRunWaitGet (int port, int poll_flag)
+{
+ pthread_t get_tid;
+ struct MHD_Daemon *d;
+ const char *const test_desc = ((poll_flag & MHD_USE_AUTO) ?
+ "MHD_USE_AUTO" :
+ (poll_flag & MHD_USE_POLL) ?
+ "MHD_USE_POLL" :
+ (poll_flag & MHD_USE_EPOLL) ?
+ "MHD_USE_EPOLL" :
+ "select()");
+
+ if (MHD_NO != MHD_is_feature_supported (MHD_FEATURE_AUTODETECT_BIND_PORT))
+ port = 0;
+
+ printf ("Starting MHD_run_wait() test with MHD in %s polling mode.\n",
+ test_desc);
+ signal_done = 0;
+ d = MHD_start_daemon (MHD_USE_ERROR_LOG | poll_flag,
+ port, NULL, NULL, &ahc_echo, "GET", MHD_OPTION_END);
+ if (d == NULL)
+ abort ();
+ if (0 == port)
+ {
+ const union MHD_DaemonInfo *dinfo;
+ dinfo = MHD_get_daemon_info (d, MHD_DAEMON_INFO_BIND_PORT);
+ if ((NULL == dinfo) || (0 == dinfo->port) )
+ abort ();
+ port = (int) dinfo->port;
+ }
+
+ if (0 != pthread_create (&get_tid, NULL,
+ &thread_gets, (void*) (intptr_t) port))
+ _exit (99);
+
+ /* As another thread sets "done" flag after ending of network
+ * activity, it's required to set positive timeout value for MHD_run_wait().
+ * Alternatively, to use timeout value "-1" here, another thread should start
+ * additional connection to wake MHD after setting "done" flag. */
+ do
+ {
+ if (MHD_NO == MHD_run_wait (d, 50))
+ abort ();
+ } while (0 == signal_done);
+
+ if (0 != pthread_join (get_tid, NULL))
+ _exit (99);
+
+ MHD_stop_daemon (d);
+ printf ("Test succeeded.\n");
+ return 0;
+}
+
+
+int
+main (int argc, char *const *argv)
+{
+ int port = 1675;
+ (void) argc; /* Unused. Silent compiler warning. */
+
+ if ((NULL == argv) || (0 == argv[0]))
+ return 99;
+ oneone = has_in_name (argv[0], "11");
+ if (oneone)
+ port += 5;
+ if (0 != curl_global_init (CURL_GLOBAL_WIN32))
+ return 2;
+ response = MHD_create_response_from_buffer (strlen ("/hello_world"),
+ "/hello_world",
+ MHD_RESPMEM_MUST_COPY);
+ testRunWaitGet (port++, 0);
+ if (MHD_YES == MHD_is_feature_supported (MHD_FEATURE_EPOLL))
+ testRunWaitGet (port++, MHD_USE_EPOLL);
+ testRunWaitGet (port++, MHD_USE_AUTO);
+
+ MHD_destroy_response (response);
+ curl_global_cleanup ();
+ return 0; /* Errors produce abort() or _exit() */
+}
--
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: Implemented new API function MHD_run_wait().,
gnunet <=