summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.bin/aucat/aproc.c13
-rw-r--r--usr.bin/aucat/aproc.h3
-rw-r--r--usr.bin/aucat/aucat.c15
-rw-r--r--usr.bin/aucat/dev.c43
-rw-r--r--usr.bin/aucat/file.c36
-rw-r--r--usr.bin/aucat/file.h3
-rw-r--r--usr.bin/aucat/pipe.c2
-rw-r--r--usr.bin/aucat/safile.c4
-rw-r--r--usr.bin/aucat/sock.c8
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