]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: tasklet: set TASK_WOKEN_OTHER on tasklets by default
authorWilly Tarreau <w@1wt.eu>
Thu, 28 Nov 2024 18:42:22 +0000 (19:42 +0100)
committerWilly Tarreau <w@1wt.eu>
Tue, 3 Dec 2024 18:45:08 +0000 (19:45 +0100)
Now when tasklets are woken up via tasklet_wakeup(), tasklet_wakeup_on()
or tasklet_wakeup_after(), either the optional wakeup flags will be used,
or TASK_WOKEN_OTHER will be used.

This allows tasklet handlers waking up for any given cause to notice
whether or not they were also woken for another reason. For example, a
mux handler could skip heavy parts when seeing that TASK_WOKEN_OTHER is
absent, proving that no standard tasklet_wakeup() was done, for example
in response to a subscribe().

The benefit of the TASK_WOKEN_* flags is that they're purged during the
wakeup, and that they're easy to check for using TASK_WOKEN_ANY.
TASK_F_UEVT1 and TASK_F_UEVT2 are also usable for private use (e.g. wakeup
from a stream to a connection inside a mux).

Probably that in the future, code dealing with subscribe events should
start to place TASK_WOKEN_IO like is done for upper layers.

include/haproxy/task.h

index 5749253037626b325abd3eccb7359de659964977..bd2ca60f0dae58e83c6f28407a604b01b6511dde 100644 (file)
@@ -380,7 +380,7 @@ static inline void task_set_thread(struct task *t, int thr)
  * flag is added).
  */
 #define tasklet_wakeup_on(tl, thr, ...)                                        \
-       _tasklet_wakeup_on(tl, thr, DEFZERO(__VA_ARGS__), MK_CALLER(WAKEUP_TYPE_TASKLET_WAKEUP, 0, 0))
+       _tasklet_wakeup_on(tl, thr, DEFVAL(TASK_WOKEN_OTHER, ##__VA_ARGS__), MK_CALLER(WAKEUP_TYPE_TASKLET_WAKEUP, 0, 0))
 
 static inline void _tasklet_wakeup_on(struct tasklet *tl, int thr, uint f, const struct ha_caller *caller)
 {
@@ -417,7 +417,7 @@ static inline void _tasklet_wakeup_on(struct tasklet *tl, int thr, uint f, const
  * flag is added).
  */
 #define tasklet_wakeup(tl, ...)                                                \
-       _tasklet_wakeup_on(tl, (tl)->tid, DEFZERO(__VA_ARGS__), MK_CALLER(WAKEUP_TYPE_TASKLET_WAKEUP, 0, 0))
+       _tasklet_wakeup_on(tl, (tl)->tid, DEFVAL(TASK_WOKEN_OTHER, ##__VA_ARGS__), MK_CALLER(WAKEUP_TYPE_TASKLET_WAKEUP, 0, 0))
 
 /* instantly wakes up task <t> on its owner thread even if it's not the current
  * one, bypassing the run queue. The purpose is to be able to avoid contention
@@ -479,11 +479,14 @@ static inline void _task_instant_wakeup(struct task *t, unsigned int f, const st
  *
  * The macro accepts an optional 3rd argument that is passed as a set of flags
  * to be set on the tasklet, among TASK_WOKEN_*, TASK_F_UEVT* etc to indicate a
- * wakeup cause to the tasklet. When not set, the arg defaults to zero (i.e. no
- * flag is added).
+ * wakeup cause to the tasklet. When not set, the arg defaults to
+ * TASK_WOKEN_OTHER, so that tasklets can differentiate a unique explicit wakeup
+ * cause from a wakeup cause combined with other implicit ones. I.e. that may be
+ * used by muxes to decide whether or not to perform a short path for certain
+ * operations, or a complete one that also covers regular I/O.
  */
 #define tasklet_wakeup_after(head, tl, ...)                                    \
-       _tasklet_wakeup_after(head, tl, DEFZERO(__VA_ARGS__), MK_CALLER(WAKEUP_TYPE_TASKLET_WAKEUP_AFTER, 0, 0))
+       _tasklet_wakeup_after(head, tl, DEFVAL(TASK_WOKEN_OTHER, ##__VA_ARGS__), MK_CALLER(WAKEUP_TYPE_TASKLET_WAKEUP_AFTER, 0, 0))
 
 static inline struct list *_tasklet_wakeup_after(struct list *head, struct tasklet *tl,
                                                  uint f, const struct ha_caller *caller)