fcgi_conn_restart_reading(fconn, 0);
}
+/* resume each fstrm eligible for sending in list head <head> */
+static void fcgi_resume_each_sending_fstrm(struct fcgi_conn *fconn, struct list *head)
+{
+ struct fcgi_strm *fstrm, *fstrm_back;
+
+ TRACE_ENTER(FCGI_EV_FCONN_SEND|FCGI_EV_FCONN_WAKE, fconn->conn);
+
+ list_for_each_entry_safe(fstrm, fstrm_back, &fconn->send_list, send_list) {
+ if (fconn->state == FCGI_CS_CLOSED || fconn->flags & FCGI_CF_MUX_BLOCK_ANY)
+ break;
+
+ fstrm->flags &= ~FCGI_SF_BLK_ANY;
+
+ if (fstrm->flags & FCGI_SF_NOTIFIED)
+ continue;
+
+ /* If the sender changed his mind and unsubscribed, let's just
+ * remove the stream from the send_list.
+ */
+ if (!(fstrm->flags & (FCGI_SF_WANT_SHUTR|FCGI_SF_WANT_SHUTW)) &&
+ (!fstrm->subs || !(fstrm->subs->events & SUB_RETRY_SEND))) {
+ LIST_DEL_INIT(&fstrm->send_list);
+ continue;
+ }
+
+ fcgi_strm_notify_send(fstrm);
+ }
+
+ TRACE_LEAVE(FCGI_EV_FCONN_SEND|FCGI_EV_FCONN_WAKE, fconn->conn);
+}
+
/* process Tx records from streams to be multiplexed. Returns > 0 if it reached
* the end.
*/
static int fcgi_process_mux(struct fcgi_conn *fconn)
{
- struct fcgi_strm *fstrm, *fstrm_back;
-
TRACE_ENTER(FCGI_EV_FCONN_WAKE, fconn->conn);
if (unlikely(fconn->state < FCGI_CS_RECORD_H)) {
}
mux:
- list_for_each_entry_safe(fstrm, fstrm_back, &fconn->send_list, send_list) {
- if (fconn->state == FCGI_CS_CLOSED || fconn->flags & FCGI_CF_MUX_BLOCK_ANY)
- break;
-
- if (fstrm->flags & FCGI_SF_NOTIFIED)
- continue;
-
- /* If the sender changed his mind and unsubscribed, let's just
- * remove the stream from the send_list.
- */
- if (!(fstrm->flags & (FCGI_SF_WANT_SHUTR|FCGI_SF_WANT_SHUTW)) &&
- (!fstrm->subs || !(fstrm->subs->events & SUB_RETRY_SEND))) {
- LIST_DEL_INIT(&fstrm->send_list);
- continue;
- }
-
- if (fstrm->subs && fstrm->subs->events & SUB_RETRY_SEND) {
- TRACE_POINT(FCGI_EV_STRM_WAKE, fconn->conn, fstrm);
- fstrm->flags &= ~FCGI_SF_BLK_ANY;
- fstrm->flags |= FCGI_SF_NOTIFIED;
- tasklet_wakeup(fstrm->subs->tasklet);
- fstrm->subs->events &= ~SUB_RETRY_SEND;
- if (!fstrm->subs->events)
- fstrm->subs = NULL;
- } else {
- /* it's the shut request that was queued */
- TRACE_POINT(FCGI_EV_STRM_WAKE, fconn->conn, fstrm);
- tasklet_wakeup(fstrm->shut_tl);
- }
- }
+ fcgi_resume_each_sending_fstrm(fconn, &fconn->send_list);
fail:
if (fconn->state == FCGI_CS_CLOSED) {
/* We're not full anymore, so we can wake any task that are waiting
* for us.
*/
- if (!(fconn->flags & (FCGI_CF_MUX_MFULL | FCGI_CF_DEM_MROOM)) && fconn->state >= FCGI_CS_RECORD_H) {
- struct fcgi_strm *fstrm, *fstrm_back;
-
- list_for_each_entry_safe(fstrm, fstrm_back, &fconn->send_list, send_list) {
- if (fconn->state == FCGI_CS_CLOSED || fconn->flags & FCGI_CF_MUX_BLOCK_ANY)
- break;
-
- if (fstrm->flags & FCGI_SF_NOTIFIED)
- continue;
+ if (!(fconn->flags & (FCGI_CF_MUX_MFULL | FCGI_CF_DEM_MROOM)) && fconn->state >= FCGI_CS_RECORD_H)
+ fcgi_resume_each_sending_fstrm(fconn, &fconn->send_list);
- /* If the sender changed his mind and unsubscribed, let's just
- * remove the stream from the send_list.
- */
- if (!(fstrm->flags & (FCGI_SF_WANT_SHUTR|FCGI_SF_WANT_SHUTW)) &&
- (!fstrm->subs || !(fstrm->subs->events & SUB_RETRY_SEND))) {
- LIST_DEL_INIT(&fstrm->send_list);
- continue;
- }
-
- if (fstrm->subs && fstrm->subs->events & SUB_RETRY_SEND) {
- TRACE_DEVEL("waking up pending stream", FCGI_EV_FCONN_SEND|FCGI_EV_STRM_WAKE, conn, fstrm);
- fstrm->flags &= ~FCGI_SF_BLK_ANY;
- fstrm->flags |= FCGI_SF_NOTIFIED;
- tasklet_wakeup(fstrm->subs->tasklet);
- fstrm->subs->events &= ~SUB_RETRY_SEND;
- if (!fstrm->subs->events)
- fstrm->subs = NULL;
- } else {
- /* it's the shut request that was queued */
- TRACE_POINT(FCGI_EV_STRM_WAKE, fconn->conn, fstrm);
- tasklet_wakeup(fstrm->shut_tl);
- }
- }
- }
/* We're done, no more to send */
if (!br_data(fconn->mbuf)) {
TRACE_DEVEL("leaving with everything sent", FCGI_EV_FCONN_SEND, conn);