mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2024-12-28 16:52:18 +00:00
closures: Add closure_wait_event_timeout()
Add a closure version of wait_event_timeout(), with the same semantics. The closure version is useful because unlike wait_event(), it allows blocking code to run in the conditional expression. Cc: Coly Li <colyli@suse.de> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
9205d24cf7
commit
04b670de28
@ -454,4 +454,39 @@ do { \
|
||||
__closure_wait_event(waitlist, _cond); \
|
||||
} while (0)
|
||||
|
||||
#define __closure_wait_event_timeout(waitlist, _cond, _until) \
|
||||
({ \
|
||||
struct closure cl; \
|
||||
long _t; \
|
||||
\
|
||||
closure_init_stack(&cl); \
|
||||
\
|
||||
while (1) { \
|
||||
closure_wait(waitlist, &cl); \
|
||||
if (_cond) { \
|
||||
_t = max_t(long, 1L, _until - jiffies); \
|
||||
break; \
|
||||
} \
|
||||
_t = max_t(long, 0L, _until - jiffies); \
|
||||
if (!_t) \
|
||||
break; \
|
||||
closure_sync_timeout(&cl, _t); \
|
||||
} \
|
||||
closure_wake_up(waitlist); \
|
||||
closure_sync(&cl); \
|
||||
_t; \
|
||||
})
|
||||
|
||||
/*
|
||||
* Returns 0 if timeout expired, remaining time in jiffies (at least 1) if
|
||||
* condition became true
|
||||
*/
|
||||
#define closure_wait_event_timeout(waitlist, _cond, _timeout) \
|
||||
({ \
|
||||
unsigned long _until = jiffies + _timeout; \
|
||||
(_cond) \
|
||||
? max_t(long, 1L, _until - jiffies) \
|
||||
: __closure_wait_event_timeout(waitlist, _cond, _until);\
|
||||
})
|
||||
|
||||
#endif /* _LINUX_CLOSURE_H */
|
||||
|
Loading…
Reference in New Issue
Block a user