int stream_upgrade_from_sc(struct stconn *sc, struct buffer *input);
int stream_set_http_mode(struct stream *s, const struct mux_proto_list *mux_proto);
-/* kill a stream and set the termination flags to <why> (one of SF_ERR_*) */
-void stream_shutdown(struct stream *stream, int why);
+/* shutdown the stream from itself */
+void stream_shutdown_self(struct stream *stream, int why);
void stream_dump_and_crash(enum obj_type *obj, int rate);
void strm_dump_to_buffer(struct buffer *buf, const struct stream *strm, const char *pfx, uint32_t anon_key);
return 0;
}
+/* Wake a stream up for shutdown by sending it an event. The stream must be
+ * locked one way or another so that it cannot leave (i.e. when inspecting
+ * a locked list or under thread isolation). Process_stream() will recognize
+ * the message and complete the job. <why> only supports SF_ERR_DOWN (mapped
+ * to UEVT1) and SF_ERR_KILLED (mapped to UEVT2). Other values will just
+ * trigger TASK_WOKEN_OTHER. The stream handler will first call function
+ * stream_shutdown_self() on wakeup to complete the notification.
+ */
+static inline void stream_shutdown(struct stream *s, int why)
+{
+ task_wakeup(s->task, TASK_WOKEN_OTHER |
+ ((why == SF_ERR_DOWN) ? TASK_F_UEVT1 :
+ (why == SF_ERR_KILLED) ? TASK_F_UEVT2 :
+ 0));
+}
+
int stream_set_timeout(struct stream *s, enum act_timeout_name name, int timeout);
void stream_retnclose(struct stream *s, const struct buffer *msg);
void sess_set_term_flags(struct stream *s);
* nothing too many times, the request and response buffers flags are monitored
* and each function is called only if at least another function has changed at
* least one flag it is interested in.
+ *
+ * This task handler understands a few wake up reasons:
+ * - TASK_WOKEN_MSG forces analysers to be re-evaluated
+ * - TASK_WOKEN_OTHER+TASK_F_UEVT1 shuts the stream down on server down
+ * - TASK_WOKEN_OTHER+TASK_F_UEVT2 shuts the stream down on active kill
+ * - TASK_WOKEN_OTHER alone has no effect
*/
struct task *process_stream(struct task *t, void *context, unsigned int state)
{
activity[tid].stream_calls++;
stream_cond_update_cpu_latency(s);
+ if ((state & TASK_WOKEN_OTHER) && (state & (TASK_F_UEVT1 | TASK_F_UEVT2))) {
+ /* that an instant kill message, the reason is in _UEVT* */
+ stream_shutdown_self(s, (state & TASK_F_UEVT2) ? SF_ERR_KILLED : SF_ERR_DOWN);
+ }
+
req = &s->req;
res = &s->res;
s->flags |= fin;
}
-/* kill a stream and set the termination flags to <why> (one of SF_ERR_*) */
-void stream_shutdown(struct stream *stream, int why)
+/* shutdown the stream from itself. It's also possible for another one from the
+ * same thread but then an explicit wakeup will be needed since this function
+ * does not perform it. <why> is a set of SF_ERR_* flags to pass as the cause
+ * for shutting down.
+ */
+void stream_shutdown_self(struct stream *stream, int why)
{
if (stream->scb->flags & (SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED))
return;
stream->task->nice = 1024;
if (!(stream->flags & SF_ERR_MASK))
stream->flags |= why;
- task_wakeup(stream->task, TASK_WOKEN_OTHER);
}
/* dumps an error message for type <type> at ptr <ptr> related to stream <s>,