aboutsummaryrefslogtreecommitdiff
path: root/src/lib/action_suspend.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/action_suspend.c')
-rw-r--r--src/lib/action_suspend.c132
1 files changed, 132 insertions, 0 deletions
diff --git a/src/lib/action_suspend.c b/src/lib/action_suspend.c
new file mode 100644
index 00000000..8327992d
--- /dev/null
+++ b/src/lib/action_suspend.c
@@ -0,0 +1,132 @@
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
20/**
21 * @file lib/action_suspend.c
22 * @brief implementation of MHD_action_suspend()
23 * @author Christian Grothoff
24 */
25#include "internal.h"
26
27
28/**
29 * The suspend action is being run. Suspend handling
30 * of the given request.
31 *
32 * @param cls NULL
33 * @param request the request to apply the action to
34 */
35static void
36suspend_action (void *cls,
37 struct MHD_Request *request)
38{
39 struct MHD_Daemon *daemon = connection->daemon;
40
41 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
42 if (connection->resuming)
43 {
44 /* suspending again while we didn't even complete resuming yet */
45 connection->resuming = false;
46 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
47 return;
48 }
49 if (0 == (daemon->options & MHD_USE_THREAD_PER_CONNECTION))
50 {
51 if (connection->connection_timeout == daemon->connection_timeout)
52 XDLL_remove (daemon->normal_timeout_head,
53 daemon->normal_timeout_tail,
54 connection);
55 else
56 XDLL_remove (daemon->manual_timeout_head,
57 daemon->manual_timeout_tail,
58 connection);
59 }
60 DLL_remove (daemon->connections_head,
61 daemon->connections_tail,
62 connection);
63 mhd_assert (! connection->suspended);
64 DLL_insert (daemon->suspended_connections_head,
65 daemon->suspended_connections_tail,
66 connection);
67 connection->suspended = true;
68#ifdef EPOLL_SUPPORT
69 if (MHD_ELS_EPOLL == daemon->event_loop_syscall)
70 {
71 if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
72 {
73 EDLL_remove (daemon->eready_head,
74 daemon->eready_tail,
75 connection);
76 connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EREADY_EDLL;
77 }
78 if (0 != (connection->epoll_state & MHD_EPOLL_STATE_IN_EPOLL_SET))
79 {
80 if (0 != epoll_ctl (daemon->epoll_fd,
81 EPOLL_CTL_DEL,
82 connection->socket_fd,
83 NULL))
84 MHD_PANIC (_("Failed to remove FD from epoll set\n"));
85 connection->epoll_state &= ~MHD_EPOLL_STATE_IN_EPOLL_SET;
86 }
87 connection->epoll_state |= MHD_EPOLL_STATE_SUSPENDED;
88 }
89#endif
90 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
91}
92
93
94/**
95 * Suspend handling of network data for a given request. This can
96 * be used to dequeue a request from MHD's event loop for a while.
97 *
98 * If you use this API in conjunction with a internal select or a
99 * thread pool, you must set the option #MHD_USE_ITC to
100 * ensure that a resumed request is immediately processed by MHD.
101 *
102 * Suspended requests continue to count against the total number of
103 * requests allowed (per daemon, as well as per IP, if such limits
104 * are set). Suspended requests will NOT time out; timeouts will
105 * restart when the request handling is resumed. While a
106 * request is suspended, MHD will not detect disconnects by the
107 * client.
108 *
109 * The only safe time to suspend a request is from either a
110 * #MHD_RequestHeaderCallback, #MHD_UploadCallback, or a
111 * #MHD_RequestfetchResponseCallback. Suspending a request
112 * at any other time will cause an assertion failure.
113 *
114 * Finally, it is an API violation to call #MHD_daemon_stop() while
115 * having suspended requests (this will at least create memory and
116 * socket leaks or lead to undefined behavior). You must explicitly
117 * resume all requests before stopping the daemon.
118 *
119 * @return action to cause a request to be suspended.
120 */
121struct MHD_Action *
122MHD_action_suspend (void)
123{
124 static MHD_Action suspend = {
125 .action = &suspend_action,
126 .action_cls = NULL
127 };
128
129 return &suspend;
130}
131
132/* end of action_suspend.c */