diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/modules/module-oss-mmap.c | 74 | ||||
| -rw-r--r-- | src/modules/module-oss.c | 42 | 
2 files changed, 81 insertions, 35 deletions
diff --git a/src/modules/module-oss-mmap.c b/src/modules/module-oss-mmap.c index cc408f90..08cf1a8d 100644 --- a/src/modules/module-oss-mmap.c +++ b/src/modules/module-oss-mmap.c @@ -117,6 +117,42 @@ static void update_usage(struct userdata *u) {                        (u->source ? pa_idxset_size(u->source->outputs) : 0));  } +static void clear_up(struct userdata *u) { +    assert(u); + +    if (u->sink) { +        pa_sink_disconnect(u->sink); +        pa_sink_unref(u->sink); +        u->sink = NULL; +    } +     +    if (u->source) { +        pa_source_disconnect(u->source); +        pa_source_unref(u->source); +        u->source = NULL; +    } + +    if (u->in_mmap && u->in_mmap != MAP_FAILED) { +        munmap(u->in_mmap, u->in_mmap_length); +        u->in_mmap = NULL; +    } +     +    if (u->out_mmap && u->out_mmap != MAP_FAILED) { +        munmap(u->out_mmap, u->out_mmap_length); +        u->out_mmap = NULL; +    } +     +    if (u->io_event) { +        u->core->mainloop->io_free(u->io_event); +        u->io_event = NULL; +    } + +    if (u->fd >= 0) { +        close(u->fd); +        u->fd = -1; +    } +} +  static void out_fill_memblocks(struct userdata *u, unsigned n) {      assert(u && u->out_memblocks); @@ -154,6 +190,9 @@ static void do_write(struct userdata *u) {      if (ioctl(u->fd, SNDCTL_DSP_GETOPTR, &info) < 0) {          pa_log(__FILE__": SNDCTL_DSP_GETOPTR: %s", pa_cstrerror(errno)); + +        clear_up(u); +        pa_module_unload_request(u->module);          return;      } @@ -217,6 +256,9 @@ static void do_read(struct userdata *u) {      if (ioctl(u->fd, SNDCTL_DSP_GETIPTR, &info) < 0) {          pa_log(__FILE__": SNDCTL_DSP_GETIPTR: %s", pa_cstrerror(errno)); + +        clear_up(u); +        pa_module_unload_request(u->module);          return;      } @@ -234,6 +276,12 @@ static void io_callback(pa_mainloop_api *m, pa_io_event *e, PA_GCC_UNUSED int fd      struct userdata *u = userdata;      assert (u && u->core->mainloop == m && u->io_event == e); +    if (f & PA_IO_EVENT_ERROR) { +        clear_up(u); +        pa_module_unload_request(u->module); +        return; +    } +      if (f & PA_IO_EVENT_INPUT)          do_read(u);      if (f & PA_IO_EVENT_OUTPUT) @@ -393,7 +441,7 @@ int pa__init(pa_core *c, pa_module*m) {      if ((u->fd = pa_oss_open(p = pa_modargs_get_value(ma, "device", DEFAULT_DEVICE), &mode, &caps)) < 0)          goto fail; -    if (!(caps & DSP_CAP_MMAP) || !(caps & DSP_CAP_REALTIME) || !(caps & DSP_CAP_TRIGGER)) { +    if (!(caps & DSP_CAP_MMAP) || !(caps & DSP_CAP_TRIGGER)) {          pa_log(__FILE__": OSS device not mmap capable.");          goto fail;      } @@ -539,6 +587,8 @@ void pa__done(pa_core *c, pa_module*m) {      if (!(u = m->userdata))          return; +    clear_up(u); +      if (u->out_memblocks) {          unsigned i;          for (i = 0; i < u->out_fragments; i++) @@ -555,27 +605,5 @@ void pa__done(pa_core *c, pa_module*m) {          pa_xfree(u->in_memblocks);      } -    if (u->in_mmap && u->in_mmap != MAP_FAILED) -        munmap(u->in_mmap, u->in_mmap_length); -     -    if (u->out_mmap && u->out_mmap != MAP_FAILED) -        munmap(u->out_mmap, u->out_mmap_length); -     -    if (u->sink) { -        pa_sink_disconnect(u->sink); -        pa_sink_unref(u->sink); -    } - -    if (u->source) { -        pa_source_disconnect(u->source); -        pa_source_unref(u->source); -    } - -    if (u->io_event) -        u->core->mainloop->io_free(u->io_event); - -    if (u->fd >= 0) -        close(u->fd); -      pa_xfree(u);  } diff --git a/src/modules/module-oss.c b/src/modules/module-oss.c index 5ce74151..c3972680 100644 --- a/src/modules/module-oss.c +++ b/src/modules/module-oss.c @@ -107,6 +107,27 @@ static void update_usage(struct userdata *u) {                        (u->source ? pa_idxset_size(u->source->outputs) : 0));  } +static void clear_up(struct userdata *u) { +    assert(u); +     +    if (u->sink) { +        pa_sink_disconnect(u->sink); +        pa_sink_unref(u->sink); +        u->sink = NULL; +    } +     +    if (u->source) { +        pa_source_disconnect(u->source); +        pa_source_unref(u->source); +        u->source = NULL; +    } + +    if (u->io) { +        pa_iochannel_free(u->io); +        u->io = NULL; +    } +} +  static void do_write(struct userdata *u) {      pa_memchunk *memchunk;      ssize_t r; @@ -148,6 +169,9 @@ static void do_write(struct userdata *u) {          if ((r = pa_iochannel_write(u->io, (uint8_t*) memchunk->memblock->data + memchunk->index, memchunk->length)) < 0) {              pa_log(__FILE__": write() failed: %s", pa_cstrerror(errno)); + +            clear_up(u); +            pa_module_unload_request(u->module);              break;          } @@ -199,8 +223,11 @@ static void do_read(struct userdata *u) {          assert(memchunk.memblock);          if ((r = pa_iochannel_read(u->io, memchunk.memblock->data, memchunk.memblock->length)) < 0) {              pa_memblock_unref(memchunk.memblock); -            if (errno != EAGAIN) +            if (errno != EAGAIN) {                  pa_log(__FILE__": read() failed: %s", pa_cstrerror(errno)); +                clear_up(u); +                pa_module_unload_request(u->module); +            }              break;          } @@ -501,22 +528,13 @@ void pa__done(pa_core *c, pa_module*m) {      if (!(u = m->userdata))          return; + +    clear_up(u);      if (u->memchunk.memblock)          pa_memblock_unref(u->memchunk.memblock);      if (u->silence.memblock)          pa_memblock_unref(u->silence.memblock); -    if (u->sink) { -        pa_sink_disconnect(u->sink); -        pa_sink_unref(u->sink); -    } -     -    if (u->source) { -        pa_source_disconnect(u->source); -        pa_source_unref(u->source); -    } -     -    pa_iochannel_free(u->io);      pa_xfree(u);  }  | 
