summaryrefslogtreecommitdiff
path: root/usr/src/lib/libc/port/threads/sigaction.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libc/port/threads/sigaction.c')
-rw-r--r--usr/src/lib/libc/port/threads/sigaction.c27
1 files changed, 17 insertions, 10 deletions
diff --git a/usr/src/lib/libc/port/threads/sigaction.c b/usr/src/lib/libc/port/threads/sigaction.c
index 529530f2af..3d8f747100 100644
--- a/usr/src/lib/libc/port/threads/sigaction.c
+++ b/usr/src/lib/libc/port/threads/sigaction.c
@@ -83,6 +83,9 @@ call_user_handler(int sig, siginfo_t *sip, ucontext_t *ucp)
* while holding the sig's sig_lock for the least possible time.
* We must acquire the sig's sig_lock because some thread running
* in sigaction() might be establishing a new signal handler.
+ * The code in sigaction() acquires the writer lock; here
+ * we acquire the readers lock to ehance concurrency in the
+ * face of heavy signal traffic, such as generated by java.
*
* Locking exceptions:
* No locking for a child of vfork().
@@ -103,12 +106,12 @@ call_user_handler(int sig, siginfo_t *sip, ucontext_t *ucp)
/* we wish this assignment could be atomic */
(void) _private_memcpy(&uact, (void *)sap, sizeof (uact));
} else {
- mutex_t *mp = &udp->siguaction[sig].sig_lock;
- lmutex_lock(mp);
+ rwlock_t *rwlp = &udp->siguaction[sig].sig_lock;
+ lrw_rdlock(rwlp);
(void) _private_memcpy(&uact, (void *)sap, sizeof (uact));
if (sig == SIGCANCEL && (sap->sa_flags & SA_RESETHAND))
sap->sa_sigaction = SIG_DFL;
- lmutex_unlock(mp);
+ lrw_unlock(rwlp);
}
/*
@@ -324,7 +327,7 @@ _libc_sigaction(int sig, const struct sigaction *nact, struct sigaction *oact)
}
if (!self->ul_vfork)
- lmutex_lock(&udp->siguaction[sig].sig_lock);
+ lrw_wrlock(&udp->siguaction[sig].sig_lock);
oaction = udp->siguaction[sig].sig_uaction;
@@ -401,7 +404,7 @@ _libc_sigaction(int sig, const struct sigaction *nact, struct sigaction *oact)
}
if (!self->ul_vfork)
- lmutex_unlock(&udp->siguaction[sig].sig_lock);
+ lrw_unlock(&udp->siguaction[sig].sig_lock);
return (rv);
}
@@ -633,7 +636,7 @@ _sigprocmask(int how, const sigset_t *set, sigset_t *oset)
/*
* Called at library initialization to set up signal handling.
- * All we really do is initialize the sig_lock mutexes.
+ * All we really do is initialize the sig_lock rwlocks.
* All signal handlers are either SIG_DFL or SIG_IGN on exec().
* However, if any signal handlers were established on alternate
* link maps before the primary link map has been initialized,
@@ -645,10 +648,14 @@ signal_init()
uberdata_t *udp = curthread->ul_uberdata;
struct sigaction *sap;
struct sigaction act;
+ rwlock_t *rwlp;
int sig;
for (sig = 0; sig < NSIG; sig++) {
- udp->siguaction[sig].sig_lock.mutex_magic = MUTEX_MAGIC;
+ rwlp = &udp->siguaction[sig].sig_lock;
+ rwlp->rwlock_magic = RWL_MAGIC;
+ rwlp->mutex.mutex_flag = LOCK_INITED;
+ rwlp->mutex.mutex_magic = MUTEX_MAGIC;
sap = &udp->siguaction[sig].sig_uaction;
if (sap->sa_sigaction != SIG_DFL &&
sap->sa_sigaction != SIG_IGN &&
@@ -694,13 +701,13 @@ void
setup_cancelsig(int sig)
{
uberdata_t *udp = curthread->ul_uberdata;
- mutex_t *mp = &udp->siguaction[sig].sig_lock;
+ rwlock_t *rwlp = &udp->siguaction[sig].sig_lock;
struct sigaction act;
ASSERT(sig == SIGCANCEL || sig == SIGAIOCANCEL);
- lmutex_lock(mp);
+ lrw_rdlock(rwlp);
act = udp->siguaction[sig].sig_uaction;
- lmutex_unlock(mp);
+ lrw_unlock(rwlp);
if (act.sa_sigaction == SIG_DFL ||
act.sa_sigaction == SIG_IGN)
act.sa_flags = SA_SIGINFO;