diff options
author | Arnd Bergmann <arnd@arndb.de> | 2010-06-01 22:53:05 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-08-10 13:47:43 -0700 |
commit | be1bc2889a4db4961ef69f47fb471ecae9f23ade (patch) | |
tree | fd6d5e46e69efd9d66e6baa184988461f608f49a /include/linux | |
parent | 4e608671674b62e97166f903830d5553e37970e8 (diff) |
tty: introduce wait_event_interruptible_tty
Calling wait_event_interruptible implicitly
releases the BKL when it sleeps, but we need
to do this explcitly when we have converted
it to a mutex.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/tty.h | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/include/linux/tty.h b/include/linux/tty.h index 6ead6b60c74..955d72ea71c 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -607,5 +607,47 @@ static inline void tty_unlock(void) __releases(kernel_lock) } #define tty_locked() (kernel_locked()) +/* + * wait_event_interruptible_tty -- wait for a condition with the tty lock held + * + * The condition we are waiting for might take a long time to + * become true, or might depend on another thread taking the + * BTM. In either case, we need to drop the BTM to guarantee + * forward progress. This is a leftover from the conversion + * from the BKL and should eventually get removed as the BTM + * falls out of use. + * + * Do not use in new code. + */ +#define wait_event_interruptible_tty(wq, condition) \ +({ \ + int __ret = 0; \ + if (!(condition)) { \ + __wait_event_interruptible_tty(wq, condition, __ret); \ + } \ + __ret; \ +}) + +#define __wait_event_interruptible_tty(wq, condition, ret) \ +do { \ + DEFINE_WAIT(__wait); \ + \ + for (;;) { \ + prepare_to_wait(&wq, &__wait, TASK_INTERRUPTIBLE); \ + if (condition) \ + break; \ + if (!signal_pending(current)) { \ + tty_unlock(); \ + schedule(); \ + tty_lock(); \ + continue; \ + } \ + ret = -ERESTARTSYS; \ + break; \ + } \ + finish_wait(&wq, &__wait); \ +} while (0) + + #endif /* __KERNEL__ */ #endif |