summaryrefslogtreecommitdiff
path: root/usr/src/lib/libc/port/threads/synch.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libc/port/threads/synch.c')
-rw-r--r--usr/src/lib/libc/port/threads/synch.c71
1 files changed, 71 insertions, 0 deletions
diff --git a/usr/src/lib/libc/port/threads/synch.c b/usr/src/lib/libc/port/threads/synch.c
index 6856ebcc6b..9c6e918620 100644
--- a/usr/src/lib/libc/port/threads/synch.c
+++ b/usr/src/lib/libc/port/threads/synch.c
@@ -2184,6 +2184,77 @@ lmutex_unlock(mutex_t *mp)
exit_critical(self);
}
+/*
+ * For specialized code in libc, like the asynchronous i/o code,
+ * the following sig_*() locking primitives are used in order
+ * to make the code asynchronous signal safe. Signals are
+ * deferred while locks acquired by these functions are held.
+ */
+void
+sig_mutex_lock(mutex_t *mp)
+{
+ sigoff(curthread);
+ (void) _private_mutex_lock(mp);
+}
+
+void
+sig_mutex_unlock(mutex_t *mp)
+{
+ (void) _private_mutex_unlock(mp);
+ sigon(curthread);
+}
+
+int
+sig_mutex_trylock(mutex_t *mp)
+{
+ int error;
+
+ sigoff(curthread);
+ if ((error = _private_mutex_trylock(mp)) != 0)
+ sigon(curthread);
+ return (error);
+}
+
+/*
+ * sig_cond_wait() is a cancellation point.
+ */
+int
+sig_cond_wait(cond_t *cv, mutex_t *mp)
+{
+ int error;
+
+ ASSERT(curthread->ul_sigdefer != 0);
+ _private_testcancel();
+ error = _cond_wait(cv, mp);
+ if (error == EINTR && curthread->ul_cursig) {
+ sig_mutex_unlock(mp);
+ /* take the deferred signal here */
+ sig_mutex_lock(mp);
+ }
+ _private_testcancel();
+ return (error);
+}
+
+/*
+ * sig_cond_reltimedwait() is a cancellation point.
+ */
+int
+sig_cond_reltimedwait(cond_t *cv, mutex_t *mp, const timespec_t *ts)
+{
+ int error;
+
+ ASSERT(curthread->ul_sigdefer != 0);
+ _private_testcancel();
+ error = _cond_reltimedwait(cv, mp, ts);
+ if (error == EINTR && curthread->ul_cursig) {
+ sig_mutex_unlock(mp);
+ /* take the deferred signal here */
+ sig_mutex_lock(mp);
+ }
+ _private_testcancel();
+ return (error);
+}
+
static int
shared_mutex_held(mutex_t *mparg)
{