summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGarrett D'Amore <gdamore@opensolaris.org>2009-07-01 17:10:10 -0700
committerGarrett D'Amore <gdamore@opensolaris.org>2009-07-01 17:10:10 -0700
commit55f338e6ff66b050744472388b2b9ee3d320414f (patch)
treec5bb2acdb05f1ff3f3ae0f76cf19f1c3082cc8c5
parentd463bb94f213817526ea7f7b2b8219ef1fe801d9 (diff)
downloadillumos-joyent-55f338e6ff66b050744472388b2b9ee3d320414f.tar.gz
6853360 crash during mplayer/sun audio
-rw-r--r--usr/src/uts/common/io/audio/impl/audio_sun.c25
1 files changed, 10 insertions, 15 deletions
diff --git a/usr/src/uts/common/io/audio/impl/audio_sun.c b/usr/src/uts/common/io/audio/impl/audio_sun.c
index 88ab23c093..55901a7bb9 100644
--- a/usr/src/uts/common/io/audio/impl/audio_sun.c
+++ b/usr/src/uts/common/io/audio/impl/audio_sun.c
@@ -163,7 +163,7 @@ struct sproc {
sclient_t *p_reader;
};
-int sproc_hold(audio_client_t *, int);
+int sproc_hold(audio_client_t *, ldi_handle_t, queue_t *, int);
void sproc_release(sclient_t *);
static void sproc_update(sproc_t *);
@@ -474,7 +474,7 @@ sproc_free(sproc_t *proc)
}
int
-sproc_hold(audio_client_t *c, int oflag)
+sproc_hold(audio_client_t *c, ldi_handle_t lh, queue_t *rq, int oflag)
{
pid_t pid;
sproc_t *proc;
@@ -522,8 +522,6 @@ sproc_hold(audio_client_t *c, int oflag)
list_insert_tail(l, proc);
}
- sc->s_proc = proc;
-
while (proc->p_oflag & oflag) {
if (oflag & (FNDELAY|FNONBLOCK)) {
@@ -592,6 +590,13 @@ sproc_hold(audio_client_t *c, int oflag)
proc->p_oflag |= FREAD;
}
+ sc->s_lh = lh;
+ sc->s_rq = rq;
+ sc->s_wq = WR(rq);
+ WR(rq)->q_ptr = rq->q_ptr = sc;
+ /* we update the s_proc last to avoid a race */
+ sc->s_proc = proc;
+
sproc_update(proc);
mutex_exit(&sdev->d_mx);
@@ -1409,7 +1414,6 @@ sunstr_open(queue_t *rq, dev_t *devp, int flag, int sflag, cred_t *cr)
ldi_ident_t lid;
ldi_handle_t lh = NULL;
audio_client_t *c = NULL;
- sclient_t *sc = NULL;
audio_dev_t *adev;
unsigned fmt;
int oflag;
@@ -1487,16 +1491,10 @@ sunstr_open(queue_t *rq, dev_t *devp, int flag, int sflag, cred_t *cr)
}
isopen = B_TRUE;
- if ((rv = sproc_hold(c, oflag)) != 0) {
+ if ((rv = sproc_hold(c, lh, rq, oflag)) != 0) {
goto fail;
}
- sc = auclnt_get_private(c);
- WR(rq)->q_ptr = rq->q_ptr = sc;
- sc->s_lh = lh;
- sc->s_rq = rq;
- sc->s_wq = WR(rq);
-
/* start up the input */
if (oflag & FREAD) {
auclnt_start(auclnt_input_stream(c));
@@ -1510,9 +1508,6 @@ sunstr_open(queue_t *rq, dev_t *devp, int flag, int sflag, cred_t *cr)
return (0);
fail:
- if (sc != NULL) {
- sproc_release(sc);
- }
if (isopen) {
auclnt_close(c);
}