aboutsummaryrefslogtreecommitdiff
path: root/src/lib/request_resume.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/request_resume.c')
-rw-r--r--src/lib/request_resume.c121
1 files changed, 121 insertions, 0 deletions
diff --git a/src/lib/request_resume.c b/src/lib/request_resume.c
index fcb9a5a3..b632d200 100644
--- a/src/lib/request_resume.c
+++ b/src/lib/request_resume.c
@@ -62,4 +62,125 @@ MHD_request_resume (struct MHD_Request *request)
62 } 62 }
63} 63}
64 64
65
66/**
67 * Run through the suspended connections and move any that are no
68 * longer suspended back to the active state.
69 * @remark To be called only from thread that process
70 * daemon's select()/poll()/etc.
71 *
72 * @param daemon daemon context
73 * @return true if a connection was actually resumed
74 */
75bool
76MHD_resume_suspended_connections_ (struct MHD_Daemon *daemon)
77{
78 struct MHD_Connection *pos;
79 struct MHD_Connection *prev = NULL;
80 bool ret;
81 const bool used_thr_p_c = (MHD_TM_THREAD_PER_CONNECTION == daemon->threading_model);
82
83 mhd_assert (NULL == daemon->worker_pool);
84 ret = false;
85 MHD_mutex_lock_chk_ (&daemon->cleanup_connection_mutex);
86
87 if (daemon->resuming)
88 {
89 prev = daemon->suspended_connections_tail;
90 /* During shutdown check for resuming is forced. */
91 mhd_assert((NULL != prev) || (daemon->shutdown));
92 }
93
94 daemon->resuming = false;
95
96 while (NULL != (pos = prev))
97 {
98#ifdef UPGRADE_SUPPORT
99 struct MHD_UpgradeResponseHandle * const urh = pos->request.urh;
100#else /* ! UPGRADE_SUPPORT */
101 static const void * const urh = NULL;
102#endif /* ! UPGRADE_SUPPORT */
103 prev = pos->prev;
104 if ( (! pos->resuming)
105#ifdef UPGRADE_SUPPORT
106 || ( (NULL != urh) &&
107 ( (! urh->was_closed) ||
108 (! urh->clean_ready) ) )
109#endif /* UPGRADE_SUPPORT */
110 )
111 continue;
112 ret = true;
113 mhd_assert (pos->suspended);
114 DLL_remove (daemon->suspended_connections_head,
115 daemon->suspended_connections_tail,
116 pos);
117 pos->suspended = false;
118 if (NULL == urh)
119 {
120 DLL_insert (daemon->connections_head,
121 daemon->connections_tail,
122 pos);
123 if (! used_thr_p_c)
124 {
125 /* Reset timeout timer on resume. */
126 if (0 != pos->connection_timeout)
127 pos->last_activity = MHD_monotonic_sec_counter();
128
129 if (pos->connection_timeout == daemon->connection_default_timeout)
130 XDLL_insert (daemon->normal_timeout_head,
131 daemon->normal_timeout_tail,
132 pos);
133 else
134 XDLL_insert (daemon->manual_timeout_head,
135 daemon->manual_timeout_tail,
136 pos);
137 }
138#ifdef EPOLL_SUPPORT
139 if (MHD_ELS_EPOLL == daemon->event_loop_syscall)
140 {
141 if (0 != (pos->epoll_state & MHD_EPOLL_STATE_IN_EREADY_EDLL))
142 MHD_PANIC ("Resumed connection was already in EREADY set\n");
143 /* we always mark resumed connections as ready, as we
144 might have missed the edge poll event during suspension */
145 EDLL_insert (daemon->eready_head,
146 daemon->eready_tail,
147 pos);
148 pos->epoll_state |= MHD_EPOLL_STATE_IN_EREADY_EDLL | \
149 MHD_EPOLL_STATE_READ_READY | MHD_EPOLL_STATE_WRITE_READY;
150 pos->epoll_state &= ~MHD_EPOLL_STATE_SUSPENDED;
151 }
152#endif
153 }
154#ifdef UPGRADE_SUPPORT
155 else
156 {
157 /* Data forwarding was finished (for TLS connections) AND
158 * application was closed upgraded connection.
159 * Insert connection into cleanup list. */
160 DLL_insert (daemon->cleanup_head,
161 daemon->cleanup_tail,
162 pos);
163
164 }
165#endif /* UPGRADE_SUPPORT */
166 pos->resuming = false;
167 }
168 MHD_mutex_unlock_chk_ (&daemon->cleanup_connection_mutex);
169 if ( (used_thr_p_c) &&
170 (ret) )
171 { /* Wake up suspended connections. */
172 if (! MHD_itc_activate_(daemon->itc,
173 "w"))
174 {
175#ifdef HAVE_MESSAGES
176 MHD_DLOG (daemon,
177 MHD_SC_ITC_USE_FAILED,
178 _("Failed to signal resume of connection via inter-thread communication channel."));
179#endif
180 }
181 }
182 return ret;
183}
184
185
65/* end of request_resume.c */ 186/* end of request_resume.c */