summaryrefslogtreecommitdiff
path: root/include/linux/closure.h
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@gmail.com>2017-12-09 20:42:44 +0300
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-19 21:47:33 +0300
commitced58fc7ab9f2d4b3d8aaeb859321a61aa884f66 (patch)
treefd2da9f3daebf59fde2e2cf794355d21c7240d14 /include/linux/closure.h
parentbd0d22e41ecbc5247e5f6a423636df14dbb1bef2 (diff)
downloadlinux-ced58fc7ab9f2d4b3d8aaeb859321a61aa884f66.tar.xz
closures: closure_wait_event()
Like wait_event() - except, because it uses closures and closure waitlists it doesn't have the restriction on modifying task state inside the condition check, like wait_event() does. Signed-off-by: Kent Overstreet <kent.overstreet@gmail.com> Acked-by: Coly Li <colyli@suse.de>
Diffstat (limited to 'include/linux/closure.h')
-rw-r--r--include/linux/closure.h22
1 files changed, 22 insertions, 0 deletions
diff --git a/include/linux/closure.h b/include/linux/closure.h
index 0ec9e7bc8d97..36b4a83f9b77 100644
--- a/include/linux/closure.h
+++ b/include/linux/closure.h
@@ -374,4 +374,26 @@ static inline void closure_call(struct closure *cl, closure_fn fn,
continue_at_nobarrier(cl, fn, wq);
}
+#define __closure_wait_event(waitlist, _cond) \
+do { \
+ struct closure cl; \
+ \
+ closure_init_stack(&cl); \
+ \
+ while (1) { \
+ closure_wait(waitlist, &cl); \
+ if (_cond) \
+ break; \
+ closure_sync(&cl); \
+ } \
+ closure_wake_up(waitlist); \
+ closure_sync(&cl); \
+} while (0)
+
+#define closure_wait_event(waitlist, _cond) \
+do { \
+ if (!(_cond)) \
+ __closure_wait_event(waitlist, _cond); \
+} while (0)
+
#endif /* _LINUX_CLOSURE_H */