GNU libmicrohttpd  0.9.61
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_model) )
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 (_("Failed to signal quiesce via inter-thread communication channel"));
94  }
95  }
96  daemon->was_quiesced = true;
97 #ifdef EPOLL_SUPPORT
98  if ( (MHD_ELS_EPOLL == daemon->event_loop_syscall) &&
99  (-1 != daemon->epoll_fd) &&
100  (daemon->listen_socket_in_epoll) )
101  {
102  if (0 != epoll_ctl (daemon->epoll_fd,
103  EPOLL_CTL_DEL,
105  NULL))
106  MHD_PANIC ("Failed to remove listen FD from epoll set\n");
107  daemon->listen_socket_in_epoll = false;
108  }
109 #endif
110  }
111 
112  if ( (MHD_ITC_IS_VALID_(daemon->itc)) &&
113  (! MHD_itc_activate_ (daemon->itc,
114  "q")) )
115  MHD_PANIC (_("Failed to signal quiesce via inter-thread communication channel"));
116 
117  /* FIXME: we might want some bi-directional communication here
118  (in both the thread-pool and single-thread case!)
119  to be sure that the threads have stopped using the listen
120  socket, otherwise there is still the possibility of a race
121  between a thread accept()ing and the caller closing and
122  re-binding the socket. */
123 
124  return listen_socket;
125 }
126 
127 /* end of daemon_quiesce.c */
128 
enum MHD_EventLoopSyscall event_loop_syscall
Definition: internal.h:1433
#define MHD_PANIC(msg)
Definition: internal.h:68
MHD_socket MHD_daemon_quiesce(struct MHD_Daemon *daemon)
int MHD_socket
Definition: microhttpd.h:181
internal shared structures
MHD_socket listen_socket
Definition: internal.h:1374
bool was_quiesced
Definition: internal.h:1502
#define MHD_INVALID_SOCKET
Definition: microhttpd.h:182
unsigned int worker_pool_size
Definition: internal.h:1363
#define NULL
Definition: reason_phrase.c:30
bool disable_itc
Definition: internal.h:1459
struct MHD_itc_ itc
Definition: internal.h:1407
enum MHD_ThreadingModel threading_model
Definition: internal.h:1414
#define _(String)
Definition: mhd_options.h:42
struct MHD_Daemon * worker_pool
Definition: internal.h:1070