Fix huge memory leak within sound buffer (during channel destruction,

buffer resizing, etc.) that was here since eon. Free all (unmanaged)
allocated buffer through sndbuf_destroy() in case we forgot to call
sndbuf_free(). For a managed buffer (mostly hw specific managed buffer),
either provide CHANNEL_FREE() method with appropriate return value to
invoke semi-automatic sndbuf_free() or simply do it on their own. If
everything is failed, sndbuf_destroy() will come to the rescue as a
final measure.

MFC after:	3 days
This commit is contained in:
Ariff Abdullah 2007-02-01 09:46:03 +00:00
parent e444a20971
commit 9e4c8259a3
2 changed files with 13 additions and 0 deletions

View File

@ -46,6 +46,12 @@ sndbuf_create(device_t dev, char *drv, char *desc, struct pcm_channel *channel)
void
sndbuf_destroy(struct snd_dbuf *b)
{
if (b->tmpbuf)
free(b->tmpbuf, M_DEVBUF);
if (b->shadbuf)
free(b->shadbuf, M_DEVBUF);
if (!(b->flags & SNDBUF_F_MANAGED) && b->buf)
free(b->buf, M_DEVBUF);
free(b, M_DEVBUF);
}
@ -85,6 +91,7 @@ sndbuf_alloc(struct snd_dbuf *b, bus_dma_tag_t dmatag, unsigned int size)
b->maxsize = size;
b->bufsize = b->maxsize;
b->buf_addr = 0;
b->flags |= SNDBUF_F_MANAGED;
if (bus_dmamem_alloc(b->dmatag, (void **)&b->buf, BUS_DMA_NOWAIT,
&b->dmamap))
return (ENOMEM);
@ -104,6 +111,8 @@ sndbuf_alloc(struct snd_dbuf *b, bus_dma_tag_t dmatag, unsigned int size)
int
sndbuf_setup(struct snd_dbuf *b, void *buf, unsigned int size)
{
if (buf)
b->flags |= SNDBUF_F_MANAGED;
b->buf = buf;
b->maxsize = size;
b->bufsize = b->maxsize;
@ -122,6 +131,9 @@ sndbuf_free(struct snd_dbuf *b)
b->shadbuf = NULL;
b->sl = 0;
if (!(b->flags & SNDBUF_F_MANAGED) && b->buf)
free(b->buf, M_DEVBUF);
if (b->dmamap)
bus_dmamap_unload(b->dmatag, b->dmamap);

View File

@ -32,6 +32,7 @@
#define SNDBUF_F_DMA 0x00000001
#define SNDBUF_F_XRUN 0x00000002
#define SNDBUF_F_RUNNING 0x00000004
#define SNDBUF_F_MANAGED 0x00000008
#define SNDBUF_NAMELEN 48