1
0
mirror of https://gitlab.xiph.org/xiph/icecast-server.git synced 2024-09-08 04:04:48 -04:00
icecast-server/src/refbuf.c
Michael Smith ed019c0cd6 Remove locking from refbuf: we used a single global lock for all of them, which
caused significant lock contention with many sources. Further, a single refbuf
is never used by more than one source (and hence one thread), so the locking
was unneeded.

Fix a nasty bug in source.c:_compare_clients() - was casting a void pointer
to the wrong type, and hence all the tree-maintaince comparisons were totally
wrong (but due to the exact nature of the bug this wasn't causing any active
problems until...)

Add another admin command to kill a client - remove it using an id. Note that
many clients will do auto-reconnect, so this may not be sufficient on its own,
we might need a ban (possibly temporary) function.

svn path=/trunk/icecast/; revision=4569
2003-03-30 13:52:27 +00:00

124 lines
2.2 KiB
C

/* refbuf.c
**
** reference counting buffer implementation
**
*/
#include <stdlib.h>
#include <string.h>
#include "refbuf.h"
void refbuf_initialize(void)
{
}
void refbuf_shutdown(void)
{
}
refbuf_t *refbuf_new(unsigned long size)
{
refbuf_t *refbuf;
refbuf = (refbuf_t *)malloc(sizeof(refbuf_t));
refbuf->data = (void *)malloc(size);
refbuf->len = size;
refbuf->_count = 1;
return refbuf;
}
void refbuf_addref(refbuf_t *self)
{
self->_count++;
}
void refbuf_release(refbuf_t *self)
{
self->_count--;
if (self->_count == 0) {
free(self->data);
free(self);
return;
}
}
void refbuf_queue_add(refbuf_queue_t **queue, refbuf_t *refbuf)
{
refbuf_queue_t *node;
refbuf_queue_t *item = (refbuf_queue_t *)malloc(sizeof(refbuf_queue_t));
item->refbuf = refbuf;
item->next = NULL;
if (*queue == NULL) {
*queue = item;
(*queue)->total_length = item->refbuf->len;
} else {
node = *queue;
while (node->next) node = node->next;
node->next = item;
(*queue)->total_length += item->refbuf->len;
}
}
refbuf_t *refbuf_queue_remove(refbuf_queue_t **queue)
{
refbuf_queue_t *item;
refbuf_t *refbuf;
if (*queue == NULL) return NULL;
item = *queue;
*queue = item->next;
item->next = NULL;
refbuf = item->refbuf;
item->refbuf = NULL;
if(*queue)
(*queue)->total_length = item->total_length - refbuf->len;
free(item);
return refbuf;
}
void refbuf_queue_insert(refbuf_queue_t **queue, refbuf_t *refbuf)
{
refbuf_queue_t *item = (refbuf_queue_t *)malloc(sizeof(refbuf_queue_t));
item->refbuf = refbuf;
item->next = *queue;
if(item->next)
item->total_length = item->next->total_length + item->refbuf->len;
else
item->total_length = item->refbuf->len;
*queue = item;
}
int refbuf_queue_size(refbuf_queue_t **queue)
{
refbuf_queue_t *node = *queue;
int size = 0;
while (node) {
node = node->next;
size++;
}
return size;
}
int refbuf_queue_length(refbuf_queue_t **queue)
{
if(*queue)
return (*queue)->total_length;
else
return 0;
}