diff options
| author | Lennart Poettering <lennart@poettering.net> | 2004-06-11 21:30:16 +0000 | 
|---|---|---|
| committer | Lennart Poettering <lennart@poettering.net> | 2004-06-11 21:30:16 +0000 | 
| commit | 7dfeb1fc745757f1c2b7bf43bae80cf0f49fc9a6 (patch) | |
| tree | 2876784e67ed6cf3974e7b06771835a8a4162979 | |
| parent | aae40dcea260296d7d02d185b42f9275f34cb238 (diff) | |
make the whole stuff run and clean it self up again
git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@8 fefdeb5f-60dc-0310-8127-8f9354f1896f
| -rw-r--r-- | src/Makefile.am | 39 | ||||
| -rw-r--r-- | src/idxset.c | 8 | ||||
| -rw-r--r-- | src/iochannel.c | 6 | ||||
| -rw-r--r-- | src/main.c | 10 | ||||
| -rw-r--r-- | src/mainloop.c | 138 | ||||
| -rw-r--r-- | src/mainloop.h | 4 | ||||
| -rw-r--r-- | src/module.c | 69 | ||||
| -rw-r--r-- | src/module.h | 2 | ||||
| -rw-r--r-- | src/sink-pipe.c | 2 | ||||
| -rw-r--r-- | src/sink.c | 9 | ||||
| -rw-r--r-- | src/source.c | 6 | 
11 files changed, 189 insertions, 104 deletions
| diff --git a/src/Makefile.am b/src/Makefile.am index c64babb3..485513df 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -20,8 +20,8 @@ AM_CFLAGS=-ansi -D_GNU_SOURCE  bin_PROGRAMS = polypaudio  -pkglib_LTLIBRARIES=protocol-simple.la protocol-simple-tcp.la \ -		socket-server.la sink-pipe.la pstream.la iochannel.la packet.la +pkglib_LTLIBRARIES=libprotocol-simple.la protocol-simple-tcp.la \ +		libsocket-server.la sink-pipe.la libpstream.la libiochannel.la libpacket.la  polypaudio_SOURCES = idxset.c queue.c strbuf.c mainloop.c  \  		memblock.c sample.c memblockq.c client.c \ @@ -31,25 +31,28 @@ polypaudio_INCLUDES = $(INCLTDL)  polypaudio_LDADD = $(LIBLTDL)   polypaudio_LDFLAGS=-export-dynamic -protocol_simple_la_SOURCES = protocol-simple.c -protocol_simple_la_LDFLAGS = -module -avoid-version +libprotocol_simple_la_SOURCES = protocol-simple.c +libprotocol_simple_la_LDFLAGS = -avoid-version +libprotocol_simple_la_LIBADD = libsocket-server.la libiochannel.la -protocol_simple_tcp_la_SOURCES = protocol-simple-tcp.c -protocol_simple_tcp_la_LDFLAGS = -module -avoid-version -protocol_simple_tcp_la_LIBADD = protocol-simple.la socket-server.la - -socket_server_la_SOURCES = socket-server.c -socket_server_la_LDFLAGS = -module -avoid-version +libsocket_server_la_SOURCES = socket-server.c +libsocket_server_la_LDFLAGS = -avoid-version +libsocket_server_la_LIBADD = libiochannel.la -sink_pipe_la_SOURCES = sink-pipe.c -sink_pipe_la_LDFLAGS = -module -avoid-version +libpstream_la_SOURCES = pstream.c +libpstream_la_LDFLAGS = -avoid-version +libpstream_la_LIBADD = libpacket.la -pstream_la_SOURCES = pstream.c -pstream_la_LDFLAGS = -module -avoid-version +libiochannel_la_SOURCES = iochannel.c +libiochannel_la_LDFLAGS = -avoid-version -iochannel_la_SOURCES = pstream.c -iochannel_la_LDFLAGS = -module -avoid-version  +libpacket_la_SOURCES = packet.c +libpacket_la_LDFLAGS = -avoid-version -packet_la_SOURCES = pstream.c -packet_la_LDFLAGS = -module -avoid-version  +protocol_simple_tcp_la_SOURCES = protocol-simple-tcp.c +protocol_simple_tcp_la_LDFLAGS = -module -avoid-version +protocol_simple_tcp_la_LIBADD = libprotocol-simple.la libiochannel.la +sink_pipe_la_SOURCES = sink-pipe.c +sink_pipe_la_LDFLAGS = -module -avoid-version +sink_pipe_la_LIBADD = libiochannel.la diff --git a/src/idxset.c b/src/idxset.c index eaea34f4..f0d7ad87 100644 --- a/src/idxset.c +++ b/src/idxset.c @@ -27,7 +27,7 @@ static unsigned trivial_hash_func(void *p) {  }  static int trivial_compare_func(void *a, void *b) { -    return !(a == b); +    return a != b;  }  struct idxset* idxset_new(unsigned (*hash_func) (void *p), int (*compare_func) (void*a, void*b)) { @@ -40,11 +40,13 @@ struct idxset* idxset_new(unsigned (*hash_func) (void *p), int (*compare_func) (      s->hash_table_size = 1023;      s->hash_table = malloc(sizeof(struct idxset_entry*)*s->hash_table_size);      assert(s->hash_table); +    memset(s->hash_table, 0, sizeof(struct idxset_entry*)*s->hash_table_size);      s->array = NULL;      s->array_size = 0;      s->index = 0;      s->start_index = 0;      s->n_entries = 0; +    s->rrobin = NULL;      s->iterate_list_head = s->iterate_list_tail = NULL; @@ -75,7 +77,7 @@ static struct idxset_entry* hash_scan(struct idxset *s, struct idxset_entry* e,      assert(s->compare_func);      for (; e; e = e->hash_next) -        if (s->compare_func(e->data, p)) +        if (s->compare_func(e->data, p) == 0)              return e;      return NULL; @@ -278,7 +280,7 @@ void* idxset_remove_by_data(struct idxset*s, void *data, uint32_t *index) {  }  void* idxset_rrobin(struct idxset *s, uint32_t *index) { -    assert(s && index); +    assert(s);      if (s->rrobin)          s->rrobin = s->rrobin->iterate_next; diff --git a/src/iochannel.c b/src/iochannel.c index db9717a9..aa7de714 100644 --- a/src/iochannel.c +++ b/src/iochannel.c @@ -156,3 +156,9 @@ ssize_t iochannel_read(struct iochannel*io, void*data, size_t l) {      return r;  } + +void iochannel_set_callback(struct iochannel*io, void (*callback)(struct iochannel*io, void *userdata), void *userdata) { +    assert(io); +    io->callback = callback; +    io->userdata = userdata; +} @@ -1,3 +1,5 @@ +#include <stdio.h> +#include <signal.h>  #include <stddef.h>  #include <assert.h>  #include <ltdl.h> @@ -6,6 +8,11 @@  #include "mainloop.h"  #include "module.h" +static void signal_callback(struct mainloop_source *m, int sig, void *userdata) { +    mainloop_quit(mainloop_source_get_mainloop(m), -1); +    fprintf(stderr, "Got signal.\n"); +} +  int main(int argc, char *argv[]) {      struct mainloop *m;      struct core *c; @@ -19,6 +26,9 @@ int main(int argc, char *argv[]) {      c = core_new(m);      assert(c); +    mainloop_source_new_signal(m, SIGINT, signal_callback, NULL); +    signal(SIGPIPE, SIG_IGN); +      module_load(c, "sink-pipe", NULL);      module_load(c, "protocol-simple-tcp", NULL); diff --git a/src/mainloop.c b/src/mainloop.c index d043ce90..0f5811f2 100644 --- a/src/mainloop.c +++ b/src/mainloop.c @@ -1,7 +1,11 @@ +#include <signal.h> +#include <unistd.h>  #include <sys/poll.h>  #include <stdlib.h>  #include <string.h>  #include <assert.h> +#include <fcntl.h> +#include <errno.h>  #include "mainloop.h" @@ -28,6 +32,12 @@ struct mainloop_source {      struct  {          void (*callback)(struct mainloop_source*s, void *userdata);      } idle; + +    struct { +        int sig; +        struct sigaction sigaction; +        void (*callback)(struct mainloop_source*s, int sig, void *userdata); +    } signal;  };  struct mainloop_source_list { @@ -37,7 +47,7 @@ struct mainloop_source_list {  };  struct mainloop { -    struct mainloop_source_list io_sources, prepare_sources, idle_sources; +    struct mainloop_source_list io_sources, prepare_sources, idle_sources, signal_sources;      struct pollfd *pollfds;      int max_pollfds, n_pollfds; @@ -45,14 +55,43 @@ struct mainloop {      int quit;      int running; +    int signal_pipe[2]; +    struct pollfd signal_pollfd;  }; +static int signal_pipe = -1; + +static void signal_func(int sig) { +    if (signal_pipe >= 0) +        write(signal_pipe, &sig, sizeof(sig)); +} + +static void make_nonblock(int fd) { +    int v; +     +    if ((v = fcntl(fd, F_GETFL)) >= 0) +        fcntl(fd, F_SETFL, v|O_NONBLOCK); +} + +  struct mainloop *mainloop_new(void) { +    int r;      struct mainloop *m;      m = malloc(sizeof(struct mainloop));      assert(m);      memset(m, 0, sizeof(struct mainloop)); + +    r = pipe(m->signal_pipe); +    assert(r >= 0 && m->signal_pipe[0] >= 0 && m->signal_pipe[1] >= 0); + +    make_nonblock(m->signal_pipe[0]); +    make_nonblock(m->signal_pipe[1]); +     +    signal_pipe = m->signal_pipe[1]; +    m->signal_pollfd.fd = m->signal_pipe[0]; +    m->signal_pollfd.events = POLLIN; +    m->signal_pollfd.revents = 0;      return m;  } @@ -61,7 +100,7 @@ static void free_sources(struct mainloop_source_list *l, int all) {      struct mainloop_source *s, *p;      assert(l); -    if (!l->dead_sources) +    if (!all && !l->dead_sources)          return;      p = NULL; @@ -86,7 +125,7 @@ static void free_sources(struct mainloop_source_list *l, int all) {      l->dead_sources = 0;      if (all) { -        assert(l->sources); +        assert(!l->sources);          l->n_sources = 0;      }  } @@ -96,15 +135,23 @@ void mainloop_free(struct mainloop* m) {      free_sources(&m->io_sources, 1);      free_sources(&m->prepare_sources, 1);      free_sources(&m->idle_sources, 1); +    free_sources(&m->signal_sources, 1); + +    if (signal_pipe == m->signal_pipe[1]) +        signal_pipe = -1; +    close(m->signal_pipe[0]); +    close(m->signal_pipe[1]); +          free(m->pollfds); +    free(m);  }  static void rebuild_pollfds(struct mainloop *m) {      struct mainloop_source*s;      struct pollfd *p; -    if (m->max_pollfds < m->io_sources.n_sources) { -        m->max_pollfds = m->io_sources.n_sources*2; +    if (m->max_pollfds < m->io_sources.n_sources+1) { +        m->max_pollfds = (m->io_sources.n_sources+1)*2;          m->pollfds = realloc(m->pollfds, sizeof(struct pollfd)*m->max_pollfds);      } @@ -117,6 +164,9 @@ static void rebuild_pollfds(struct mainloop *m) {              m->n_pollfds++;          }      } + +    *(p++) = m->signal_pollfd; +    m->n_pollfds++;  }  static void dispatch_pollfds(struct mainloop *m) { @@ -128,10 +178,42 @@ static void dispatch_pollfds(struct mainloop *m) {      s = m->io_sources.sources;      for (p = m->pollfds, i = 0; i < m->n_pollfds; p++, i++) { -        for (;;) { -            assert(s && s->type == MAINLOOP_SOURCE_TYPE_IO); +        if (!p->revents) +            continue; + +        if (p->fd == m->signal_pipe[0]) { +            /* Event from signal pipe */ + +            if (p->revents & POLLIN) { +                int sig; +                ssize_t r; +                r = read(m->signal_pipe[0], &sig, sizeof(sig)); +                assert((r < 0 && errno == EAGAIN) || r == sizeof(sig)); -            if (p->fd == s->io.fd) { +                if (r == sizeof(sig)) { +                    struct mainloop_source *l = m->signal_sources.sources; +                    while (l) { +                        assert(l->type == MAINLOOP_SOURCE_TYPE_SIGNAL); +                         +                        if (l->signal.sig == sig && l->enabled && !l->dead) { +                            assert(l->signal.callback); +                            l->signal.callback(l, sig, l->userdata); +                        } +                         +                        l = l->next; +                    } +                } +            } + +        } else { +            /* Event from I/O source */ + +            for (; s; s = s->next) { +                if (p->fd != s->io.fd) +                    continue; +                 +                assert(s->type == MAINLOOP_SOURCE_TYPE_IO); +                  if (!s->dead && s->enabled) {                      enum mainloop_io_event e = (p->revents & POLLIN ? MAINLOOP_IO_EVENT_IN : 0) | (p->revents & POLLOUT ? MAINLOOP_IO_EVENT_OUT : 0);                      if (e) { @@ -142,7 +224,6 @@ static void dispatch_pollfds(struct mainloop *m) {                  break;              } -            s = s->next;          }      }  } @@ -172,7 +253,11 @@ int mainloop_iterate(struct mainloop *m, int block) {      m->running = 1; -    if ((c = poll(m->pollfds, m->n_pollfds, (block && !m->idle_sources.n_sources) ? -1 : 0)) > 0) +    do { +        c = poll(m->pollfds, m->n_pollfds, (block && !m->idle_sources.n_sources) ? -1 : 0); +    } while (c < 0 && errno == EINTR); +         +    if (c > 0)          dispatch_pollfds(m);      else if (c == 0) {          for (s = m->idle_sources.sources; s; s = s->next) { @@ -212,6 +297,9 @@ static struct mainloop_source_list* get_source_list(struct mainloop *m, enum mai          case MAINLOOP_SOURCE_TYPE_IDLE:              l = &m->idle_sources;              break; +        case MAINLOOP_SOURCE_TYPE_SIGNAL: +            l = &m->signal_sources; +            break;          default:              l = NULL;              break; @@ -279,7 +367,33 @@ struct mainloop_source* mainloop_source_new_idle(struct mainloop*m, void (*callb      s = source_new(m, MAINLOOP_SOURCE_TYPE_IDLE); -    s->prepare.callback = callback; +    s->idle.callback = callback; +    s->userdata = userdata; +    s->enabled = 1; +    return s; +} + +struct mainloop_source* mainloop_source_new_signal(struct mainloop*m, int sig, void (*callback)(struct mainloop_source *s, int sig, void*userdata), void*userdata) { +    struct mainloop_source* s; +    struct sigaction save_sa, sa; +     +    assert(m && callback); + +    memset(&sa, 0, sizeof(sa)); +    sa.sa_handler = signal_func; +    sa.sa_flags = SA_RESTART; +    sigemptyset(&sa.sa_mask); + +    memset(&save_sa, 0, sizeof(save_sa)); + +    if (sigaction(sig, &sa, &save_sa) < 0) +        return NULL; +     +    s = source_new(m, MAINLOOP_SOURCE_TYPE_SIGNAL); +    s->signal.sig = sig; +    s->signal.sigaction = save_sa; +     +    s->signal.callback = callback;      s->userdata = userdata;      s->enabled = 1;      return s; @@ -299,6 +413,8 @@ void mainloop_source_free(struct mainloop_source*s) {      if (s->type == MAINLOOP_SOURCE_TYPE_IO)          s->mainloop->rebuild_pollfds = 1; +    else if (s->type == MAINLOOP_SOURCE_TYPE_SIGNAL) +        sigaction(s->signal.sig, &s->signal.sigaction, NULL);  }  void mainloop_source_enable(struct mainloop_source*s, int b) { diff --git a/src/mainloop.h b/src/mainloop.h index 72376c72..3c6d7e37 100644 --- a/src/mainloop.h +++ b/src/mainloop.h @@ -14,7 +14,8 @@ enum mainloop_io_event {  enum mainloop_source_type {      MAINLOOP_SOURCE_TYPE_IO,      MAINLOOP_SOURCE_TYPE_PREPARE, -    MAINLOOP_SOURCE_TYPE_IDLE +    MAINLOOP_SOURCE_TYPE_IDLE, +    MAINLOOP_SOURCE_TYPE_SIGNAL  };  struct mainloop *mainloop_new(void); @@ -27,6 +28,7 @@ void mainloop_quit(struct mainloop *m, int r);  struct mainloop_source* mainloop_source_new_io(struct mainloop*m, int fd, enum mainloop_io_event event, void (*callback)(struct mainloop_source*s, int fd, enum mainloop_io_event event, void *userdata), void *userdata);  struct mainloop_source* mainloop_source_new_prepare(struct mainloop*m, void (*callback)(struct mainloop_source *s, void*userdata), void*userdata);  struct mainloop_source* mainloop_source_new_idle(struct mainloop*m, void (*callback)(struct mainloop_source *s, void*userdata), void*userdata); +struct mainloop_source* mainloop_source_new_signal(struct mainloop*m, int sig, void (*callback)(struct mainloop_source *s, int sig, void*userdata), void*userdata);  void mainloop_source_free(struct mainloop_source*s);  void mainloop_source_enable(struct mainloop_source*s, int b); diff --git a/src/module.c b/src/module.c index 4aa9fd68..62204e4c 100644 --- a/src/module.c +++ b/src/module.c @@ -3,66 +3,10 @@  #include <stdlib.h>  #include <assert.h>  #include <string.h> +#include <errno.h>  #include "module.h" - -static void free_deps(struct dependency_module** deps) { -    assert(deps); -     -    while (*deps) { -        struct dependency_module *next = (*deps)->next; -        lt_dlclose((*deps)->dl); -        free(deps); -        *deps = next; -    } -} - -static int load_deps(const char *fname, struct dependency_module **deps) { -    char line[PATH_MAX]; -    FILE *f; -    char depfile[PATH_MAX]; -    assert(fname && deps); - -    snprintf(depfile, sizeof(depfile), "%s.moddep", fname); -     -    if (!(f = fopen(depfile, "r"))) -        return -1; - -    while (fgets(line, sizeof(line)-1, f)) { -        lt_dlhandle dl; -        char *p; -        size_t l; -        struct dependency_module* d; - -        p = line + strspn(line, " \t"); -         -        l = strlen(p); -        if (p[l-1] == '\n') -            p[l-1] = 0; - -        if (*p == '#' || *p == 0) -            continue; - -        load_deps(p, deps); -         -        if (!(dl = lt_dlopenext(p))) { -            free_deps(deps); -            fclose(f); -            return -1; -        } - -        d = malloc(sizeof(struct dependency_module)); -        assert(d); -        d->dl = dl; -        d->next = *deps; -        *deps = d; -    } - -    fclose(f); -    return 0; -} -  struct module* module_load(struct core *c, const char *name, const char *argument) {      struct module *m = NULL;      int r; @@ -72,12 +16,6 @@ struct module* module_load(struct core *c, const char *name, const char *argumen      m = malloc(sizeof(struct module));      assert(m); -    m->dl = NULL; -     -    m->dependencies = NULL; -    if (load_deps(name, &m->dependencies) < 0) -        goto fail; -      if (!(m->dl = lt_dlopenext(name)))          goto fail; @@ -106,10 +44,12 @@ struct module* module_load(struct core *c, const char *name, const char *argumen  fail:      if (m) { +        free(m->argument); +        free(m->name); +                  if (m->dl)              lt_dlclose(m->dl); -        free_deps(&m->dependencies);          free(m);      } @@ -121,7 +61,6 @@ static void module_free(struct module *m) {      m->done(m->core, m);      lt_dlclose(m->dl); -    free_deps(&m->dependencies);      free(m->name);      free(m->argument);      free(m); diff --git a/src/module.h b/src/module.h index d16c25cd..98082194 100644 --- a/src/module.h +++ b/src/module.h @@ -17,8 +17,6 @@ struct module {      uint32_t index;      lt_dlhandle dl; -    struct dependency_module *dependencies; -          int (*init)(struct core *c, struct module*m);      void (*done)(struct core *c, struct module*m); diff --git a/src/sink-pipe.c b/src/sink-pipe.c index 4a8348f8..78ea7bf2 100644 --- a/src/sink-pipe.c +++ b/src/sink-pipe.c @@ -85,7 +85,7 @@ int module_init(struct core *c, struct module*m) {      mkfifo((p = m->argument ? m->argument : "/tmp/musicfifo"), 0777); -    if ((fd = open(p, O_RDWR) < 0)) { +    if ((fd = open(p, O_RDWR)) < 0) {          fprintf(stderr, "open('%s'): %s\n", p, strerror(errno));          goto fail;      } @@ -29,6 +29,8 @@ struct sink* sink_new(struct core *core, const char *name, const struct sample_s      }      s->monitor_source = source_new(core, n, spec); +    free(n); +          s->volume = 0xFF;      s->notify_callback = NULL; @@ -41,12 +43,13 @@ void sink_free(struct sink *s) {      struct input_stream *i;      assert(s); -    idxset_remove_by_data(s->core->sinks, s, NULL); -    source_free(s->monitor_source); -      while ((i = idxset_rrobin(s->input_streams, NULL)))          input_stream_free(i); +    idxset_free(s->input_streams, NULL, NULL); +    idxset_remove_by_data(s->core->sinks, s, NULL); +    source_free(s->monitor_source); +      free(s->name);      free(s);  } diff --git a/src/source.c b/src/source.c index 2f34c461..98df2447 100644 --- a/src/source.c +++ b/src/source.c @@ -34,10 +34,16 @@ static void do_free(void *p, void *userdata) {  };  void source_free(struct source *s) { +    struct output_stream *o;      assert(s); +    while ((o = idxset_rrobin(s->output_streams, NULL))) +        output_stream_free(o); +    idxset_free(s->output_streams, NULL, NULL); +          idxset_remove_by_data(s->core->sources, s, NULL);      idxset_free(s->output_streams, do_free, NULL); +      free(s->name);      free(s);  } | 
