diff options
Diffstat (limited to 'src/lib/request_resume.c')
-rw-r--r-- | src/lib/request_resume.c | 121 |
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 | */ | ||
75 | bool | ||
76 | MHD_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 */ |