From 8ebc4311185e3329622ad883dde54409fa1c8350 Mon Sep 17 00:00:00 2001 From: cbdev Date: Sun, 9 Feb 2020 11:50:41 +0100 Subject: Mention release page in installer section, move images around --- TODO | 1 + 1 file changed, 1 insertion(+) (limited to 'TODO') diff --git a/TODO b/TODO index ee58777..3a78b9b 100644 --- a/TODO +++ b/TODO @@ -5,3 +5,4 @@ udp backends may ignore MTU mm_managed_fd.impl is not freed currently (and is heaped most of the time anyway) -> documentation make event collectors threadsafe to stop marshalling data... collect & check backend API version +windows strerror -- cgit v1.2.3 From b529f4d3a9efc59c6bec46e07ebf1a114b7a0831 Mon Sep 17 00:00:00 2001 From: cbdev Date: Sat, 22 Feb 2020 13:45:34 +0100 Subject: Update logo --- MIDIMonster.svg | 2 +- README.md | 2 +- TODO | 1 + midimonster.ico | Bin 5430 -> 321510 bytes 4 files changed, 3 insertions(+), 2 deletions(-) (limited to 'TODO') diff --git a/MIDIMonster.svg b/MIDIMonster.svg index 492feb5..7e411dc 100644 --- a/MIDIMonster.svg +++ b/MIDIMonster.svg @@ -1 +1 @@ -Asset 1 \ No newline at end of file +Asset 3 \ No newline at end of file diff --git a/README.md b/README.md index 4ab20a3..46331f3 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ with additional flexibility provided by a [Lua scripting environment](backends/l With these features, the MIDIMonster allows the user to translate any channel on one protocol into channel(s) on any other (or the same) supported protocol, for example to: -* Translate MIDI Control Changes into Notes ([Example configuration](configs/unifest-17.cfg)) +* Translate MIDI Control Changes into MIDI Notes ([Example configuration](configs/unifest-17.cfg)) * Translate MIDI Notes into ArtNet or sACN ([Example configuration](configs/launchctl-sacn.cfg)) * Translate OSC messages into MIDI ([Example configuration](configs/midi-osc.cfg)) * Dynamically generate, route and modify events using the Lua programming language ([Example configuration](configs/lua.cfg) and [Script](configs/demo.lua)) diff --git a/TODO b/TODO index 3a78b9b..900cc1b 100644 --- a/TODO +++ b/TODO @@ -6,3 +6,4 @@ mm_managed_fd.impl is not freed currently (and is heaped most of the time anyway make event collectors threadsafe to stop marshalling data... collect & check backend API version windows strerror +move all connection establishment to _start to be able to hot-stop/start all backends diff --git a/midimonster.ico b/midimonster.ico index 012fef6..9391160 100644 Binary files a/midimonster.ico and b/midimonster.ico differ -- cgit v1.2.3 From d757a9c63371fcf5f9aa832d58ed4b8bdf634909 Mon Sep 17 00:00:00 2001 From: cbdev Date: Tue, 10 Mar 2020 20:42:55 +0100 Subject: Restructure core loop, add check for zero-descriptor case --- TODO | 1 + backend.c | 3 + midimonster.c | 197 ++++++++++++++++++++++++++++++++++++---------------------- 3 files changed, 125 insertions(+), 76 deletions(-) (limited to 'TODO') diff --git a/TODO b/TODO index 900cc1b..1ea91f4 100644 --- a/TODO +++ b/TODO @@ -7,3 +7,4 @@ make event collectors threadsafe to stop marshalling data... collect & check backend API version windows strerror move all connection establishment to _start to be able to hot-stop/start all backends +only call _handle and _interval on backends with instances diff --git a/backend.c b/backend.c index e9c3829..ef8f66a 100644 --- a/backend.c +++ b/backend.c @@ -4,6 +4,7 @@ #else #define MM_API __attribute__((dllexport)) #endif +#define BACKEND_NAME "core/be" #include "midimonster.h" #include "backend.h" @@ -227,10 +228,12 @@ struct timeval backend_timeout(){ if(backends[u].interval){ res = backends[u].interval(); if((res / 1000) < secs){ + DBGPF("Updating interval to %" PRIu32 " msecs by request from %s", res, backends[u].name); secs = res / 1000; msecs = res % 1000; } else if(res / 1000 == secs && (res % 1000) < msecs){ + DBGPF("Updating interval to %" PRIu32 " msecs by request from %s", res, backends[u].name); msecs = res % 1000; } } diff --git a/midimonster.c b/midimonster.c index b8594b4..3212f7f 100644 --- a/midimonster.c +++ b/midimonster.c @@ -9,6 +9,7 @@ #else #define MM_API __attribute__((dllexport)) #endif +#define BACKEND_NAME "core" #include "midimonster.h" #include "config.h" #include "backend.h" @@ -325,18 +326,126 @@ static int args_parse(int argc, char** argv, char** cfg_file){ return 0; } -int main(int argc, char** argv){ - fd_set all_fds, read_fds; +static int core_process(size_t nfds, managed_fd* signaled_fds){ event_collection* secondary = NULL; - struct timeval tv; - size_t u, n; + size_t u; + + //run backend processing, collect events + DBGPF("%lu backend FDs signaled\n", nfds); + if(backends_handle(nfds, signaled_fds)){ + return 1; + } + + while(primary->n){ + //swap primary and secondary event collectors + DBGPF("Swapping event collectors, %lu events in primary\n", primary->n); + for(u = 0; u < sizeof(event_pool) / sizeof(event_collection); u++){ + if(primary != event_pool + u){ + secondary = primary; + primary = event_pool + u; + break; + } + } + + //push collected events to target backends + if(secondary->n && backends_notify(secondary->n, secondary->channel, secondary->value)){ + fprintf(stderr, "Backends failed to handle output\n"); + return 1; + } + + //reset the event count + secondary->n = 0; + } + + return 0; +} + +static int core_loop(){ + fd_set all_fds, read_fds; managed_fd* signaled_fds = NULL; - int rv = EXIT_FAILURE, error, maxfd = -1; - char* cfg_file = DEFAULT_CFG; + struct timeval tv; + int error, maxfd = -1; + size_t n, u; #ifdef _WIN32 char* error_message = NULL; + #else + struct timespec ts; #endif + FD_ZERO(&all_fds); + + //process events + while(!shutdown_requested){ + //rebuild fd set if necessary + if(fd_set_dirty){ + all_fds = fds_collect(&maxfd); + signaled_fds = realloc(signaled_fds, fds * sizeof(managed_fd)); + if(!signaled_fds){ + fprintf(stderr, "Failed to allocate memory\n"); + return 1; + } + fd_set_dirty = 0; + } + + //wait for & translate events + read_fds = all_fds; + tv = backend_timeout(); + + //check whether there are any fds active, windows does not like select() without descriptors + if(maxfd >= 0){ + error = select(maxfd + 1, &read_fds, NULL, NULL, &tv); + if(error < 0){ + #ifndef _WIN32 + fprintf(stderr, "select failed: %s\n", strerror(errno)); + #else + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, WSAGetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &error_message, 0, NULL); + fprintf(stderr, "select failed: %s\n", error_message); + LocalFree(error_message); + error_message = NULL; + #endif + free(signaled_fds); + return 1; + } + } + else{ + DBGPF("No descriptors, sleeping for %zu msec", tv.tv_sec * 1000 + tv.tv_usec / 1000); + #ifdef _WIN32 + Sleep(tv.tv_sec * 1000 + tv.tv_usec / 1000); + #else + ts.tv_sec = tv.tv_sec; + ts.tv_nsec = tv.tv_usec * 1000; + error = nanosleep(&ts, NULL); + #endif + } + + //update this iteration's timestamp + update_timestamp(); + + //find all signaled fds + n = 0; + for(u = 0; u < fds; u++){ + if(fd[u].fd >= 0 && FD_ISSET(fd[u].fd, &read_fds)){ + signaled_fds[n] = fd[u]; + n++; + } + } + + //fetch and process events + if(core_process(n, signaled_fds)){ + free(signaled_fds); + return 1; + } + } + + free(signaled_fds); + return 0; +} + +int main(int argc, char** argv){ + int rv = EXIT_FAILURE; + char* cfg_file = DEFAULT_CFG; + //parse commandline arguments if(args_parse(argc, argv, &cfg_file)){ return EXIT_FAILURE; @@ -347,7 +456,6 @@ int main(int argc, char** argv){ return EXIT_FAILURE; } - FD_ZERO(&all_fds); //initialize backends if(plugins_load(PLUGINS)){ fprintf(stderr, "Failed to initialize a backend\n"); @@ -377,80 +485,17 @@ int main(int argc, char** argv){ signal(SIGINT, signal_handler); - //process events - while(!shutdown_requested){ - //rebuild fd set if necessary - if(fd_set_dirty){ - all_fds = fds_collect(&maxfd); - signaled_fds = realloc(signaled_fds, fds * sizeof(managed_fd)); - if(!signaled_fds){ - fprintf(stderr, "Failed to allocate memory\n"); - goto bail; - } - fd_set_dirty = 0; - } - - //wait for & translate events - read_fds = all_fds; - tv = backend_timeout(); - error = select(maxfd + 1, &read_fds, NULL, NULL, &tv); - if(error < 0){ - #ifndef _WIN32 - fprintf(stderr, "select failed: %s\n", strerror(errno)); - #else - FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, WSAGetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &error_message, 0, NULL); - fprintf(stderr, "select failed: %s\n", error_message); - LocalFree(error_message); - error_message = NULL; - #endif - break; - } - - //find all signaled fds - n = 0; - for(u = 0; u < fds; u++){ - if(fd[u].fd >= 0 && FD_ISSET(fd[u].fd, &read_fds)){ - signaled_fds[n] = fd[u]; - n++; - } - } - - //update this iteration's timestamp - update_timestamp(); - - //run backend processing, collect events - DBGPF("%lu backend FDs signaled\n", n); - if(backends_handle(n, signaled_fds)){ - goto bail; - } - - while(primary->n){ - //swap primary and secondary event collectors - DBGPF("Swapping event collectors, %lu events in primary\n", primary->n); - for(u = 0; u < sizeof(event_pool) / sizeof(event_collection); u++){ - if(primary != event_pool + u){ - secondary = primary; - primary = event_pool + u; - break; - } - } - - //push collected events to target backends - if(secondary->n && backends_notify(secondary->n, secondary->channel, secondary->value)){ - fprintf(stderr, "Backends failed to handle output\n"); - goto bail; - } + if(!fds){ + fprintf(stderr, "No descriptors registered for multiplexing\n"); + } - //reset the event count - secondary->n = 0; - } + //run the core loop + if(!core_loop()){ + rv = EXIT_SUCCESS; } - rv = EXIT_SUCCESS; bail: //free all data - free(signaled_fds); backends_stop(); channels_free(); instances_free(); -- cgit v1.2.3 From 05cdf563fcc4c7835ec422fa5d7ee86b68a9f1df Mon Sep 17 00:00:00 2001 From: cbdev Date: Sat, 14 Mar 2020 21:45:09 +0100 Subject: Restructure backend and instance registry --- TODO | 1 - backend.c | 268 +++++++++++++++++++++++++++++------------------------- backend.h | 4 +- backends/artnet.c | 5 - backends/sacn.c | 5 - config.c | 2 +- 6 files changed, 147 insertions(+), 138 deletions(-) (limited to 'TODO') diff --git a/TODO b/TODO index 1ea91f4..900cc1b 100644 --- a/TODO +++ b/TODO @@ -7,4 +7,3 @@ make event collectors threadsafe to stop marshalling data... collect & check backend API version windows strerror move all connection establishment to _start to be able to hot-stop/start all backends -only call _handle and _interval on backends with instances diff --git a/backend.c b/backend.c index ef8f66a..65cbd7d 100644 --- a/backend.c +++ b/backend.c @@ -8,10 +8,15 @@ #include "midimonster.h" #include "backend.h" -static size_t nbackends = 0; -static backend* backends = NULL; -static size_t ninstances = 0; -static instance** instances = NULL; +static struct { + size_t n; + backend* backends; + instance*** instances; +} registry = { + .n = 0 +}; + +//TODO move channel store into registry static size_t nchannels = 0; static channel** channels = NULL; @@ -20,11 +25,11 @@ int backends_handle(size_t nfds, managed_fd* fds){ int rv = 0; managed_fd xchg; - for(u = 0; u < nbackends && !rv; u++){ + for(u = 0; u < registry.n && !rv; u++){ n = 0; for(p = 0; p < nfds; p++){ - if(fds[p].backend == backends + u){ + if(fds[p].backend == registry.backends + u){ xchg = fds[n]; fds[n] = fds[p]; fds[p] = xchg; @@ -32,10 +37,13 @@ int backends_handle(size_t nfds, managed_fd* fds){ } } - DBGPF("Notifying backend %s of %lu waiting FDs\n", backends[u].name, n); - rv |= backends[u].process(n, fds); - if(rv){ - fprintf(stderr, "Backend %s failed to handle input\n", backends[u].name); + //handle if there is data ready or the backend has active instances for polling + if(n || registry.instances[u]){ + DBGPF("Notifying backend %s of %" PRIsize_t " waiting FDs\n", registry.backends[u].name, n); + rv |= registry.backends[u].process(n, fds); + if(rv){ + fprintf(stderr, "Backend %s failed to handle input\n", registry.backends[u].name); + } } } return rv; @@ -45,28 +53,29 @@ int backends_notify(size_t nev, channel** c, channel_value* v){ size_t u, p, n; int rv = 0; channel_value xval; - channel* xchnl; - - //TODO eliminate duplicates - for(u = 0; u < ninstances && !rv; u++){ - n = 0; + channel* xchnl = NULL; - for(p = 0; p < nev; p++){ - if(c[p]->instance == instances[u]){ - xval = v[n]; - xchnl = c[n]; + for(u = 0; u < nev && !rv; u++){ + //sort for this instance + n = u + 1; + for(p = u + 1; p < nev; p++){ + if(c[p]->instance == c[u]->instance){ + xval = v[p]; + xchnl = c[p]; - v[n] = v[p]; - c[n] = c[p]; + v[p] = v[n]; + c[p] = c[n]; - v[p] = xval; - c[p] = xchnl; + v[n] = xval; + c[n] = xchnl; n++; } } - DBGPF("Calling handler for instance %s with %lu events\n", instances[u]->name, n); - rv |= instances[u]->backend->handle(instances[u], n, c, v); + //TODO eliminate duplicates + DBGPF("Calling handler for instance %s with %" PRIsize_t " events\n", c[u]->instance->name, n - u); + rv |= c[u]->instance->backend->handle(c[u]->instance, n - u, c + u, v + u); + u = n; } return 0; @@ -76,17 +85,17 @@ MM_API channel* mm_channel(instance* inst, uint64_t ident, uint8_t create){ size_t u; for(u = 0; u < nchannels; u++){ if(channels[u]->instance == inst && channels[u]->ident == ident){ - DBGPF("Requested channel %lu on instance %s already exists, reusing\n", ident, inst->name); + DBGPF("Requested channel %" PRIu64 " on instance %s already exists, reusing\n", ident, inst->name); return channels[u]; } } if(!create){ - DBGPF("Requested unknown channel %lu on instance %s\n", ident, inst->name); + DBGPF("Requested unknown channel %" PRIu64 " on instance %s\n", ident, inst->name); return NULL; } - DBGPF("Creating previously unknown channel %lu on instance %s\n", ident, inst->name); + DBGPF("Creating previously unknown channel %" PRIu64 " on instance %s\n", ident, inst->name); channel** new_chan = realloc(channels, (nchannels + 1) * sizeof(channel*)); if(!new_chan){ fprintf(stderr, "Failed to allocate memory\n"); @@ -106,34 +115,46 @@ MM_API channel* mm_channel(instance* inst, uint64_t ident, uint8_t create){ return channels[nchannels++]; } -instance* mm_instance(){ - instance** new_inst = realloc(instances, (ninstances + 1) * sizeof(instance*)); - if(!new_inst){ - //TODO free - fprintf(stderr, "Failed to allocate memory\n"); - ninstances = 0; - return NULL; - } - instances = new_inst; - instances[ninstances] = calloc(1, sizeof(instance)); - if(!instances[ninstances]){ - fprintf(stderr, "Failed to allocate memory\n"); - return NULL; +instance* mm_instance(backend* b){ + size_t u = 0, n = 0; + + for(u = 0; u < registry.n; u++){ + if(registry.backends + u == b){ + //count existing instances + for(n = 0; registry.instances[u] && registry.instances[u][n]; n++){ + } + + //extend + registry.instances[u] = realloc(registry.instances[u], (n + 2) * sizeof(instance*)); + if(!registry.instances[u]){ + fprintf(stderr, "Failed to allocate memory\n"); + return NULL; + } + //sentinel + registry.instances[u][n + 1] = NULL; + registry.instances[u][n] = calloc(1, sizeof(instance)); + if(!registry.instances[u][n]){ + fprintf(stderr, "Failed to allocate memory\n"); + } + registry.instances[u][n]->backend = b; + return registry.instances[u][n]; + } } - return instances[ninstances++]; + //this should never happen + return NULL; } MM_API instance* mm_instance_find(char* name, uint64_t ident){ - size_t u; - backend* b = backend_match(name); - if(!b){ - return NULL; - } - - for(u = 0; u < ninstances; u++){ - if(instances[u]->backend == b && instances[u]->ident == ident){ - return instances[u]; + size_t b = 0; + instance** iter = NULL; + for(b = 0; b < registry.n; b++){ + if(!strcmp(registry.backends[b].name, name)){ + for(iter = registry.instances[b]; iter && *iter; iter++){ + if((*iter)->ident == ident){ + return *iter; + } + } } } @@ -141,55 +162,40 @@ MM_API instance* mm_instance_find(char* name, uint64_t ident){ } MM_API int mm_backend_instances(char* name, size_t* ninst, instance*** inst){ - backend* b = backend_match(name); - size_t n = 0, u; - //count number of affected instances - for(u = 0; u < ninstances; u++){ - if(instances[u]->backend == b){ - n++; - } + size_t b = 0, i = 0; + if(!ninst || !inst){ + return 1; } - *ninst = n; + for(b = 0; b < registry.n; b++){ + if(!strcmp(registry.backends[b].name, name)){ + //count instances + for(i = 0; registry.instances[b] && registry.instances[b][i]; i++){ + } - if(!n){ - *inst = NULL; - return 0; - } + *ninst = i; + if(!i){ + *inst = NULL; + return 0; + } - *inst = calloc(n, sizeof(instance*)); - if(!*inst){ - fprintf(stderr, "Failed to allocate memory\n"); - return 1; - } + *inst = calloc(i, sizeof(instance*)); + if(!*inst){ + fprintf(stderr, "Failed to allocate memory\n"); + return 1; + } - n = 0; - for(u = 0; u < ninstances; u++){ - if(instances[u]->backend == b){ - (*inst)[n] = instances[u]; - n++; + memcpy(*inst, registry.instances[b], i * sizeof(instance*)); + return 0; } } - return 0; -} - -void instances_free(){ - size_t u; - for(u = 0; u < ninstances; u++){ - free(instances[u]->name); - instances[u]->name = NULL; - instances[u]->backend = NULL; - free(instances[u]); - instances[u] = NULL; - } - free(instances); - ninstances = 0; + return 1; } void channels_free(){ size_t u; for(u = 0; u < nchannels; u++){ - DBGPF("Destroying channel %lu on instance %s\n", channels[u]->ident, channels[u]->instance->name); + DBGPF("Destroying channel %" PRIu64 " on instance %s\n", channels[u]->ident, channels[u]->instance->name); if(channels[u]->impl && channels[u]->instance->backend->channel_free){ channels[u]->instance->backend->channel_free(channels[u]); } @@ -200,11 +206,12 @@ void channels_free(){ nchannels = 0; } + backend* backend_match(char* name){ size_t u; - for(u = 0; u < nbackends; u++){ - if(!strcmp(backends[u].name, name)){ - return backends + u; + for(u = 0; u < registry.n; u++){ + if(!strcmp(registry.backends[u].name, name)){ + return registry.backends + u; } } return NULL; @@ -212,9 +219,12 @@ backend* backend_match(char* name){ instance* instance_match(char* name){ size_t u; - for(u = 0; u < ninstances; u++){ - if(!strcmp(instances[u]->name, name)){ - return instances[u]; + instance** iter = NULL; + for(u = 0; u < registry.n; u++){ + for(iter = registry.instances[u]; iter && *iter; iter++){ + if(!strcmp(name, (*iter)->name)){ + return *iter; + } } } return NULL; @@ -224,16 +234,17 @@ struct timeval backend_timeout(){ size_t u; uint32_t res, secs = 1, msecs = 0; - for(u = 0; u < nbackends; u++){ - if(backends[u].interval){ - res = backends[u].interval(); + for(u = 0; u < registry.n; u++){ + //only call interval if backend has instances + if(registry.instances[u] && registry.backends[u].interval){ + res = registry.backends[u].interval(); if((res / 1000) < secs){ - DBGPF("Updating interval to %" PRIu32 " msecs by request from %s", res, backends[u].name); + DBGPF("Updating interval to %" PRIu32 " msecs by request from %s", res, registry.backends[u].name); secs = res / 1000; msecs = res % 1000; } else if(res / 1000 == secs && (res % 1000) < msecs){ - DBGPF("Updating interval to %" PRIu32 " msecs by request from %s", res, backends[u].name); + DBGPF("Updating interval to %" PRIu32 " msecs by request from %s", res, registry.backends[u].name); msecs = res % 1000; } } @@ -248,14 +259,16 @@ struct timeval backend_timeout(){ MM_API int mm_backend_register(backend b){ if(!backend_match(b.name)){ - backends = realloc(backends, (nbackends + 1) * sizeof(backend)); - if(!backends){ + registry.backends = realloc(registry.backends, (registry.n + 1) * sizeof(backend)); + registry.instances = realloc(registry.instances, (registry.n + 1) * sizeof(instance**)); + if(!registry.backends || !registry.instances){ fprintf(stderr, "Failed to allocate memory\n"); - nbackends = 0; + registry.n = 0; return 1; } - backends[nbackends] = b; - nbackends++; + registry.backends[registry.n] = b; + registry.instances[registry.n] = NULL; + registry.n++; fprintf(stderr, "Registered backend %s\n", b.name); return 0; @@ -265,29 +278,25 @@ MM_API int mm_backend_register(backend b){ int backends_start(){ int rv = 0, current; - size_t n, u, p; instance** inst = NULL; + size_t n, u; - for(u = 0; u < nbackends; u++){ - //only start backends that have instances - for(p = 0; p < ninstances && instances[p]->backend != backends + u; p++){ - } - - //backend has no instances, skip the start call - if(p == ninstances){ + for(u = 0; u < registry.n; u++){ + //skip backends without instances + if(!registry.instances[u]){ continue; } //fetch list of instances - if(mm_backend_instances(backends[u].name, &n, &inst)){ - fprintf(stderr, "Failed to fetch instance list for initialization of backend %s\n", backends[u].name); + if(mm_backend_instances(registry.backends[u].name, &n, &inst)){ + fprintf(stderr, "Failed to fetch instance list for initialization of backend %s\n", registry.backends[u].name); return 1; } //start the backend - current = backends[u].start(n, inst); + current = registry.backends[u].start(n, inst); if(current){ - fprintf(stderr, "Failed to start backend %s\n", backends[u].name); + fprintf(stderr, "Failed to start backend %s\n", registry.backends[u].name); } //clean up @@ -302,20 +311,33 @@ int backends_stop(){ size_t u, n; instance** inst = NULL; - for(u = 0; u < nbackends; u++){ + //shut down the registry + for(u = 0; u < registry.n; u++){ //fetch list of instances - if(mm_backend_instances(backends[u].name, &n, &inst)){ - fprintf(stderr, "Failed to fetch instance list for shutdown of backend %s\n", backends[u].name); - n = 0; + if(mm_backend_instances(registry.backends[u].name, &n, &inst)){ + fprintf(stderr, "Failed to fetch instance list for shutdown of backend %s\n", registry.backends[u].name); inst = NULL; + n = 0; } - backends[u].shutdown(n, inst); + registry.backends[u].shutdown(n, inst); free(inst); inst = NULL; + + //free instances + for(inst = registry.instances[u]; inst && *inst; inst++){ + free((*inst)->name); + (*inst)->name = NULL; + (*inst)->backend = NULL; + free(*inst); + } + free(registry.instances[u]); + registry.instances[u] = NULL; } - free(backends); - nbackends = 0; + channels_free(); + free(registry.backends); + free(registry.instances); + registry.n = 0; return 0; } diff --git a/backend.h b/backend.h index de9b5dc..6a69508 100644 --- a/backend.h +++ b/backend.h @@ -8,9 +8,7 @@ instance* instance_match(char* name); struct timeval backend_timeout(); int backends_start(); int backends_stop(); -void instances_free(); -void channels_free(); -instance* mm_instance(); +instance* mm_instance(backend* b); /* Backend API */ MM_API channel* mm_channel(instance* inst, uint64_t ident, uint8_t create); diff --git a/backends/artnet.c b/backends/artnet.c index 34fc82d..caab6e0 100644 --- a/backends/artnet.c +++ b/backends/artnet.c @@ -321,11 +321,6 @@ static inline int artnet_process_frame(instance* inst, artnet_pkt* frame){ chan = data->data.channel + MAPPED_CHANNEL(data->data.map[p]); } - if(!chan){ - LOGPF("Active channel %" PRIsize_t " on %s not known to core", p, inst->name); - return 1; - } - if(IS_WIDE(data->data.map[p])){ data->data.map[MAPPED_CHANNEL(data->data.map[p])] &= ~MAP_MARK; wide_val = data->data.in[p] << ((data->data.map[p] & MAP_COARSE) ? 8 : 0); diff --git a/backends/sacn.c b/backends/sacn.c index 495bdf3..bd5c75a 100644 --- a/backends/sacn.c +++ b/backends/sacn.c @@ -436,11 +436,6 @@ static int sacn_process_frame(instance* inst, sacn_frame_root* frame, sacn_frame chan = inst_data->data.channel + MAPPED_CHANNEL(inst_data->data.map[u]); } - if(!chan){ - LOGPF("Active channel %" PRIsize_t " on %s not known to core", u, inst->name); - return 1; - } - //generate value if(IS_WIDE(inst_data->data.map[u])){ inst_data->data.map[MAPPED_CHANNEL(inst_data->data.map[u])] &= ~MAP_MARK; diff --git a/config.c b/config.c index 920e161..aef4f87 100644 --- a/config.c +++ b/config.c @@ -388,7 +388,7 @@ static int config_line(char* line){ return 1; } - current_instance = mm_instance(); + current_instance = mm_instance(current_backend); if(!current_instance){ return 1; } -- cgit v1.2.3