gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [libmicrohttpd] branch master updated (2a815fe3 -> f154b0ef


From: gnunet
Subject: [GNUnet-SVN] [libmicrohttpd] branch master updated (2a815fe3 -> f154b0ef)
Date: Wed, 15 Feb 2017 13:37:14 +0100

This is an automated email from the git hooks/post-receive script.

grothoff pushed a change to branch master
in repository libmicrohttpd.

    from 2a815fe3 convert have_chunked_upload to 'bool' type
     new 2eb1573d fix race related to MHD_quiesce_daemon setting the listen 
socket to -1 which may disrupt concurrent non-locking activities by instead 
setting a flag (which suffices given the document semantics of 
MHD_quiesce_daemon()); renaming the socket_fd to listen_fd to distinguish it 
better by name
     new f9c239ec convert listen_socket_in_epoll to 'bool'
     new 3b2c0e14 convert upgrade_fd_in_epoll to 'bool'
     new e5fd7e14 convert have_dhparams to 'bool'
     new 925adb38 convert clean_ready to 'bool'
     new d170754b convert tls_closed to 'bool'
     new d6dd85a3 convert client_aware to 'bool'
     new f154b0ef bump dates and versions and update ChangeLog

The 8 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 ChangeLog                         |   6 ++
 src/include/microhttpd.h          |   2 +-
 src/microhttpd/connection.c       |  18 ++--
 src/microhttpd/connection_https.c |   4 +-
 src/microhttpd/daemon.c           | 203 +++++++++++++++++++++-----------------
 src/microhttpd/internal.h         |  41 ++++----
 src/microhttpd/response.c         |   6 +-
 7 files changed, 156 insertions(+), 124 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 33759ab5..1d61f64a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Wed Feb 15 13:35:36 CET 2017
+       Fixing a few very rare race conditions for thread-pool or
+       thread-per-connection operations during shutdown.
+       Various minor cosmetic improvements.
+       Fixed #4884 and #4888 (solaris portability issues). -CG
+
 Wed Nov 23 15:24:10 MSK 2016
        Used SO_REUSEADDR (on non-W32) alongside with SO_REUSEPORT if option
        MHD_OPTION_LISTENING_ADDRESS_REUSE was set. -EG
diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h
index 32bf41bc..e7879496 100644
--- a/src/include/microhttpd.h
+++ b/src/include/microhttpd.h
@@ -126,7 +126,7 @@ typedef intptr_t ssize_t;
  * Current version of the library.
  * 0x01093001 = 1.9.30-1.
  */
-#define MHD_VERSION 0x00095211
+#define MHD_VERSION 0x00095212
 
 /**
  * MHD-internal return code for "YES".
diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c
index e91b2d87..7cd60da9 100644
--- a/src/microhttpd/connection.c
+++ b/src/microhttpd/connection.c
@@ -1,6 +1,6 @@
 /*
      This file is part of libmicrohttpd
-     Copyright (C) 2007-2016 Daniel Pittman and Christian Grothoff
+     Copyright (C) 2007-2017 Daniel Pittman and Christian Grothoff
 
      This library is free software; you can redistribute it and/or
      modify it under the terms of the GNU Lesser General Public
@@ -551,12 +551,12 @@ MHD_connection_close_ (struct MHD_Connection *connection,
       MHD_destroy_response (resp);
     }
   if ( (NULL != daemon->notify_completed) &&
-       (MHD_YES == connection->client_aware) )
+       (connection->client_aware) )
     daemon->notify_completed (daemon->notify_completed_cls,
                              connection,
                              &connection->client_context,
                              termination_code);
-  connection->client_aware = MHD_NO;
+  connection->client_aware = false;
 }
 
 
@@ -1771,11 +1771,11 @@ parse_initial_message_line (struct MHD_Connection 
*connection,
     }
   if (NULL != daemon->uri_log_callback)
     {
+      connection->client_aware = true;
       connection->client_context
         = daemon->uri_log_callback (daemon->uri_log_callback_cls,
                                    curi,
                                     connection);
-      connection->client_aware = MHD_YES;
     }
   if (NULL != args)
     {
@@ -1812,7 +1812,7 @@ call_connection_handler (struct MHD_Connection 
*connection)
   if (NULL != connection->response)
     return;                     /* already queued a response */
   processed = 0;
-  connection->client_aware = MHD_YES;
+  connection->client_aware = true;
   if (MHD_NO ==
       connection->daemon->default_handler (connection->daemon-> 
default_handler_cls,
                                           connection,
@@ -1974,7 +1974,7 @@ process_request_body (struct MHD_Connection *connection)
            }
         }
       used = processed;
-      connection->client_aware = MHD_YES;
+      connection->client_aware = true;
       if (MHD_NO ==
           connection->daemon->default_handler 
(connection->daemon->default_handler_cls,
                                                connection,
@@ -3132,13 +3132,13 @@ MHD_connection_handle_idle (struct MHD_Connection 
*connection)
           MHD_destroy_response (connection->response);
           connection->response = NULL;
           if ( (NULL != daemon->notify_completed) &&
-               (MHD_YES == connection->client_aware) )
+               (connection->client_aware) )
           {
+            connection->client_aware = false;
            daemon->notify_completed (daemon->notify_completed_cls,
                                      connection,
                                      &connection->client_context,
                                      MHD_REQUEST_TERMINATED_COMPLETED_OK);
-            connection->client_aware = MHD_NO;
           }
           end =
             MHD_lookup_connection_value (connection,
@@ -3183,7 +3183,7 @@ MHD_connection_handle_idle (struct MHD_Connection 
*connection)
               connection->read_buffer_size
                 = connection->daemon->pool_size / 2;
             }
-         connection->client_aware = MHD_NO;
+         connection->client_aware = false;
           connection->client_context = NULL;
           connection->continue_message_write_offset = 0;
           connection->responseCode = 0;
diff --git a/src/microhttpd/connection_https.c 
b/src/microhttpd/connection_https.c
index f1f1f90c..dea9956d 100644
--- a/src/microhttpd/connection_https.c
+++ b/src/microhttpd/connection_https.c
@@ -191,10 +191,10 @@ MHD_set_https_callbacks (struct MHD_Connection 
*connection)
 int
 MHD_tls_connection_shutdown (struct MHD_Connection *connection)
 {
-  if (MHD_NO != connection->tls_closed)
+  if (connection->tls_closed)
     return MHD_NO;
 
-  connection->tls_closed = MHD_YES;
+  connection->tls_closed = true;
   return (GNUTLS_E_SUCCESS == gnutls_bye(connection->tls_session, 
GNUTLS_SHUT_WR)) ?
       MHD_YES : MHD_NO;
 }
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c
index a8997d87..7c4dcde1 100644
--- a/src/microhttpd/daemon.c
+++ b/src/microhttpd/daemon.c
@@ -1,6 +1,6 @@
 /*
   This file is part of libmicrohttpd
-  Copyright (C) 2007-2016 Daniel Pittman and Christian Grothoff
+  Copyright (C) 2007-2017 Daniel Pittman and Christian Grothoff
 
   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
@@ -538,7 +538,7 @@ MHD_init_daemon_certificate (struct MHD_Daemon *daemon)
        }
     }
 
-  if (MHD_YES == daemon->have_dhparams)
+  if (daemon->have_dhparams)
     {
       gnutls_certificate_set_dh_params (daemon->x509_cred,
                                         daemon->https_mem_dhparams);
@@ -796,8 +796,9 @@ MHD_get_fdset2 (struct MHD_Daemon *daemon,
                                  fd_setsize) ? MHD_YES : MHD_NO;
     }
 #endif
-  ls = daemon->socket_fd;
+  ls = daemon->listen_fd;
   if ( (MHD_INVALID_SOCKET != ls) &&
+       (! daemon->was_quiesced) &&
        (! MHD_add_to_fd_set_ (ls,
                               read_fd_set,
                               max_fd,
@@ -1741,18 +1742,18 @@ thread_main_handle_connection (void *data)
           /* Normal HTTP processing is finished,
            * notify application. */
           if ( (NULL != daemon->notify_completed) &&
-               (MHD_YES == con->client_aware) )
+               (con->client_aware) )
             daemon->notify_completed (daemon->notify_completed_cls,
                                       con,
                                       &con->client_context,
                                       MHD_REQUEST_TERMINATED_COMPLETED_OK);
-          con->client_aware = MHD_NO;
+          con->client_aware = false;
 
           thread_main_connection_upgrade (con);
           /* MHD_connection_finish_forward_() was called by 
thread_main_connection_upgrade(). */
 
           /* "Upgraded" data will not be used in this thread from this point. 
*/
-          con->urh->clean_ready = MHD_YES;
+          con->urh->clean_ready = true;
           /* If 'urh->was_closed' set to true, connection will be
            * moved immediately to cleanup list. Otherwise connection
            * will stay in suspended list until 'urh' will be marked
@@ -2500,7 +2501,7 @@ resume_suspended_connections (struct MHD_Daemon *daemon)
 #ifdef UPGRADE_SUPPORT
           || ( (NULL != urh) &&
                ( (! urh->was_closed) ||
-                 (MHD_NO == urh->clean_ready) ) )
+                 (! urh->clean_ready) ) )
 #endif /* UPGRADE_SUPPORT */
          )
         continue;
@@ -2669,7 +2670,8 @@ MHD_accept_connection (struct MHD_Daemon *daemon)
   memset (addr,
           0,
           sizeof (addrstorage));
-  if (MHD_INVALID_SOCKET == (fd = daemon->socket_fd))
+  if ( (MHD_INVALID_SOCKET == (fd = daemon->listen_fd)) ||
+       (daemon->was_quiesced) )
     return MHD_NO;
 #ifdef USE_ACCEPT4
   s = accept4 (fd,
@@ -3034,7 +3036,8 @@ MHD_run_from_select (struct MHD_Daemon *daemon,
 #endif
 
   /* select connection thread handling type */
-  if ( (MHD_INVALID_SOCKET != (ds = daemon->socket_fd)) &&
+  if ( (MHD_INVALID_SOCKET != (ds = daemon->listen_fd)) &&
+       (! daemon->was_quiesced) &&
        (FD_ISSET (ds,
                   read_fd_set)) )
     (void) MHD_accept_connection (daemon);
@@ -3076,7 +3079,7 @@ MHD_run_from_select (struct MHD_Daemon *daemon,
            (0 == urh->out_buffer_used) )
         {
           MHD_connection_finish_forward_ (urh->connection);
-          urh->clean_ready = MHD_YES;
+          urh->clean_ready = true;
           /* Resuming will move connection to cleanup list. */
           MHD_resume_connection(urh->connection);
         }
@@ -3144,7 +3147,8 @@ MHD_select (struct MHD_Daemon *daemon,
   else
     {
       /* accept only, have one thread per connection */
-      if ( (MHD_INVALID_SOCKET != (ls = daemon->socket_fd)) &&
+      if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
+           (! daemon->was_quiesced) &&
            (! MHD_add_to_fd_set_ (ls,
                                   &rs,
                                   &maxsock,
@@ -3167,7 +3171,8 @@ MHD_select (struct MHD_Daemon *daemon,
       /* fdset limit reached, new connections
          cannot be handled. Remove listen socket FD
          from fdset and retry to add ITC FD. */
-      if (MHD_INVALID_SOCKET != (ls = daemon->socket_fd))
+      if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
+           (! daemon->was_quiesced) )
         {
           FD_CLR (ls,
                   &rs);
@@ -3193,7 +3198,7 @@ MHD_select (struct MHD_Daemon *daemon,
      the shutdown OR the termination of an existing connection; so
      only do this optimization if we have a signaling ITC in
      place. */
-  if ( (MHD_INVALID_SOCKET != (ls = daemon->socket_fd)) &&
+  if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
        (MHD_ITC_IS_VALID_(daemon->itc)) &&
        (0 != (daemon->options & MHD_USE_ITC)) &&
        ( (daemon->connections == daemon->connection_limit) ||
@@ -3305,7 +3310,8 @@ MHD_poll_all (struct MHD_Daemon *daemon,
       }
     poll_server = 0;
     poll_listen = -1;
-    if ( (MHD_INVALID_SOCKET != (ls = daemon->socket_fd)) &&
+    if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
+         (! daemon->was_quiesced) &&
         (daemon->connections < daemon->connection_limit) &&
          (! daemon->at_limit) )
       {
@@ -3472,7 +3478,7 @@ MHD_poll_all (struct MHD_Daemon *daemon,
             /* MHD_connection_finish_forward_() will remove connection from
              * 'daemon->urh_head' list. */
             MHD_connection_finish_forward_ (urh->connection);
-            urh->clean_ready = MHD_YES;
+            urh->clean_ready = true;
             /* If 'urh->was_closed' set to true, connection will be
              * moved immediately to cleanup list. Otherwise connection
              * will stay in suspended list until 'urh' will be marked
@@ -3516,7 +3522,9 @@ MHD_poll_listen_socket (struct MHD_Daemon *daemon,
   poll_count = 0;
   poll_listen = -1;
   poll_itc_idx = -1;
-  if (MHD_INVALID_SOCKET != (ls = daemon->socket_fd))
+  if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
+       (! daemon->was_quiesced) )
+
     {
       p[poll_count].fd = ls;
       p[poll_count].events = POLLIN;
@@ -3652,7 +3660,7 @@ run_epoll_for_upgrade (struct MHD_Daemon *daemon)
            * one time for TLS data and one time for socketpair data.
            * If forwarding was finished on first time, second time must
            * be skipped as urh must not be used anymore. */
-          if (MHD_NO != urh->clean_ready)
+          if (urh->clean_ready)
             continue;
 
           /* Update our state based on what is ready according to epoll() */
@@ -3669,7 +3677,7 @@ run_epoll_for_upgrade (struct MHD_Daemon *daemon)
                (0 == urh->out_buffer_used) )
             {
               MHD_connection_finish_forward_ (urh->connection);
-              urh->clean_ready = MHD_YES;
+              urh->clean_ready = true;
               /* If 'urh->was_closed' set to true, connection will be
                * moved immediately to cleanup list. Otherwise connection
                * will stay in suspended list until 'urh' will be marked
@@ -3716,9 +3724,10 @@ MHD_epoll (struct MHD_Daemon *daemon,
     return MHD_NO; /* we're down! */
   if (daemon->shutdown)
     return MHD_NO;
-  if ( (MHD_INVALID_SOCKET != (ls = daemon->socket_fd)) &&
+  if ( (MHD_INVALID_SOCKET != (ls = daemon->listen_fd)) &&
+       (! daemon->was_quiesced) &&
        (daemon->connections < daemon->connection_limit) &&
-       (MHD_NO == daemon->listen_socket_in_epoll) &&
+       (! daemon->listen_socket_in_epoll) &&
        (! daemon->at_limit) )
     {
       event.events = EPOLLIN;
@@ -3735,10 +3744,21 @@ MHD_epoll (struct MHD_Daemon *daemon,
 #endif
          return MHD_NO;
        }
-      daemon->listen_socket_in_epoll = MHD_YES;
+      daemon->listen_socket_in_epoll = true;
     }
+  if ( (daemon->was_quiesced) &&
+       (daemon->listen_socket_in_epoll) )
+  {
+    if (0 != epoll_ctl (daemon->epoll_fd,
+                        EPOLL_CTL_DEL,
+                        ls,
+                        NULL))
+      MHD_PANIC ("Failed to remove listen FD from epoll set\n");
+    daemon->listen_socket_in_epoll = false;
+  }
+
 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
-  if ( (MHD_NO == daemon->upgrade_fd_in_epoll) &&
+  if ( (! daemon->upgrade_fd_in_epoll) &&
        (-1 != daemon->epoll_upgrade_fd) )
     {
       event.events = EPOLLIN | EPOLLOUT;
@@ -3755,12 +3775,13 @@ MHD_epoll (struct MHD_Daemon *daemon,
 #endif
          return MHD_NO;
        }
-      daemon->upgrade_fd_in_epoll = MHD_YES;
+      daemon->upgrade_fd_in_epoll = true;
     }
 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
-  if ( ( (MHD_YES == daemon->listen_socket_in_epoll) &&
-         (daemon->connections == daemon->connection_limit) ) ||
-       (daemon->at_limit) )
+  if ( (daemon->listen_socket_in_epoll) &&
+       ( (daemon->connections == daemon->connection_limit) ||
+         (daemon->at_limit) ||
+         (daemon->was_quiesced) ) )
     {
       /* we're at the connection limit, disable listen socket
         for event loop for now */
@@ -3769,7 +3790,7 @@ MHD_epoll (struct MHD_Daemon *daemon,
                          ls,
                          NULL))
        MHD_PANIC (_("Failed to remove listen FD from epoll set\n"));
-      daemon->listen_socket_in_epoll = MHD_NO;
+      daemon->listen_socket_in_epoll = false;
     }
   if (MHD_YES == may_block)
     {
@@ -4166,7 +4187,7 @@ MHD_quiesce_daemon (struct MHD_Daemon *daemon)
   unsigned int i;
   MHD_socket ret;
 
-  ret = daemon->socket_fd;
+  ret = daemon->listen_fd;
   if (MHD_INVALID_SOCKET == ret)
     return MHD_INVALID_SOCKET;
   if ( (MHD_ITC_IS_INVALID_(daemon->itc)) &&
@@ -4182,18 +4203,18 @@ MHD_quiesce_daemon (struct MHD_Daemon *daemon)
   if (NULL != daemon->worker_pool)
     for (i = 0; i < daemon->worker_pool_size; i++)
       {
-       daemon->worker_pool[i].socket_fd = MHD_INVALID_SOCKET;
+       daemon->worker_pool[i].was_quiesced = true;
 #ifdef EPOLL_SUPPORT
        if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
             (-1 != daemon->worker_pool[i].epoll_fd) &&
-            (MHD_YES == daemon->worker_pool[i].listen_socket_in_epoll) )
+            (daemon->worker_pool[i].listen_socket_in_epoll) )
          {
            if (0 != epoll_ctl (daemon->worker_pool[i].epoll_fd,
                                EPOLL_CTL_DEL,
                                ret,
                                NULL))
              MHD_PANIC (_("Failed to remove listen FD from epoll set\n"));
-           daemon->worker_pool[i].listen_socket_in_epoll = MHD_NO;
+           daemon->worker_pool[i].listen_socket_in_epoll = false;
          }
         else
 #endif
@@ -4203,30 +4224,23 @@ MHD_quiesce_daemon (struct MHD_Daemon *daemon)
               MHD_PANIC (_("Failed to signal quiesce via inter-thread 
communication channel"));
           }
       }
-  /* FIXME: This creates a race with the rest of the code.
-     We may be adding the FD to the epoll-set concurrently
-     in another thread! So we DO need to lock (yuck yuck). */
-  daemon->socket_fd = MHD_INVALID_SOCKET;
+  daemon->was_quiesced = true;
 #ifdef EPOLL_SUPPORT
   if ( (0 != (daemon->options & MHD_USE_EPOLL)) &&
        (-1 != daemon->epoll_fd) &&
-       (MHD_YES == daemon->listen_socket_in_epoll) )
+       (daemon->listen_socket_in_epoll) )
     {
       if (0 != epoll_ctl (daemon->epoll_fd,
                          EPOLL_CTL_DEL,
                          ret,
                          NULL))
        MHD_PANIC ("Failed to remove listen FD from epoll set\n");
-      daemon->listen_socket_in_epoll = MHD_NO;
+      daemon->listen_socket_in_epoll = false;
     }
-  else
 #endif
-    if (MHD_ITC_IS_VALID_(daemon->itc))
-    {
-      if (! MHD_itc_activate_ (daemon->itc, "q"))
-       MHD_PANIC (_("failed to signal quiesce via inter-thread communication 
channel"));
-    }
-
+  if ( (MHD_ITC_IS_VALID_(daemon->itc)) &&
+       (! MHD_itc_activate_ (daemon->itc, "q")) )
+    MHD_PANIC (_("failed to signal quiesce via inter-thread communication 
channel"));
   return ret;
 }
 
@@ -4440,7 +4454,7 @@ parse_options_va (struct MHD_Daemon *daemon,
                   gnutls_dh_params_deinit (daemon->https_mem_dhparams);
                   return MHD_NO;
                 }
-              daemon->have_dhparams = MHD_YES;
+              daemon->have_dhparams = true;
             }
           else
             {
@@ -4499,7 +4513,7 @@ parse_options_va (struct MHD_Daemon *daemon,
          break;
 #endif
        case MHD_OPTION_LISTEN_SOCKET:
-         daemon->socket_fd = va_arg (ap,
+         daemon->listen_fd = va_arg (ap,
                                       MHD_socket);
          break;
         case MHD_OPTION_EXTERNAL_LOGGER:
@@ -4721,7 +4735,8 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon)
          return MHD_NO;
     }
 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
-  if (MHD_INVALID_SOCKET == (ls = daemon->socket_fd))
+  if ( (MHD_INVALID_SOCKET == (ls = daemon->listen_fd)) ||
+       (daemon->was_quiesced) )
     return MHD_YES; /* non-listening daemon */
   event.events = EPOLLIN;
   event.data.ptr = daemon;
@@ -4737,6 +4752,7 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon)
 #endif
       return MHD_NO;
     }
+  daemon->listen_socket_in_epoll = true;
   if (MHD_ITC_IS_VALID_(daemon->itc))
     {
       event.events = EPOLLIN;
@@ -4755,7 +4771,6 @@ setup_epoll_to_listen (struct MHD_Daemon *daemon)
           return MHD_NO;
         }
     }
-  daemon->listen_socket_in_epoll = MHD_YES;
   return MHD_YES;
 }
 #endif
@@ -4789,7 +4804,7 @@ MHD_start_daemon_va (unsigned int flags,
 {
   const MHD_SCKT_OPT_BOOL_ on = 1;
   struct MHD_Daemon *daemon;
-  MHD_socket socket_fd;
+  MHD_socket listen_fd;
   struct sockaddr_in servaddr4;
 #if HAVE_INET6
   struct sockaddr_in6 servaddr6;
@@ -4887,7 +4902,7 @@ MHD_start_daemon_va (unsigned int flags,
                            NULL);
     }
 #endif /* HTTPS_SUPPORT */
-  daemon->socket_fd = MHD_INVALID_SOCKET;
+  daemon->listen_fd = MHD_INVALID_SOCKET;
   daemon->listening_address_reuse = 0;
   daemon->options = flags;
   daemon->port = port;
@@ -5052,12 +5067,12 @@ MHD_start_daemon_va (unsigned int flags,
       goto free_and_fail;
     }
 #endif
-  if ( (MHD_INVALID_SOCKET == daemon->socket_fd) &&
+  if ( (MHD_INVALID_SOCKET == daemon->listen_fd) &&
        (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) )
     {
       /* try to open listen socket */
-      socket_fd = MHD_socket_create_listen_(flags & MHD_USE_IPv6);
-      if (MHD_INVALID_SOCKET == socket_fd)
+      listen_fd = MHD_socket_create_listen_(flags & MHD_USE_IPv6);
+      if (MHD_INVALID_SOCKET == listen_fd)
        {
 #ifdef HAVE_MESSAGES
           MHD_DLOG (daemon,
@@ -5075,7 +5090,7 @@ MHD_start_daemon_va (unsigned int flags,
            * on non-W32 platforms, and do not fail if it doesn't work.
            * Don't use it on W32, because on W32 it will allow multiple
            * bind to the same address:port, like SO_REUSEPORT on others. */
-          if (0 > setsockopt (socket_fd,
+          if (0 > setsockopt (listen_fd,
                               SOL_SOCKET,
                               SO_REUSEADDR,
                               (void*)&on, sizeof (on)))
@@ -5094,7 +5109,7 @@ MHD_start_daemon_va (unsigned int flags,
 #ifndef _WIN32
           /* Use SO_REUSEADDR on non-W32 platforms, and do not fail if
            * it doesn't work. */
-          if (0 > setsockopt (socket_fd,
+          if (0 > setsockopt (listen_fd,
                               SOL_SOCKET,
                               SO_REUSEADDR,
                               (void*)&on, sizeof (on)))
@@ -5112,7 +5127,7 @@ MHD_start_daemon_va (unsigned int flags,
           /* SO_REUSEADDR on W32 has the same semantics
              as SO_REUSEPORT on BSD/Linux */
 #if defined(_WIN32) || defined(SO_REUSEPORT)
-          if (0 > setsockopt (socket_fd,
+          if (0 > setsockopt (listen_fd,
                               SOL_SOCKET,
 #ifndef _WIN32
                               SO_REUSEPORT,
@@ -5150,7 +5165,7 @@ MHD_start_daemon_va (unsigned int flags,
 #if (defined(_WIN32) && defined(SO_EXCLUSIVEADDRUSE)) || \
     (defined(__sun) && defined(SO_EXCLBIND))
 #ifdef SO_EXCLUSIVEADDRUSE
-          if (0 > setsockopt (socket_fd,
+          if (0 > setsockopt (listen_fd,
                               SOL_SOCKET,
 #ifdef SO_EXCLUSIVEADDRUSE
                               SO_EXCLUSIVEADDRUSE,
@@ -5213,7 +5228,7 @@ MHD_start_daemon_va (unsigned int flags,
              servaddr = (struct sockaddr *) &servaddr4;
            }
        }
-      daemon->socket_fd = socket_fd;
+      daemon->listen_fd = listen_fd;
 
       if (0 != (flags & MHD_USE_IPv6))
        {
@@ -5225,7 +5240,7 @@ MHD_start_daemon_va (unsigned int flags,
             your IPv6 socket may then also bind against IPv4 anyway... */
          const MHD_SCKT_OPT_BOOL_ v6_only =
             (MHD_USE_DUAL_STACK != (flags & MHD_USE_DUAL_STACK));
-         if (0 > setsockopt (socket_fd,
+         if (0 > setsockopt (listen_fd,
                               IPPROTO_IPV6, IPV6_V6ONLY,
                               (const void *) &v6_only,
                               sizeof (v6_only)))
@@ -5239,7 +5254,7 @@ MHD_start_daemon_va (unsigned int flags,
 #endif
 #endif
        }
-      if (-1 == bind (socket_fd, servaddr, addrlen))
+      if (-1 == bind (listen_fd, servaddr, addrlen))
        {
 #ifdef HAVE_MESSAGES
           MHD_DLOG (daemon,
@@ -5247,7 +5262,7 @@ MHD_start_daemon_va (unsigned int flags,
                     (unsigned int) port,
                     MHD_socket_last_strerr_ ());
 #endif
-         MHD_socket_close_chk_ (socket_fd);
+         MHD_socket_close_chk_ (listen_fd);
          goto free_and_fail;
        }
 #ifdef TCP_FASTOPEN
@@ -5255,7 +5270,7 @@ MHD_start_daemon_va (unsigned int flags,
       {
         if (0 == daemon->fastopen_queue_size)
           daemon->fastopen_queue_size = MHD_TCP_FASTOPEN_QUEUE_SIZE_DEFAULT;
-        if (0 != setsockopt (socket_fd,
+        if (0 != setsockopt (listen_fd,
                              IPPROTO_TCP,
                              TCP_FASTOPEN,
                              &daemon->fastopen_queue_size,
@@ -5269,7 +5284,7 @@ MHD_start_daemon_va (unsigned int flags,
         }
       }
 #endif
-      if (listen (socket_fd,
+      if (listen (listen_fd,
                   daemon->listen_backlog_size) < 0)
        {
 #ifdef HAVE_MESSAGES
@@ -5277,16 +5292,16 @@ MHD_start_daemon_va (unsigned int flags,
                     _("Failed to listen for connections: %s\n"),
                     MHD_socket_last_strerr_ ());
 #endif
-         MHD_socket_close_chk_ (socket_fd);
+         MHD_socket_close_chk_ (listen_fd);
          goto free_and_fail;
        }
     }
   else
     {
-      socket_fd = daemon->socket_fd;
+      listen_fd = daemon->listen_fd;
     }
 
-  if (!MHD_socket_nonblocking_ (socket_fd))
+  if (!MHD_socket_nonblocking_ (listen_fd))
     {
 #ifdef HAVE_MESSAGES
       MHD_DLOG (daemon,
@@ -5299,21 +5314,21 @@ MHD_start_daemon_va (unsigned int flags,
            /* Accept must be non-blocking. Multiple children may wake up
             * to handle a new connection, but only one will win the race.
             * The others must immediately return. */
-          MHD_socket_close_chk_ (socket_fd);
+          MHD_socket_close_chk_ (listen_fd);
           goto free_and_fail;
         }
     }
-  if ( (!MHD_SCKT_FD_FITS_FDSET_(socket_fd,
+  if ( (!MHD_SCKT_FD_FITS_FDSET_(listen_fd,
                                  NULL)) &&
        (0 == (flags & (MHD_USE_POLL | MHD_USE_EPOLL)) ) )
     {
 #ifdef HAVE_MESSAGES
       MHD_DLOG (daemon,
                 _("Socket descriptor larger than FD_SETSIZE: %d > %d\n"),
-                socket_fd,
+                listen_fd,
                 FD_SETSIZE);
 #endif
-      MHD_socket_close_chk_ (socket_fd);
+      MHD_socket_close_chk_ (listen_fd);
       goto free_and_fail;
     }
 
@@ -5341,8 +5356,8 @@ MHD_start_daemon_va (unsigned int flags,
       MHD_DLOG (daemon,
                 _("MHD failed to initialize IP connection limit mutex\n"));
 #endif
-      if (MHD_INVALID_SOCKET != socket_fd)
-        MHD_socket_close_chk_ (socket_fd);
+      if (MHD_INVALID_SOCKET != listen_fd)
+        MHD_socket_close_chk_ (listen_fd);
       goto free_and_fail;
     }
   if (! MHD_mutex_init_ (&daemon->cleanup_connection_mutex))
@@ -5352,8 +5367,8 @@ MHD_start_daemon_va (unsigned int flags,
                 _("MHD failed to initialize IP connection limit mutex\n"));
 #endif
       MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex);
-      if (MHD_INVALID_SOCKET != socket_fd)
-        MHD_socket_close_chk_ (socket_fd);
+      if (MHD_INVALID_SOCKET != listen_fd)
+        MHD_socket_close_chk_ (listen_fd);
       goto free_and_fail;
     }
 
@@ -5366,8 +5381,8 @@ MHD_start_daemon_va (unsigned int flags,
       MHD_DLOG (daemon,
                _("Failed to initialize TLS support\n"));
 #endif
-      if (MHD_INVALID_SOCKET != socket_fd)
-        MHD_socket_close_chk_ (socket_fd);
+      if (MHD_INVALID_SOCKET != listen_fd)
+        MHD_socket_close_chk_ (listen_fd);
       MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex);
       MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex);
       goto free_and_fail;
@@ -5390,8 +5405,8 @@ MHD_start_daemon_va (unsigned int flags,
 #endif
       MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex);
       MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex);
-      if (MHD_INVALID_SOCKET != socket_fd)
-        MHD_socket_close_chk_ (socket_fd);
+      if (MHD_INVALID_SOCKET != listen_fd)
+        MHD_socket_close_chk_ (listen_fd);
       goto free_and_fail;
     }
   if ( (daemon->worker_pool_size > 0) &&
@@ -5507,8 +5522,8 @@ thread_failed:
      MHD_USE_INTERNAL_POLLING_THREAD mode. */
   if (0 == i)
     {
-      if (MHD_INVALID_SOCKET != socket_fd)
-        MHD_socket_close_chk_ (socket_fd);
+      if (MHD_INVALID_SOCKET != listen_fd)
+        MHD_socket_close_chk_ (listen_fd);
       MHD_mutex_destroy_chk_ (&daemon->cleanup_connection_mutex);
       MHD_mutex_destroy_chk_ (&daemon->per_ip_connection_mutex);
       if (NULL != daemon->worker_pool)
@@ -5529,14 +5544,14 @@ thread_failed:
      indicate failure */
 #ifdef EPOLL_SUPPORT
 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
-  if (MHD_YES == daemon->upgrade_fd_in_epoll)
+  if (daemon->upgrade_fd_in_epoll)
     {
       if (0 != epoll_ctl (daemon->epoll_fd,
                          EPOLL_CTL_DEL,
                          daemon->epoll_upgrade_fd,
                          NULL))
        MHD_PANIC (_("Failed to remove FD from epoll set\n"));
-      daemon->upgrade_fd_in_epoll = MHD_NO;
+      daemon->upgrade_fd_in_epoll = false;
     }
 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
   if (-1 != daemon->epoll_fd)
@@ -5591,7 +5606,7 @@ close_all_connections (struct MHD_Daemon *daemon)
          with chance to detect that application is done. */
       process_urh (urh);
       MHD_connection_finish_forward_ (urh->connection);
-      urh->clean_ready = MHD_YES;
+      urh->clean_ready = true;
       /* Resuming will move connection to cleanup list. */
       MHD_resume_connection(urh->connection);
     }
@@ -5622,7 +5637,7 @@ close_all_connections (struct MHD_Daemon *daemon)
 #ifdef HTTPS_SUPPORT
           else if (used_tls &&
                    used_thr_p_c &&
-                   (MHD_NO == susp->urh->clean_ready) )
+                   (! susp->urh->clean_ready) )
             shutdown (urh->app.socket,
                       SHUT_RDWR); /* Wake thread by shutdown of app socket. */
 #endif /* HTTPS_SUPPORT */
@@ -5728,7 +5743,7 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
     resume_suspended_connections (daemon);
 
   daemon->shutdown = true;
-  fd = daemon->socket_fd;
+  fd = daemon->listen_fd;
 
   if (0 != (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD))
     {
@@ -5750,7 +5765,8 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
                 {
                   /* fd might be MHD_INVALID_SOCKET here due to 
'MHD_quiesce_daemon' */
                   /* No problem if shutdown will be called several times for 
the same socket. */
-                    (void) shutdown (fd, SHUT_RDWR);
+                    (void) shutdown (fd,
+                                     SHUT_RDWR);
                 }
 #endif
             }
@@ -5785,8 +5801,10 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
           else
             {
               /* fd might be MHD_INVALID_SOCKET here due to 
'MHD_quiesce_daemon' */
-              if (MHD_INVALID_SOCKET != fd)
-                (void) shutdown (fd, SHUT_RDWR);
+              if ( (MHD_INVALID_SOCKET != fd) &&
+                   (! daemon->was_quiesced) )
+                (void) shutdown (fd,
+                                 SHUT_RDWR);
             }
 #endif
           if (! MHD_join_thread_ (daemon->pid))
@@ -5801,7 +5819,8 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
       close_all_connections (daemon);
     }
 
-  if (MHD_INVALID_SOCKET != fd)
+  if ( (MHD_INVALID_SOCKET != fd) &&
+       (! daemon->was_quiesced) )
     MHD_socket_close_chk_ (fd);
 
   if (MHD_ITC_IS_VALID_ (daemon->itc))
@@ -5820,10 +5839,10 @@ MHD_stop_daemon (struct MHD_Daemon *daemon)
 
   /* TLS clean up */
 #ifdef HTTPS_SUPPORT
-  if (MHD_YES == daemon->have_dhparams)
+  if (daemon->have_dhparams)
     {
       gnutls_dh_params_deinit (daemon->https_mem_dhparams);
-      daemon->have_dhparams = MHD_NO;
+      daemon->have_dhparams = false;
     }
   if (0 != (daemon->options & MHD_USE_TLS))
     {
@@ -5867,7 +5886,7 @@ MHD_get_daemon_info (struct MHD_Daemon *daemon,
     case MHD_DAEMON_INFO_MAC_KEY_SIZE:
       return NULL; /* no longer supported */
     case MHD_DAEMON_INFO_LISTEN_FD:
-      return (const union MHD_DaemonInfo *) &daemon->socket_fd;
+      return (const union MHD_DaemonInfo *) &daemon->listen_fd;
 #ifdef EPOLL_SUPPORT
     case MHD_DAEMON_INFO_EPOLL_FD:
       return (const union MHD_DaemonInfo *) &daemon->epoll_fd;
diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h
index 5d61705a..95163461 100644
--- a/src/microhttpd/internal.h
+++ b/src/microhttpd/internal.h
@@ -788,7 +788,7 @@ struct MHD_Connection
    * flag will determine if we call the #MHD_OPTION_NOTIFY_COMPLETED
    * handler when the connection closes down).
    */
-  int client_aware;
+  bool client_aware;
 
   /**
    * Socket for this connection.  Set to #MHD_INVALID_SOCKET if
@@ -937,7 +937,7 @@ struct MHD_Connection
   /**
    * TLS layer was shut down?
    */
-  int tls_closed;
+  bool tls_closed;
 #endif /* HTTPS_SUPPORT */
 
   /**
@@ -1098,27 +1098,27 @@ struct MHD_UpgradeResponseHandle
   volatile bool was_closed;
 
   /**
-   * Set to #MHD_YES if connection is ready for cleanup.
+   * Set to true if connection is ready for cleanup.
    *
    * In TLS mode functions #MHD_connection_finish_forward_() must
-   * be called before setting this flag to #MHD_YES.
+   * be called before setting this flag to true.
    *
-   * In thread-per-connection mode #MHD_YES in this flag means
+   * In thread-per-connection mode, true in this flag means
    * that connection's thread exited or about to exit and will
    * not use MHD_Connection::urh data anymore.
    *
-   * In any mode #MHD_YES in this flag also means that
+   * In any mode true in this flag also means that
    * MHD_Connection::urh data will not be used for socketpair
    * forwarding and forwarding itself is finished.
    *
    * When BOTH @e was_closed (changed by command from application)
    * AND @e clean_ready (changed internally by MHD) are set to
-   * #MHD_YES, function #MHD_resume_connection() will move this
+   * true, function #MHD_resume_connection() will move this
    * connection to cleanup list.
    * @remark This flag could be changed from thread that process
    * connection's recv(), send() and response.
    */
-  int clean_ready;
+  bool clean_ready;
 };
 #endif /* UPGRADE_SUPPORT */
 
@@ -1374,7 +1374,7 @@ struct MHD_Daemon
   /**
    * Listen socket.
    */
-  MHD_socket socket_fd;
+  MHD_socket listen_fd;
 
   /**
    * Whether to allow/disallow/ignore reuse of listening address.
@@ -1394,10 +1394,10 @@ struct MHD_Daemon
   int epoll_fd;
 
   /**
-   * #MHD_YES if the listen socket is in the 'epoll' set,
-   * #MHD_NO if not.
+   * true if the listen socket is in the 'epoll' set,
+   * false if not.
    */
-  int listen_socket_in_epoll;
+  bool listen_socket_in_epoll;
 
 #if defined(HTTPS_SUPPORT) && defined(UPGRADE_SUPPORT)
   /**
@@ -1407,10 +1407,10 @@ struct MHD_Daemon
   int epoll_upgrade_fd;
 
   /**
-   * #MHD_YES if @e epoll_upgrade_fd is in the 'epoll' set,
-   * #MHD_NO if not.
+   * true if @e epoll_upgrade_fd is in the 'epoll' set,
+   * false if not.
    */
-  int upgrade_fd_in_epoll;
+  bool upgrade_fd_in_epoll;
 #endif /* HTTPS_SUPPORT && UPGRADE_SUPPORT */
 
 #endif
@@ -1426,6 +1426,13 @@ struct MHD_Daemon
   volatile bool shutdown;
 
   /**
+   * Has this deamon been quiesced via #MHD_quiesce_daemon()?
+   * If so, we should no longer use the @e listen_fd (including
+   * removing it from the @e epoll_fd when possible).
+   */
+  volatile bool was_quiesced;
+
+  /**
    * Did we hit some system or process-wide resource limit while
    * trying to accept() the last time? If so, we don't accept new
    * connections until we close an existing one.  This effectively
@@ -1543,9 +1550,9 @@ struct MHD_Daemon
   gnutls_dh_params_t https_mem_dhparams;
 
   /**
-   * #MHD_YES if we have initialized @e https_mem_dhparams.
+   * true if we have initialized @e https_mem_dhparams.
    */
-  int have_dhparams;
+  bool have_dhparams;
 
   /**
    * For how many connections do we have 'tls_read_ready' set to MHD_YES?
diff --git a/src/microhttpd/response.c b/src/microhttpd/response.c
index d9055416..a0897d8b 100644
--- a/src/microhttpd/response.c
+++ b/src/microhttpd/response.c
@@ -1,6 +1,6 @@
 /*
      This file is part of libmicrohttpd
-     Copyright (C) 2007, 2009, 2010, 2016 Daniel Pittman and Christian Grothoff
+     Copyright (C) 2007, 2009, 2010, 2016, 2017 Daniel Pittman and Christian 
Grothoff
 
      This library is free software; you can redistribute it and/or
      modify it under the terms of the GNU Lesser General Public
@@ -912,10 +912,10 @@ MHD_response_execute_upgrade_ (struct MHD_Response 
*response,
       urh->app.socket = MHD_INVALID_SOCKET;
       urh->mhd.socket = MHD_INVALID_SOCKET;
       /* Non-TLS connection do not hold any additional resources. */
-      urh->clean_ready = MHD_YES;
+      urh->clean_ready = true;
     }
 #else  /* ! HTTPS_SUPPORT */
-  urh->clean_ready = MHD_YES;
+  urh->clean_ready = true;
 #endif /* ! HTTPS_SUPPORT */
   connection->urh = urh;
   /* As far as MHD's event loops are concerned, this connection is

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

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