mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2025-02-02 15:07:36 -05:00
Don't free up the second, third... header pages, as those are only referenced
once, only the first page is refcounted multiple times by the queue. Put some checks in to help capture odd cases if they arise. svn path=/icecast/trunk/icecast/; revision=15613
This commit is contained in:
parent
52129d4c5e
commit
add7342a14
@ -120,6 +120,7 @@ void format_ogg_free_headers (ogg_state_t *ogg_info)
|
||||
{
|
||||
refbuf_t *to_release = header;
|
||||
header = header->next;
|
||||
to_release->next = NULL;
|
||||
refbuf_release (to_release);
|
||||
}
|
||||
ogg_info->header_pages = NULL;
|
||||
|
39
src/refbuf.c
39
src/refbuf.c
@ -25,6 +25,11 @@
|
||||
|
||||
#include "refbuf.h"
|
||||
|
||||
#define CATMODULE "refbuf"
|
||||
|
||||
#include "logging.h"
|
||||
|
||||
|
||||
void refbuf_initialize(void)
|
||||
{
|
||||
}
|
||||
@ -33,22 +38,19 @@ void refbuf_shutdown(void)
|
||||
{
|
||||
}
|
||||
|
||||
refbuf_t *refbuf_new(unsigned int size)
|
||||
refbuf_t *refbuf_new (unsigned int size)
|
||||
{
|
||||
refbuf_t *refbuf;
|
||||
|
||||
refbuf = (refbuf_t *)malloc(sizeof(refbuf_t));
|
||||
if (refbuf == NULL)
|
||||
return NULL;
|
||||
abort();
|
||||
refbuf->data = NULL;
|
||||
if (size)
|
||||
{
|
||||
refbuf->data = malloc (size);
|
||||
if (refbuf->data == NULL)
|
||||
{
|
||||
free (refbuf);
|
||||
return NULL;
|
||||
}
|
||||
abort();
|
||||
}
|
||||
refbuf->len = size;
|
||||
refbuf->sync_point = 0;
|
||||
@ -64,18 +66,29 @@ void refbuf_addref(refbuf_t *self)
|
||||
self->_count++;
|
||||
}
|
||||
|
||||
static void refbuf_release_associated (refbuf_t *ref)
|
||||
{
|
||||
if (ref == NULL)
|
||||
return;
|
||||
while (ref && ref->_count == 1)
|
||||
{
|
||||
refbuf_t *to_go = ref;
|
||||
ref = to_go->next;
|
||||
to_go->next = NULL;
|
||||
refbuf_release (to_go);
|
||||
}
|
||||
}
|
||||
|
||||
void refbuf_release(refbuf_t *self)
|
||||
{
|
||||
if (self == NULL)
|
||||
return;
|
||||
self->_count--;
|
||||
if (self->_count == 0) {
|
||||
while (self->associated)
|
||||
{
|
||||
refbuf_t *ref = self->associated;
|
||||
self->associated = ref->next;
|
||||
refbuf_release (ref);
|
||||
}
|
||||
if (self->_count == 0)
|
||||
{
|
||||
refbuf_release_associated (self->associated);
|
||||
if (self->next)
|
||||
DEBUG0 ("next not null");
|
||||
free(self->data);
|
||||
free(self);
|
||||
}
|
||||
|
@ -239,6 +239,7 @@ void source_clear_source (source_t *source)
|
||||
{
|
||||
refbuf_t *p = source->stream_data;
|
||||
source->stream_data = p->next;
|
||||
p->next = NULL;
|
||||
/* can be referenced by burst handler as well */
|
||||
while (p->_count > 1)
|
||||
refbuf_release (p);
|
||||
@ -806,6 +807,7 @@ void source_main (source_t *source)
|
||||
}
|
||||
source->stream_data = to_go->next;
|
||||
source->queue_size -= to_go->len;
|
||||
to_go->next = NULL;
|
||||
refbuf_release (to_go);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user