summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorariff <ariff@FreeBSD.org>2007-03-17 17:07:21 +0000
committerariff <ariff@FreeBSD.org>2007-03-17 17:07:21 +0000
commit1008dd40e3ccaea2037b43cebc74eb7310fccdd6 (patch)
treedf099de99e511cfda817c2c8db0e8bb873b780ea
parent07ef309a5ab5c901cf3b3ba8b49c4ad26a811962 (diff)
downloadFreeBSD-src-1008dd40e3ccaea2037b43cebc74eb7310fccdd6.zip
FreeBSD-src-1008dd40e3ccaea2037b43cebc74eb7310fccdd6.tar.gz
Fix long delay closing/syncing issues on mmaped buffer.
-rw-r--r--sys/dev/sound/pcm/channel.c10
-rw-r--r--sys/dev/sound/pcm/vchan.c2
2 files changed, 8 insertions, 4 deletions
diff --git a/sys/dev/sound/pcm/channel.c b/sys/dev/sound/pcm/channel.c
index d099e8b..4eae3b2 100644
--- a/sys/dev/sound/pcm/channel.c
+++ b/sys/dev/sound/pcm/channel.c
@@ -343,7 +343,7 @@ chn_wrfeed(struct pcm_channel *c)
})
#endif
- if (c->flags & CHN_F_MAPPED)
+ if ((c->flags & CHN_F_MAPPED) && !(c->flags & CHN_F_CLOSING))
sndbuf_acquire(bs, NULL, sndbuf_getfree(bs));
amt = sndbuf_getfree(b);
@@ -696,9 +696,9 @@ chn_resetbuf(struct pcm_channel *c)
int
chn_sync(struct pcm_channel *c, int threshold)
{
- int ret, count, hcount, minflush, resid, residp;
struct snd_dbuf *b, *bs;
- int syncdelay, blksz;
+ int ret, count, hcount, minflush, resid, residp, syncdelay, blksz;
+ u_int32_t cflag;
CHN_LOCKASSERT(c);
@@ -769,6 +769,8 @@ chn_sync(struct pcm_channel *c, int threshold)
"minflush=%d resid=%d\n", __func__, c->timeout, count,
minflush, resid);
+ cflag = c->flags & CHN_F_CLOSING;
+ c->flags |= CHN_F_CLOSING;
while (count > 0 && (resid > 0 || minflush > 0)) {
ret = chn_sleep(c, "pcmsyn", c->timeout);
if (ret == ERESTART || ret == EINTR) {
@@ -805,6 +807,8 @@ chn_sync(struct pcm_channel *c, int threshold)
residp = resid;
}
}
+ c->flags &= ~CHN_F_CLOSING;
+ c->flags |= cflag;
if (snd_verbose > 3)
printf("%s: timeout=%d count=%d hcount=%d resid=%d residp=%d "
diff --git a/sys/dev/sound/pcm/vchan.c b/sys/dev/sound/pcm/vchan.c
index 832a7e7..b65b43c 100644
--- a/sys/dev/sound/pcm/vchan.c
+++ b/sys/dev/sound/pcm/vchan.c
@@ -226,7 +226,7 @@ feed_vchan(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
CHN_UNLOCK(ch);
continue;
}
- if (ch->flags & CHN_F_MAPPED)
+ if ((ch->flags & CHN_F_MAPPED) && !(ch->flags & CHN_F_CLOSING))
sndbuf_acquire(ch->bufsoft, NULL,
sndbuf_getfree(ch->bufsoft));
if (rcnt == 0)
OpenPOWER on IntegriCloud