Fixed a few c/p errors and removed not related changes.

Can't test POLL mode as MHD didn't support POLL on W32. The reason - winsock implementation is somehow different from POSIX one. libcurl initially added poll support for win32 but later it was removed. I didn't check specific reason so for safety MHD didn't use POLL on W32. However I leave changes for POLL code "as is" in case that we will add support for POLL on win32.
SELECT mode now works perfectly. Shutdown processed without any delay.

May be some comments will be good addition. 
Patch is attached.

--
Evgeny


09.04.2015, 17:28, "Christian Grothoff" <christian@grothoff.org>:
> Hi Evgeny,
>
> I've tried to put together a patch for the issue, but as I'm on
> GNU/Linux, I cannot even test if the patch compiles...  Please let me
> know if it works (and please test with POLL and SELECT separately), at
> least in principle I think this is roughly what the patch should look
> like...
>
> Happy hacking!
>
> Christian
>
> On 04/09/2015 03:25 PM, Evgeny Grin wrote:
>>  If HAVE_LISTEN_SHUTDOWN is not defined (as on win32), pipe is used
>>  automatically.
>>  But pipe is monitored only in main "select()" thread. It's not
>>  monitored in "connection" thread.
>>
>>  Best Wishes,
>>  Evgeny Grin
>>
>>  On 04/09/2015 12:56 PM, Evgeny Grin wrote:
>>>  Hi Christian!
>>>
>>>  Another issue on win32, 100% reproducible.
>>>  When running Kodi unittests, MHD always takes 120 seconds to shutdown.
>>>
>>>  How to reproduce:
>>>  * Start MHD with THREAD_PER_CONNECTION | DEBUG and some static
>>  response,
>>>  * Generate one http 1.1 request with libcurl. Notice that libcurl
>>  always add keep-alive for http 1.1.
>>>  * Let MHD to process request and answer with response.
>>>  * MHD will stay with master thread and one connection thread waiting
>>  for additional requests from same client.
>>>  * Call MHD shutdown. Main thread will shutdown all sockets, but
>>  additional connection thread will stay at MHD_sys_select_ and will get
>>  notification about socket shutdown only after 2 minutes. May be it's
>>  after libcurl will close connection.
>>>  Again - have no idea how to fix it properly. Use pair of sockets
>>  (emulated pipe) for each connection thread? Add daemon pipe FD to
>>  select() in connection thread?
This commit is contained in:
Christian Grothoff
2015-04-09 22:43:05 +00:00
parent d8ac6fd245
commit 84f0be5c24
3 changed files with 62 additions and 5 deletions
+4
View File
@@ -1,3 +1,7 @@
Fri Apr 10 00:38:40 CEST 2015
Ensure fast termination in MHD_USE_THREAD_PER_CONNECTION
mode on W32 by using signal pipe. -CG
Thu Apr 9 09:01:15 CEST 2015
Fixing issue with undrained signal pipe when using
MHD_USE_SELECT_INTERNALLY and MHD_USE_POLL in combination
+1 -1
View File
@@ -130,7 +130,7 @@ typedef intptr_t ssize_t;
* Current version of the library.
* 0x01093001 = 1.9.30-1.
*/
#define MHD_VERSION 0x00094001
#define MHD_VERSION 0x00094002
/**
* MHD-internal return code for "YES".
+57 -4
View File
@@ -792,8 +792,18 @@ MHD_handle_connection (void *data)
struct timeval *tvp;
unsigned int timeout;
time_t now;
#if WINDOWS
MHD_pipe spipe = con->daemon->wpipe[0];
char tmp;
#ifdef HAVE_POLL_H
struct pollfd p[1];
int extra_slot;
#endif /* HAVE_POLL_H */
#define EXTRA_SLOTS 1
#else /* !WINDOWS */
#define EXTRA_SLOTS 0
#endif /* !WINDOWS */
#ifdef HAVE_POLL_H
struct pollfd p[1 + EXTRA_SLOTS];
#endif
timeout = con->daemon->connection_timeout;
@@ -856,6 +866,14 @@ MHD_handle_connection (void *data)
/* how did we get here!? */
goto exit;
}
#if WINDOWS
if (MHD_INVALID_PIPE_ != spipe)
{
if (MHD_YES !=
add_to_fd_set (spipe, &rs, &max, FD_SETSIZE))
err_state = 1;
}
#endif
if (0 != err_state)
{
#if HAVE_MESSAGES
@@ -878,6 +896,12 @@ MHD_handle_connection (void *data)
#endif
break;
}
#if WINDOWS
/* drain signaling pipe */
if ( (MHD_INVALID_PIPE_ != spipe) &&
(FD_ISSET (spipe, &rs)) )
(void) MHD_pipe_read_ (spipe, &tmp, sizeof (tmp));
#endif
/* call appropriate connection handler if necessary */
if ( (FD_ISSET (con->socket_fd, &rs))
#if HTTPS_SUPPORT
@@ -917,7 +941,22 @@ MHD_handle_connection (void *data)
/* how did we get here!? */
goto exit;
}
if (poll (p, 1,
#if WINDOWS
extra_slot = 0;
if (MHD_INVALID_PIPE != spipe)
{
p[1].events |= POLLIN;
p[1].fd = spipe;
p[1].revents = 0;
extra_slot = 1;
}
#endif
if (poll (p,
#if WINDOWS
1 + extra_slot,
#else
1,
#endif
(NULL == tvp) ? -1 : tv.tv_sec * 1000) < 0)
{
if (EINTR == MHD_socket_errno_)
@@ -929,6 +968,12 @@ MHD_handle_connection (void *data)
#endif
break;
}
#if WINDOWS
/* drain signaling pipe */
if ( (MHD_INVALID_PIPE_ != spipe) &&
(0 != (p[1].revents & (PLLERR | POLLHUP))) )
(void) MHD_pipe_read_ (spipe, &tmp, sizeof (tmp));
#endif
if ( (0 != (p[0].revents & POLLIN))
#if HTTPS_SUPPORT
|| (MHD_YES == con->tls_read_ready)
@@ -4260,8 +4305,16 @@ close_all_connections (struct MHD_Daemon *daemon)
(MHD_YES != MHD_mutex_lock_ (&daemon->cleanup_connection_mutex)) )
MHD_PANIC ("Failed to acquire cleanup mutex\n");
for (pos = daemon->connections_head; NULL != pos; pos = pos->next)
shutdown (pos->socket_fd,
(pos->read_closed == MHD_YES) ? SHUT_WR : SHUT_RDWR);
{
shutdown (pos->socket_fd,
(pos->read_closed == MHD_YES) ? SHUT_WR : SHUT_RDWR);
#if WINDOWS
if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
(MHD_INVALID_PIPE_ != daemon->wpipe[1]) &&
(1 != MHD_pipe_write_ (daemon->wpipe[1], "e", 1)) )
MHD_PANIC ("failed to signal shutdown via pipe");
#endif
}
if ( (0 != (daemon->options & MHD_USE_THREAD_PER_CONNECTION)) &&
(MHD_YES != MHD_mutex_unlock_ (&daemon->cleanup_connection_mutex)) )
MHD_PANIC ("Failed to release cleanup mutex\n");