summaryrefslogtreecommitdiffstats
path: root/module/spl/spl-condvar.c
diff options
context:
space:
mode:
authorBrian Behlendorf <[email protected]>2010-05-14 09:24:51 -0700
committerBrian Behlendorf <[email protected]>2010-05-14 09:24:51 -0700
commitf752b46eb3c3b889d62465ea800cf17c980becd1 (patch)
tree3d9b8f152d2ea919472d7436dce587c4c6557f90 /module/spl/spl-condvar.c
parent97f8f6d78999ab41d23cf5942d55ea3ad0ca4f3e (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.c20
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.
*/