aboutsummaryrefslogtreecommitdiffhomepage
path: root/midimonster.c
diff options
context:
space:
mode:
authorcbdev <cb@cbcdn.com>2017-06-05 18:53:41 +0200
committercbdev <cb@cbcdn.com>2017-06-05 18:53:41 +0200
commit40e123db7713b188162cd94d935f7a395405567a (patch)
treef745b15d41af6a38b675bdbe2de6473657c7e212 /midimonster.c
parented55916e772264dc8278fc8c96d4139aec31e89e (diff)
downloadmidimonster-40e123db7713b188162cd94d935f7a395405567a.tar.gz
midimonster-40e123db7713b188162cd94d935f7a395405567a.tar.bz2
midimonster-40e123db7713b188162cd94d935f7a395405567a.zip
Core select loop
Diffstat (limited to 'midimonster.c')
-rw-r--r--midimonster.c106
1 files changed, 104 insertions, 2 deletions
diff --git a/midimonster.c b/midimonster.c
index 367ca6f..2c3013d 100644
--- a/midimonster.c
+++ b/midimonster.c
@@ -1,4 +1,8 @@
#include <string.h>
+#include <signal.h>
+#include <sys/select.h>
+#include <unistd.h>
+#include <errno.h>
#include "midimonster.h"
#include "config.h"
#include "backend.h"
@@ -10,6 +14,13 @@ int osc_init();
static size_t mappings = 0;
static channel_mapping* map = NULL;
+static size_t fds = 0;
+static managed_fd* fd = NULL;
+volatile static sig_atomic_t shutdown_requested = 0;
+
+void signal_handler(int signum){
+ shutdown_requested = 1;
+}
int mm_map_channel(channel* from, channel* to){
size_t u, m;
@@ -60,6 +71,68 @@ void map_free(){
map = NULL;
}
+int mm_manage_fd(int new_fd, char* back, int manage, void* impl){
+ backend* b = backend_match(back);
+ size_t u;
+
+ if(!b){
+ fprintf(stderr, "Unknown backend %s registered for managed fd\n", back);
+ return 1;
+ }
+
+ //find exact match
+ for(u = 0; u < fds; u++){
+ if(fd[u].fd == new_fd && fd[u].backend == b){
+ if(!manage){
+ fd[u].fd = -1;
+ fd[u].backend = NULL;
+ fd[u].impl = NULL;
+ }
+ return 0;
+ }
+ }
+
+ if(!manage){
+ return 0;
+ }
+
+ //find free slot
+ for(u = 0; u < fds; u++){
+ if(fd[u].fd < 0){
+ break;
+ }
+ }
+ //if necessary expand
+ if(u == fds){
+ fd = realloc(fd, (fds + 1) * sizeof(managed_fd));
+ if(!fd){
+ fprintf(stderr, "Failed to allocate memory\n");
+ return 1;
+ }
+ fds++;
+ }
+
+ //store new fd
+ fd[u].fd = new_fd;
+ fd[u].backend = b;
+ fd[u].impl = impl;
+ return 0;
+}
+
+void fds_free(){
+ size_t u;
+ for(u = 0; u < fds; u++){
+ //TODO free impl
+ if(fd[u].fd >= 0){
+ close(fd[u].fd);
+ fd[u].fd = -1;
+ }
+ }
+ free(fd);
+ fds = 0;
+ fd = NULL;
+}
+
int usage(char* fn){
fprintf(stderr, "MIDIMonster v0.1\n");
fprintf(stderr, "Usage:\n");
@@ -68,7 +141,10 @@ int usage(char* fn){
}
int main(int argc, char** argv){
- int rv = EXIT_FAILURE;
+ fd_set all_fds, read_fds;
+ struct timeval tv;
+ size_t u;
+ int rv = EXIT_FAILURE, error, maxfd = -1;
char* cfg_file = DEFAULT_CFG;
if(argc > 1){
cfg_file = argv[1];
@@ -88,6 +164,7 @@ int main(int argc, char** argv){
channels_free();
instances_free();
map_free();
+ fds_free();
return usage(argv[0]);
}
@@ -97,7 +174,31 @@ int main(int argc, char** argv){
goto bail;
}
- //TODO wait for & translate events
+ signal(SIGINT, signal_handler);
+
+ //create initial fd set
+ FD_ZERO(&all_fds);
+ for(u = 0; u < fds; u++){
+ if(fd[u].fd >= 0){
+ FD_SET(fd[u].fd, &all_fds);
+ maxfd = max(maxfd, fd[u].fd);
+ }
+ }
+
+ //process events
+ while(!shutdown_requested){
+ //wait for & translate events
+ read_fds = all_fds;
+ tv = backend_timeout();
+ error = select(maxfd + 1, &read_fds, NULL, NULL, &tv);
+ if(error < 0){
+ fprintf(stderr, "select failed: %s\n", strerror(errno));
+ break;
+ }
+ //TODO process all backends, collect events
+ //TODO push all events to backends
+ //FIXME notify non-fd backends
+ }
rv = EXIT_SUCCESS;
bail:
@@ -106,6 +207,7 @@ bail:
channels_free();
instances_free();
map_free();
+ fds_free();
return rv;
}