diff options
-rw-r--r-- | usr.bin/aucat/aproc.c | 13 | ||||
-rw-r--r-- | usr.bin/aucat/aproc.h | 3 | ||||
-rw-r--r-- | usr.bin/aucat/aucat.c | 15 | ||||
-rw-r--r-- | usr.bin/aucat/dev.c | 43 | ||||
-rw-r--r-- | usr.bin/aucat/file.c | 36 | ||||
-rw-r--r-- | usr.bin/aucat/file.h | 3 | ||||
-rw-r--r-- | usr.bin/aucat/pipe.c | 2 | ||||
-rw-r--r-- | usr.bin/aucat/safile.c | 4 | ||||
-rw-r--r-- | usr.bin/aucat/sock.c | 8 |
9 files changed, 103 insertions, 24 deletions
diff --git a/usr.bin/aucat/aproc.c b/usr.bin/aucat/aproc.c index 101489b520a..f7f417b8c19 100644 --- a/usr.bin/aucat/aproc.c +++ b/usr.bin/aucat/aproc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: aproc.c,v 1.29 2008/12/27 17:02:13 ratchov Exp $ */ +/* $OpenBSD: aproc.c,v 1.30 2008/12/29 17:59:08 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -67,6 +67,7 @@ aproc_new(struct aproc_ops *ops, char *name) LIST_INIT(&p->obuflist); p->name = name; p->ops = ops; + p->refs = 0; return p; } @@ -88,6 +89,10 @@ aproc_del(struct aproc *p) i = LIST_FIRST(&p->obuflist); abuf_eof(i); } + if (p->refs > 0) { + DPRINTF("aproc_del: %s(%s): has refs\n", p->ops->name, p->name); + return; + } DPRINTF("aproc_del: %s(%s): freed\n", p->ops->name, p->name); free(p); } @@ -199,9 +204,12 @@ rpipe_done(struct aproc *p) { struct file *f = p->u.io.file; + if (f == NULL) + return; f->rproc = NULL; if (f->wproc == NULL) file_del(f); + p->u.io.file = NULL; } void @@ -247,9 +255,12 @@ wpipe_done(struct aproc *p) { struct file *f = p->u.io.file; + if (f == NULL) + return; f->wproc = NULL; if (f->rproc == NULL) file_del(f); + p->u.io.file = NULL; } int diff --git a/usr.bin/aucat/aproc.h b/usr.bin/aucat/aproc.h index 910724169b4..e07afed72fc 100644 --- a/usr.bin/aucat/aproc.h +++ b/usr.bin/aucat/aproc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: aproc.h,v 1.14 2008/12/19 08:01:06 ratchov Exp $ */ +/* $OpenBSD: aproc.h,v 1.15 2008/12/29 17:59:08 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -121,6 +121,7 @@ struct aproc { struct aproc_ops *ops; /* call-backs */ LIST_HEAD(, abuf) ibuflist; /* list of inputs */ LIST_HEAD(, abuf) obuflist; /* list of outputs */ + unsigned refs; /* extern references */ union { /* follow type-specific data */ struct { /* file/device io */ struct file *file; /* file to read/write */ diff --git a/usr.bin/aucat/aucat.c b/usr.bin/aucat/aucat.c index 7c45e3bb4c4..4cabe127593 100644 --- a/usr.bin/aucat/aucat.c +++ b/usr.bin/aucat/aucat.c @@ -1,4 +1,4 @@ -/* $OpenBSD: aucat.c,v 1.49 2008/12/26 13:29:31 ratchov Exp $ */ +/* $OpenBSD: aucat.c,v 1.50 2008/12/29 17:59:08 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -527,14 +527,15 @@ main(int argc, char **argv) */ for (;;) { if (quit_flag) { - if (l_flag) - filelist_unlisten(); break; } - if (!file_poll()) { - fprintf(stderr, "Terminated, device disappeared?\n"); - exit(1); + if ((!dev_rec || dev_rec->u.io.file == NULL) && + (!dev_play || dev_play->u.io.file == NULL)) { + fprintf(stderr, "device desappeared, terminating\n"); + break; } + if (!file_poll()) + break; if ((!dev_mix || dev_mix->u.mix.idle > 2 * dev_bufsz) && (!dev_sub || dev_sub->u.sub.idle > 2 * dev_bufsz)) { if (!l_flag) @@ -555,6 +556,8 @@ main(int argc, char **argv) } } } + if (l_flag) + filelist_unlisten(); if (suspend) { DPRINTF("resuming to drain\n"); suspend = 0; diff --git a/usr.bin/aucat/dev.c b/usr.bin/aucat/dev.c index c62fd892952..9fe8d39ff2c 100644 --- a/usr.bin/aucat/dev.c +++ b/usr.bin/aucat/dev.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dev.c,v 1.21 2008/12/16 22:11:12 ratchov Exp $ */ +/* $OpenBSD: dev.c,v 1.22 2008/12/29 17:59:08 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -103,6 +103,7 @@ dev_init(char *devpath, * create the read end */ dev_rec = rpipe_new(dev_file); + dev_rec->refs++; buf = abuf_new(nfr, dipar); aproc_setout(dev_rec, buf); ibufsz += nfr; @@ -123,6 +124,7 @@ dev_init(char *devpath, * append a "sub" to which clients will connect */ dev_sub = sub_new("sub", nfr); + dev_sub->refs++; aproc_setin(dev_sub, buf); } else { dev_rec = NULL; @@ -138,6 +140,7 @@ dev_init(char *devpath, * create the write end */ dev_play = wpipe_new(dev_file); + dev_play->refs++; buf = abuf_new(nfr, dopar); aproc_setin(dev_play, buf); obufsz += nfr; @@ -158,6 +161,7 @@ dev_init(char *devpath, * append a "mix" to which clients will connect */ dev_mix = mix_new("mix", nfr); + dev_mix->refs++; aproc_setout(dev_mix, buf); } else { dev_play = NULL; @@ -179,7 +183,9 @@ dev_done(void) DPRINTF("dev_done: dev_mix = %p, dev_sub = %p\n", dev_mix, dev_sub); if (dev_mix) { + dev_mix->refs--; dev_mix->u.mix.flags |= MIX_AUTOQUIT; + dev_mix = NULL; /* * generate EOF on all inputs (but not the device), and * put the mixer in ``autoquit'' state, so once buffers @@ -201,14 +207,18 @@ dev_done(void) /* * wait play chain to terminate */ - while (dev_file->wproc != NULL) { + while (!LIST_EMPTY(&dev_play->ibuflist)) { if (!file_poll()) break; } - dev_mix = 0; + dev_play->refs--; + aproc_del(dev_play); + dev_play = NULL; } if (dev_sub) { + dev_sub->refs--; dev_sub->u.sub.flags |= SUB_AUTOQUIT; + dev_sub = NULL; /* * same as above, but for the record chain: generate eof * on the read-end of the device and wait record buffers @@ -217,12 +227,15 @@ dev_done(void) * insert silence on the record-end of the device) */ dev_stop(); - file_eof(dev_file); + if (dev_rec->u.io.file) + file_eof(dev_rec->u.io.file); for (;;) { if (!file_poll()) break; } - dev_sub = NULL; + dev_rec->refs--; + aproc_del(dev_rec); + dev_rec = NULL; } } @@ -232,11 +245,19 @@ dev_done(void) void dev_start(void) { + struct file *f; + if (dev_mix) dev_mix->u.mix.flags |= MIX_DROP; if (dev_sub) dev_sub->u.sub.flags |= SUB_DROP; - dev_file->ops->start(dev_file); + if (dev_play && dev_play->u.io.file) { + f = dev_play->u.io.file; + f->ops->start(f); + } else if (dev_rec && dev_rec->u.io.file) { + f = dev_rec->u.io.file; + f->ops->start(f); + } } /* @@ -245,7 +266,15 @@ dev_start(void) void dev_stop(void) { - dev_file->ops->stop(dev_file); + struct file *f; + + if (dev_play && dev_play->u.io.file) { + f = dev_play->u.io.file; + f->ops->stop(f); + } else if (dev_rec && dev_rec->u.io.file) { + f = dev_rec->u.io.file; + f->ops->stop(f); + } if (dev_mix) dev_mix->u.mix.flags &= ~MIX_DROP; if (dev_sub) diff --git a/usr.bin/aucat/file.c b/usr.bin/aucat/file.c index 7d559a2fadb..545d22d51e8 100644 --- a/usr.bin/aucat/file.c +++ b/usr.bin/aucat/file.c @@ -1,4 +1,4 @@ -/* $OpenBSD: file.c,v 1.8 2008/12/27 14:23:40 ratchov Exp $ */ +/* $OpenBSD: file.c,v 1.9 2008/12/29 17:59:08 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -157,10 +157,12 @@ file_poll(void) DPRINTF("file_poll: nothing to do...\n"); return 0; } - if (poll(pfds, nfds, -1) < 0) { - if (errno == EINTR) - return 1; - err(1, "file_poll: poll failed"); + if (nfds > 0) { + if (poll(pfds, nfds, -1) < 0) { + if (errno == EINTR) + return 1; + err(1, "file_poll: poll failed"); + } } f = LIST_FIRST(&file_list); while (f != LIST_END(&file_list)) { @@ -320,3 +322,27 @@ file_hup(struct file *f) f->state |= FILE_HUP; } } + +void +file_close(struct file *f) +{ + struct aproc *p; + + if (f->refs == 0) { + DPRINTFN(2, "file_close: %s: immediate\n", f->name); + f->refs++; + p = f->rproc; + if (p) + p->ops->eof(p, NULL); + p = f->wproc; + if (p) + p->ops->hup(p, NULL); + f->refs--; + if (f->state & FILE_ZOMB) + file_del(f); + } else { + DPRINTFN(2, "file_close: %s: delayed\n", f->name); + f->state &= ~(FILE_ROK | FILE_WOK); + f->state |= (FILE_EOF | FILE_HUP); + } +} diff --git a/usr.bin/aucat/file.h b/usr.bin/aucat/file.h index b800636a8cb..7fd9bad184e 100644 --- a/usr.bin/aucat/file.h +++ b/usr.bin/aucat/file.h @@ -1,4 +1,4 @@ -/* $OpenBSD: file.h,v 1.4 2008/10/26 08:49:44 ratchov Exp $ */ +/* $OpenBSD: file.h,v 1.5 2008/12/29 17:59:08 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -71,5 +71,6 @@ unsigned file_write(struct file *, unsigned char *, unsigned); int file_poll(void); void file_eof(struct file *); void file_hup(struct file *); +void file_close(struct file *); #endif /* !defined(FILE_H) */ diff --git a/usr.bin/aucat/pipe.c b/usr.bin/aucat/pipe.c index d7cc750df5d..f8679931f3a 100644 --- a/usr.bin/aucat/pipe.c +++ b/usr.bin/aucat/pipe.c @@ -128,7 +128,7 @@ pipe_pollfd(struct file *file, struct pollfd *pfd, int events) pfd->fd = f->fd; pfd->events = events; - return (events != 0) ? 1 : 0; + return (events != 0) ? 1 : 0; } int diff --git a/usr.bin/aucat/safile.c b/usr.bin/aucat/safile.c index 7e6cd30902b..280edc936d5 100644 --- a/usr.bin/aucat/safile.c +++ b/usr.bin/aucat/safile.c @@ -1,4 +1,4 @@ -/* $OpenBSD: safile.c,v 1.8 2008/12/27 14:18:26 ratchov Exp $ */ +/* $OpenBSD: safile.c,v 1.9 2008/12/29 17:59:08 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -165,6 +165,7 @@ safile_start(struct file *file) if (!sio_start(f->hdl)) { DPRINTF("safile_start: sio_start() failed\n"); + file_close(file); return; } DPRINTF("safile_start: play/rec started\n"); @@ -177,6 +178,7 @@ safile_stop(struct file *file) if (!sio_stop(f->hdl)) { DPRINTF("safile_stop: sio_stop() filed\n"); + file_close(file); return; } DPRINTF("safile_stop: play/rec stopped\n"); diff --git a/usr.bin/aucat/sock.c b/usr.bin/aucat/sock.c index 8b86f31ce5a..8a94eb71e07 100644 --- a/usr.bin/aucat/sock.c +++ b/usr.bin/aucat/sock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sock.c,v 1.10 2008/12/17 07:19:27 ratchov Exp $ */ +/* $OpenBSD: sock.c,v 1.11 2008/12/29 17:59:08 ratchov Exp $ */ /* * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> * @@ -55,12 +55,15 @@ rsock_done(struct aproc *p) struct sock *f = (struct sock *)p->u.io.file; DPRINTFN(1, "rsock_done: %p\n", f); + if (f == NULL) + return; sock_reset(f); f->pipe.file.rproc = NULL; if (f->pipe.file.wproc) { aproc_del(f->pipe.file.wproc); file_del(&f->pipe.file); } + p->u.io.file = NULL; } int @@ -160,12 +163,15 @@ wsock_done(struct aproc *p) struct sock *f = (struct sock *)p->u.io.file; DPRINTFN(1, "wsock_done: %p\n", f); + if (f == NULL) + return; sock_reset(f); f->pipe.file.wproc = NULL; if (f->pipe.file.rproc) { aproc_del(f->pipe.file.rproc); file_del(&f->pipe.file); } + p->u.io.file = NULL; } int |