GNU libmicrohttpd  0.9.72
daemon_quiesce.c
Go to the documentation of this file.
1 /*
2  This file is part of libmicrohttpd
3  Copyright (C) 2007-2018 Daniel Pittman and Christian Grothoff
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Lesser General Public
7  License as published by the Free Software Foundation; either
8  version 2.1 of the License, or (at your option) any later version.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public
16  License along with this library; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19 
25 #include "internal.h"
26 
27 
50 {
51  MHD_socket listen_socket;
52 
53  if (MHD_INVALID_SOCKET == (listen_socket = daemon->listen_socket))
54  return MHD_INVALID_SOCKET;
55  if ( (daemon->disable_itc) &&
56  (MHD_TM_EXTERNAL_EVENT_LOOP != daemon->threading_mode) )
57  {
58 #ifdef HAVE_MESSAGES
59  MHD_DLOG (daemon,
60  MHD_SC_SYSCALL_QUIESCE_REQUIRES_ITC,
61  "Using MHD_quiesce_daemon in this mode requires ITC.\n");
62 #endif
63  return MHD_INVALID_SOCKET;
64  }
65 
66  if (NULL != daemon->worker_pool)
67  {
68  unsigned int i;
69 
70  for (i = 0; i < daemon->worker_pool_size; i++)
71  {
72  struct MHD_Daemon *worker = &daemon->worker_pool[i];
73 
74  worker->was_quiesced = true;
75 #ifdef EPOLL_SUPPORT
76  if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) &&
77  (-1 != worker->epoll_fd) &&
78  (worker->listen_socket_in_epoll) )
79  {
80  if (0 != epoll_ctl (worker->epoll_fd,
81  EPOLL_CTL_DEL,
83  NULL))
84  MHD_PANIC (_ ("Failed to remove listen FD from epoll set.\n"));
85  worker->listen_socket_in_epoll = false;
86  }
87  else
88 #endif
89  if (MHD_ITC_IS_VALID_ (worker->itc))
90  {
91  if (! MHD_itc_activate_ (worker->itc,
92  "q"))
93  MHD_PANIC (_ (
94  "Failed to signal quiesce via inter-thread communication channel.\n"));
95  }
96  }
97  daemon->was_quiesced = true;
98 #ifdef EPOLL_SUPPORT
99  if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) &&
100  (-1 != daemon->epoll_fd) &&
101  (daemon->listen_socket_in_epoll) )
102  {
103  if (0 != epoll_ctl (daemon->epoll_fd,
104  EPOLL_CTL_DEL,
106  NULL))
107  MHD_PANIC ("Failed to remove listen FD from epoll set.\n");
108  daemon->listen_socket_in_epoll = false;
109  }
110 #endif
111  }
112 
113  if ( (MHD_ITC_IS_VALID_ (daemon->itc)) &&
114  (! MHD_itc_activate_ (daemon->itc,
115  "q")) )
116  MHD_PANIC (_ (
117  "Failed to signal quiesce via inter-thread communication channel.\n"));
118 
119  /* FIXME: we might want some bi-directional communication here
120  (in both the thread-pool and single-thread case!)
121  to be sure that the threads have stopped using the listen
122  socket, otherwise there is still the possibility of a race
123  between a thread accept()ing and the caller closing and
124  re-binding the socket. */return listen_socket;
125 }
126 
127 
128 /* end of daemon_quiesce.c */
MHD_socket MHD_daemon_quiesce(struct MHD_Daemon *daemon)
#define MHD_PANIC(msg)
Definition: internal.h:69
#define NULL
Definition: reason_phrase.c:30
#define _(String)
Definition: mhd_options.h:42
internal shared structures
int MHD_socket
Definition: microhttpd.h:196
#define MHD_INVALID_SOCKET
Definition: microhttpd.h:197
bool was_quiesced
Definition: internal.h:1505
unsigned int worker_pool_size
Definition: internal.h:1366
struct MHD_itc_ itc
Definition: internal.h:1410
bool disable_itc
Definition: internal.h:1462
enum MHD_EventLoopSyscall event_loop_syscall
Definition: internal.h:1436
struct MHD_Daemon * worker_pool
Definition: internal.h:1073
MHD_socket listen_socket
Definition: internal.h:1377
enum MHD_ThreadingMode threading_mode
Definition: internal.h:1417