Date: Fri, 24 Apr 2026 16:24:46 +0000 From: Warner Losh <imp@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Cc: Raphael 'kena' Poss <knz@thaumogen.net> Subject: git: e2199dc33f16 - main - speaker(4): one ioctl / write at a time Message-ID: <69eb994e.3ba9b.43f166b0@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch main has been updated by imp: URL: https://cgit.FreeBSD.org/src/commit/?id=e2199dc33f16332b3e138da3059ba57c25ef713d commit e2199dc33f16332b3e138da3059ba57c25ef713d Author: Raphael 'kena' Poss <knz@thaumogen.net> AuthorDate: 2026-01-01 16:45:45 +0000 Commit: Warner Losh <imp@FreeBSD.org> CommitDate: 2026-04-24 16:23:06 +0000 speaker(4): one ioctl / write at a time If two processes are holding a spkr fd, we want orderly access to the allocated tone buffer and the speaker itself. Signed-off-by: Raphael Poss <knz@thaumogen.net> Reviewed by: imp Pull Request: https://github.com/freebsd/freebsd-src/pull/1922 --- sys/dev/speaker/spkr.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/sys/dev/speaker/spkr.c b/sys/dev/speaker/spkr.c index 85a0c837f4b4..7aaebd225512 100644 --- a/sys/dev/speaker/spkr.c +++ b/sys/dev/speaker/spkr.c @@ -10,6 +10,7 @@ #include <sys/systm.h> #include <sys/kernel.h> #include <sys/module.h> +#include <sys/sx.h> #include <sys/uio.h> #include <sys/conf.h> #include <sys/ctype.h> @@ -394,9 +395,17 @@ playstring(char *cp, size_t slen) * endtone(), and rest() functions defined above. */ -static int spkr_active = 0; /* exclusion flag */ +static int spkr_dev_busy = 0; /* one open at a time */ static char *spkr_inbuf; /* incoming buf */ +/* + * we use a lock to serialize access to spkr_inbuf but also to prevent + * interleaving of melodies written concurrently from two different + * threads. + */ +static struct sx spkr_op_locked; + + static int spkropen(struct cdev *dev, int flags, int fmt, struct thread *td) { @@ -404,7 +413,7 @@ spkropen(struct cdev *dev, int flags, int fmt, struct thread *td) (void) printf("spkropen: entering with dev = %s\n", devtoname(dev)); #endif /* DEBUG */ - if (!atomic_cmpset_int(&spkr_active, 0, 1)) + if (!atomic_cmpset_int(&spkr_dev_busy, 0, 1)) return(EBUSY); else { #ifdef DEBUG @@ -431,6 +440,7 @@ spkrwrite(struct cdev *dev, struct uio *uio, int ioflag) char *cp; int error; + sx_xlock(&spkr_op_locked); n = uio->uio_resid; cp = spkr_inbuf; error = uiomove(cp, n, uio); @@ -438,7 +448,8 @@ spkrwrite(struct cdev *dev, struct uio *uio, int ioflag) cp[n] = '\0'; playstring(cp, n); } - return(error); + sx_xunlock(&spkr_op_locked); + return(error); } } @@ -452,7 +463,7 @@ spkrclose(struct cdev *dev, int flags, int fmt, struct thread *td) wakeup(&endtone); wakeup(&endrest); free(spkr_inbuf, M_SPKR); - (void) atomic_swap_int(&spkr_active, 0); + (void) atomic_swap_int(&spkr_dev_busy, 0); return(0); } @@ -468,20 +479,25 @@ spkrioctl(struct cdev *dev, unsigned long cmd, caddr_t cmdarg, int flags, if (cmd == SPKRTONE) { tone_t *tp = (tone_t *)cmdarg; + sx_xlock(&spkr_op_locked); if (tp->frequency == 0) rest(tp->duration); else tone(tp->frequency, tp->duration); + sx_xunlock(&spkr_op_locked); return 0; } else if (cmd == SPKRTUNE) { tone_t *tp = (tone_t *)(*(caddr_t *)cmdarg); tone_t ttp; int error; + sx_xlock(&spkr_op_locked); for (; ; tp++) { error = copyin(tp, &ttp, sizeof(tone_t)); - if (error) + if (error) { + sx_xunlock(&spkr_op_locked); return(error); + } if (ttp.duration == 0) break; @@ -491,6 +507,7 @@ spkrioctl(struct cdev *dev, unsigned long cmd, caddr_t cmdarg, int flags, else tone(ttp.frequency, ttp.duration); } + sx_xunlock(&spkr_op_locked); return(0); } return(EINVAL); @@ -507,13 +524,15 @@ speaker_modevent(module_t mod, int type, void *data) int error = 0; switch(type) { - case MOD_LOAD: + case MOD_LOAD: + sx_init(&spkr_op_locked, "spkr"); speaker_dev = make_dev(&spkr_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, "speaker"); break; case MOD_SHUTDOWN: case MOD_UNLOAD: destroy_dev(speaker_dev); + sx_destroy(&spkr_op_locked); break; default: error = EOPNOTSUPP;home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69eb994e.3ba9b.43f166b0>
