Mercurial > repos > rhope
view buffer.c @ 121:1af91ceaaf49
Fixed memory leak when an output is only attached to a single null input
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Thu, 28 Oct 2010 21:04:12 -0400 |
parents | 76568becd6d6 |
children |
line wrap: on
line source
#include "datum.h" #include "vis_threading.h" #include "structs.h" #include <string.h> //TODO: Make some kind of "notifier" lock that takes some kind of callback //to be called when the lock becomes free typedef struct { int offset; char * buffer; int size; VIS_CRITICAL_SECTION(lock) } fixed_buffer; int vis_buffer_new(datum ** params, queue_entry * entry) { int size = params[0]->c.integers.num_a; fixed_buffer * buf; release_ref(params[0]); params[0] = new_datum(BUILTIN_TYPE_BUFFER, 1, sizeof(fixed_buffer) + size, entry->instance->def->program); buf = params[0]->c.generic.data; buf->offset = 0; buf->buffer = ((char *)buf) + sizeof(fixed_buffer); buf->size = size; VIS_InitializeCriticalSection(buf->lock); return 0; } int vis_buffer_lock(datum ** params, queue_entry * entry) { fixed_buffer * buf = params[0]->c.generic.data; VIS_EnterCriticalSection(buf->lock); return 0; } int vis_buffer_unlock(datum ** params, queue_entry * entry) { fixed_buffer * buf = params[0]->c.generic.data; VIS_LeaveCriticalSection(buf->lock); return 0; } int vis_buffer_putbyte(datum ** params, queue_entry * entry) { fixed_buffer * buf = params[0]->c.generic.data; char byte = params[1]->c.integers.num_a; release_ref(params[1]); if(buf->offset < buf->size) { buf->buffer[buf->offset++] = byte; params[1] = NULL; } else { params[1] = params[0]; params[1] = NULL; } return 0; } int vis_buffer_writebyte(datum ** params, queue_entry * entry) { fixed_buffer * buf = params[0]->c.generic.data; char byte = params[1]->c.integers.num_a; release_ref(params[1]); if(buf->offset < buf->size) { buf->buffer[buf->offset] = byte; params[1] = NULL; } else { params[1] = params[0]; params[1] = NULL; } return 0; } int vis_buffer_putshort(datum ** params, queue_entry * entry) { fixed_buffer * buf = params[0]->c.generic.data; short * wordbuf; short word = params[1]->c.integers.num_a; release_ref(params[1]); if(buf->offset < buf->size) { wordbuf = (short *)buf->buffer; wordbuf[buf->offset >> 1] = word; params[1] = NULL; buf->offset += 2; } else { params[1] = params[0]; params[1] = NULL; } return 0; } int vis_buffer_writeshort(datum ** params, queue_entry * entry) { fixed_buffer * buf = params[0]->c.generic.data; short * wordbuf; short word = params[1]->c.integers.num_a; release_ref(params[1]); if(buf->offset < buf->size) { wordbuf = (short *)buf->buffer; wordbuf[buf->offset >> 1] = word; params[1] = NULL; } else { params[1] = params[0]; params[1] = NULL; } return 0; } int vis_buffer_putlong(datum ** params, queue_entry * entry) { fixed_buffer * buf = params[0]->c.generic.data; long * longbuf; long lword = params[1]->c.integers.num_a; release_ref(params[1]); if(buf->offset < buf->size) { longbuf = (long *)buf->buffer; longbuf[buf->offset >> 2] = lword; params[1] = NULL; buf->offset += 4; } else { params[1] = params[0]; params[1] = NULL; } return 0; } int vis_buffer_writelong(datum ** params, queue_entry * entry) { fixed_buffer * buf = params[0]->c.generic.data; long * longbuf; long lword = params[1]->c.integers.num_a; release_ref(params[1]); if(buf->offset < buf->size) { longbuf = (long *)buf->buffer; longbuf[buf->offset >> 2] = lword; params[1] = NULL; } else { params[1] = params[0]; params[1] = NULL; } return 0; } int vis_buffer_reset(datum ** params, queue_entry * entry) { fixed_buffer * buf = params[0]->c.generic.data; buf->offset = 0; return 0; } #if defined(SEGA) | defined(NINTENDO_DS) int vis_buffer_fromaddress(datum ** params, queue_entry * entry) { char buffer; datum * out; int size = params[1]->c.integers.num_a; fixed_buffer * buf; release_ref(params[1]); out = new_datum(BUILTIN_TYPE_BUFFER, 1, sizeof(fixed_buffer), entry->instance->def->program); buf = out->c.generic.data; buf->offset = 0; buf->buffer = (char *)(params[0]->c.integers.num_a); buf->size = size; VIS_InitializeCriticalSection(buf->lock); release_ref(params[0]); params[0] = out; return 0; } #endif