Fix a few race conditions and handle unloadable samples better

This commit is contained in:
Nick Lanham 2012-02-07 21:08:33 +01:00
parent 88081691c3
commit 4809e697c0
2 changed files with 17 additions and 8 deletions

16
drmr.c
View File

@ -62,12 +62,14 @@ static void* load_thread(void* arg) {
for(;;) { for(;;) {
pthread_cond_wait(&drmr->load_cond, pthread_cond_wait(&drmr->load_cond,
&drmr->load_mutex); &drmr->load_mutex);
if (drmr->curKit >= drmr->kits->num_kits) { int request = (int)floorf(*(drmr->kitReq));
if (request >= drmr->kits->num_kits) {
int os = drmr->num_samples; int os = drmr->num_samples;
drmr->num_samples = 0; drmr->num_samples = 0;
if (os > 0) free_samples(drmr->samples,os); if (os > 0) free_samples(drmr->samples,os);
} else } else
load_hydrogen_kit(drmr,drmr->kits->kits[drmr->curKit].path); load_hydrogen_kit(drmr,drmr->kits->kits[request].path);
drmr->curKit = request;
} }
pthread_mutex_unlock(&drmr->load_mutex); pthread_mutex_unlock(&drmr->load_mutex);
return 0; return 0;
@ -212,10 +214,8 @@ static void run(LV2_Handle instance, uint32_t n_samples) {
DrMr* drmr = (DrMr*)instance; DrMr* drmr = (DrMr*)instance;
kitInt = (int)floorf(*(drmr->kitReq)); kitInt = (int)floorf(*(drmr->kitReq));
if (kitInt != drmr->curKit) { // requested a new kit if (kitInt != drmr->curKit) // requested a new kit
drmr->curKit = kitInt;
pthread_cond_signal(&drmr->load_cond); pthread_cond_signal(&drmr->load_cond);
}
LV2_Event_Iterator eit; LV2_Event_Iterator eit;
if (lv2_event_begin(&eit,drmr->midi_port)) { // if we have any events if (lv2_event_begin(&eit,drmr->midi_port)) { // if we have any events
@ -232,10 +232,14 @@ static void run(LV2_Handle instance, uint32_t n_samples) {
case 9: { case 9: {
uint8_t nn = data[1]; uint8_t nn = data[1];
nn-=60; // middle c is our root note (setting?) nn-=60; // middle c is our root note (setting?)
// need to mutex this to avoid getting the samples array
// changed after the check that the midi-note is valid
pthread_mutex_lock(&drmr->load_mutex);
if (nn >= 0 && nn < drmr->num_samples) { if (nn >= 0 && nn < drmr->num_samples) {
drmr->samples[nn].active = 1; drmr->samples[nn].active = 1;
drmr->samples[nn].offset = 0; drmr->samples[nn].offset = 0;
} }
pthread_mutex_unlock(&drmr->load_mutex);
break; break;
} }
default: default:
@ -247,6 +251,7 @@ static void run(LV2_Handle instance, uint32_t n_samples) {
} }
first_active = 1; first_active = 1;
pthread_mutex_lock(&drmr->load_mutex);
for (i = 0;i < drmr->num_samples;i++) { for (i = 0;i < drmr->num_samples;i++) {
int pos,lim; int pos,lim;
drmr_sample* cs = drmr->samples+i; drmr_sample* cs = drmr->samples+i;
@ -292,6 +297,7 @@ static void run(LV2_Handle instance, uint32_t n_samples) {
if (cs->offset >= cs->limit) cs->active = 0; if (cs->offset >= cs->limit) cs->active = 0;
} }
} }
pthread_mutex_unlock(&drmr->load_mutex);
if (first_active) { // didn't find any samples if (first_active) { // didn't find any samples
int pos; int pos;
for(pos = 0;pos<n_samples;pos++) { for(pos = 0;pos<n_samples;pos++) {

View File

@ -253,6 +253,7 @@ kits* scan_kits() {
void free_samples(drmr_sample* samples, int num_samples) { void free_samples(drmr_sample* samples, int num_samples) {
int i; int i;
for (i=0;i<num_samples;i++) for (i=0;i<num_samples;i++)
if (samples[i].data)
free(samples[i].data); free(samples[i].data);
free(samples); free(samples);
} }
@ -316,8 +317,10 @@ int load_hydrogen_kit(DrMr* drmr, char* path) {
snprintf(buf,BUFSIZ,"%s/%s",path,cur_i->filename); snprintf(buf,BUFSIZ,"%s/%s",path,cur_i->filename);
if (load_sample(buf,samples+i)) { if (load_sample(buf,samples+i)) {
fprintf(stderr,"Could not load sample: %s\n",buf); fprintf(stderr,"Could not load sample: %s\n",buf);
// TODO: Memory leak on previously loaded samples samples[i].offset = 0;
return 1; // set limit to zero, will never try and play
samples[i].limit = 0;
samples[i].data = NULL;
} }
i++; i++;
cur_i = cur_i->next; cur_i = cur_i->next;