diff options
author | Brian Behlendorf <[email protected]> | 2010-05-14 09:24:51 -0700 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2010-05-14 09:24:51 -0700 |
commit | f752b46eb3c3b889d62465ea800cf17c980becd1 (patch) | |
tree | 3d9b8f152d2ea919472d7436dce587c4c6557f90 /module/spl/spl-condvar.c | |
parent | 97f8f6d78999ab41d23cf5942d55ea3ad0ca4f3e (diff) |
Add cv_wait_interruptible() function.
This is a minor extension to the condition variable API to allow
for reasonable signal handling on Linux. The cv_wait() function by
definition must wait unconditionally for cv_signal()/cv_broadcast()
before waking it. This makes it impossible to woken by a signal
such as SIGTERM. The cv_wait_interruptible() function was added
to handle this case. It behaves identically to cv_wait() with the
exception that it waits interruptibly allowing a signal to wake it
up. This means you do need to be careful and check issig() after
waking.
Diffstat (limited to 'module/spl/spl-condvar.c')
-rw-r--r-- | module/spl/spl-condvar.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/module/spl/spl-condvar.c b/module/spl/spl-condvar.c index 163f2a1de..d5b9be721 100644 --- a/module/spl/spl-condvar.c +++ b/module/spl/spl-condvar.c @@ -84,8 +84,8 @@ __cv_destroy(kcondvar_t *cvp) } EXPORT_SYMBOL(__cv_destroy); -void -__cv_wait(kcondvar_t *cvp, kmutex_t *mp) +static void +cv_wait_common(kcondvar_t *cvp, kmutex_t *mp, int state) { DEFINE_WAIT(wait); ENTRY; @@ -103,8 +103,7 @@ __cv_wait(kcondvar_t *cvp, kmutex_t *mp) ASSERT(cvp->cv_mutex == mp); spin_unlock(&cvp->cv_lock); - prepare_to_wait_exclusive(&cvp->cv_event, &wait, - TASK_UNINTERRUPTIBLE); + prepare_to_wait_exclusive(&cvp->cv_event, &wait, state); atomic_inc(&cvp->cv_waiters); /* Mutex should be dropped after prepare_to_wait() this @@ -118,8 +117,21 @@ __cv_wait(kcondvar_t *cvp, kmutex_t *mp) finish_wait(&cvp->cv_event, &wait); EXIT; } + +void +__cv_wait(kcondvar_t *cvp, kmutex_t *mp) +{ + cv_wait_common(cvp, mp, TASK_UNINTERRUPTIBLE); +} EXPORT_SYMBOL(__cv_wait); +void +__cv_wait_interruptible(kcondvar_t *cvp, kmutex_t *mp) +{ + cv_wait_common(cvp, mp, TASK_INTERRUPTIBLE); +} +EXPORT_SYMBOL(__cv_wait_interruptible); + /* 'expire_time' argument is an absolute wall clock time in jiffies. * Return value is time left (expire_time - now) or -1 if timeout occurred. */ |