mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2025-02-02 15:07:36 -05:00
Thanks to Ciaran for realizing that we werne't freeing the format plugins
memory on source exits. This caused a small but noticable memory leak. The fix was to add a new method to the format_plugin object - free_plugin() - and have the source thread call this on shutdown. svn path=/trunk/icecast/; revision=2946
This commit is contained in:
parent
cbbdb5fc49
commit
6c0132596f
@ -23,6 +23,7 @@ typedef struct _format_plugin_tag
|
|||||||
|
|
||||||
refbuf_t *(*get_buffer)(struct _format_plugin_tag *self, char *data, unsigned long len);
|
refbuf_t *(*get_buffer)(struct _format_plugin_tag *self, char *data, unsigned long len);
|
||||||
refbuf_queue_t *(*get_predata)(struct _format_plugin_tag *self);
|
refbuf_queue_t *(*get_predata)(struct _format_plugin_tag *self);
|
||||||
|
void (*free_plugin)(struct _format_plugin_tag *self);
|
||||||
|
|
||||||
/* for internal state management */
|
/* for internal state management */
|
||||||
void *_state;
|
void *_state;
|
||||||
|
@ -24,6 +24,7 @@ typedef struct _vstate_tag
|
|||||||
refbuf_t *headbuf[10];
|
refbuf_t *headbuf[10];
|
||||||
} vstate_t;
|
} vstate_t;
|
||||||
|
|
||||||
|
void format_vorbis_free_plugin(format_plugin_t *self);
|
||||||
refbuf_t *format_vorbis_get_buffer(format_plugin_t *self, char *data, unsigned long len);
|
refbuf_t *format_vorbis_get_buffer(format_plugin_t *self, char *data, unsigned long len);
|
||||||
refbuf_queue_t *format_vorbis_get_predata(format_plugin_t *self);
|
refbuf_queue_t *format_vorbis_get_predata(format_plugin_t *self);
|
||||||
|
|
||||||
@ -33,10 +34,12 @@ format_plugin_t *format_vorbis_get_plugin(void)
|
|||||||
vstate_t *state;
|
vstate_t *state;
|
||||||
|
|
||||||
plugin = (format_plugin_t *)malloc(sizeof(format_plugin_t));
|
plugin = (format_plugin_t *)malloc(sizeof(format_plugin_t));
|
||||||
|
|
||||||
plugin->type = FORMAT_TYPE_VORBIS;
|
plugin->type = FORMAT_TYPE_VORBIS;
|
||||||
plugin->has_predata = 1;
|
plugin->has_predata = 1;
|
||||||
plugin->get_buffer = format_vorbis_get_buffer;
|
plugin->get_buffer = format_vorbis_get_buffer;
|
||||||
plugin->get_predata = format_vorbis_get_predata;
|
plugin->get_predata = format_vorbis_get_predata;
|
||||||
|
plugin->free_plugin = format_vorbis_free_plugin;
|
||||||
|
|
||||||
state = (vstate_t *)calloc(1, sizeof(vstate_t));
|
state = (vstate_t *)calloc(1, sizeof(vstate_t));
|
||||||
ogg_sync_init(&state->oy);
|
ogg_sync_init(&state->oy);
|
||||||
@ -46,6 +49,29 @@ format_plugin_t *format_vorbis_get_plugin(void)
|
|||||||
return plugin;
|
return plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void format_vorbis_free_plugin(format_plugin_t *self)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
vstate_t *state = (vstate_t *)self->_state;
|
||||||
|
|
||||||
|
/* free memory associated with this plugin instance */
|
||||||
|
|
||||||
|
/* free state memory */
|
||||||
|
ogg_sync_clear(&state->oy);
|
||||||
|
|
||||||
|
for (i = 0; i < 10; i++) {
|
||||||
|
if (state->headbuf[i]) {
|
||||||
|
refbuf_release(state->headbuf[i]);
|
||||||
|
state->headbuf[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(state);
|
||||||
|
|
||||||
|
/* free the plugin instance */
|
||||||
|
free(self);
|
||||||
|
}
|
||||||
|
|
||||||
refbuf_t *format_vorbis_get_buffer(format_plugin_t *self, char *data, unsigned long len)
|
refbuf_t *format_vorbis_get_buffer(format_plugin_t *self, char *data, unsigned long len)
|
||||||
{
|
{
|
||||||
char *buffer;
|
char *buffer;
|
||||||
|
@ -90,6 +90,7 @@ int source_free_source(void *key)
|
|||||||
httpp_destroy(source->parser);
|
httpp_destroy(source->parser);
|
||||||
avl_tree_free(source->pending_tree, _free_client);
|
avl_tree_free(source->pending_tree, _free_client);
|
||||||
avl_tree_free(source->client_tree, _free_client);
|
avl_tree_free(source->client_tree, _free_client);
|
||||||
|
source->format->free_plugin(source->format);
|
||||||
free(source);
|
free(source);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user