Module Name:    src
Committed By:   riastradh
Date:           Fri Jun  4 08:57:05 UTC 2021

Modified Files:
        src/sys/dev/audio: audio.c

Log Message:
audio(4): When closing /dev/audioN, drain before removing from list.

Previously, in revision 1.100, I factored the SLIST_REMOVE out of
audio_unlink and audio_close up into audioclose since it is now used
by /dev/audio, /dev/audioctl, and /dev/mixer alike.  But I didn't
realize that the order

1. audio_track_drain
2. SLIST_REMOVE from sc_files

was significant; it matters because audio_track_drain waits for
wakeups that are delivered by hardware interrupts only to files
listed in sc_files.

This also fixes a bug introduced with the audiobell -- it was missing
the SLIST_REMOVE altogether.

For now, duplicate the SLIST_REMOVE calls in a few more places --
this is suboptimal but I want to make sure the logic works before
factoring it all out to tidy up.


To generate a diff of this commit:
cvs rdiff -u -r1.102 -r1.103 src/sys/dev/audio/audio.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/audio/audio.c
diff -u src/sys/dev/audio/audio.c:1.102 src/sys/dev/audio/audio.c:1.103
--- src/sys/dev/audio/audio.c:1.102	Tue Jun  1 21:27:36 2021
+++ src/sys/dev/audio/audio.c	Fri Jun  4 08:57:05 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: audio.c,v 1.102 2021/06/01 21:27:36 riastradh Exp $	*/
+/*	$NetBSD: audio.c,v 1.103 2021/06/04 08:57:05 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -138,7 +138,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.102 2021/06/01 21:27:36 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.103 2021/06/04 08:57:05 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "audio.h"
@@ -1747,20 +1747,25 @@ audioclose(struct file *fp)
 	bound = curlwp_bind();
 	sc = audio_sc_acquire_fromfile(file, &sc_ref);
 	if (sc) {
-		mutex_enter(sc->sc_lock);
-		mutex_enter(sc->sc_intr_lock);
-		SLIST_REMOVE(&sc->sc_files, file, audio_file, entry);
-		mutex_exit(sc->sc_intr_lock);
-		mutex_exit(sc->sc_lock);
 		switch (AUDIODEV(dev)) {
 		case SOUND_DEVICE:
 		case AUDIO_DEVICE:
 			error = audio_close(sc, file);
 			break;
 		case AUDIOCTL_DEVICE:
+			mutex_enter(sc->sc_lock);
+			mutex_enter(sc->sc_intr_lock);
+			SLIST_REMOVE(&sc->sc_files, file, audio_file, entry);
+			mutex_exit(sc->sc_intr_lock);
+			mutex_exit(sc->sc_lock);
 			error = 0;
 			break;
 		case MIXER_DEVICE:
+			mutex_enter(sc->sc_lock);
+			mutex_enter(sc->sc_intr_lock);
+			SLIST_REMOVE(&sc->sc_files, file, audio_file, entry);
+			mutex_exit(sc->sc_intr_lock);
+			mutex_exit(sc->sc_lock);
 			error = mixer_close(sc, file);
 			break;
 		default:
@@ -2569,6 +2574,12 @@ audio_close(struct audio_softc *sc, audi
 		mutex_exit(sc->sc_lock);
 	}
 
+	mutex_enter(sc->sc_lock);
+	mutex_enter(sc->sc_intr_lock);
+	SLIST_REMOVE(&sc->sc_files, file, audio_file, entry);
+	mutex_exit(sc->sc_intr_lock);
+	mutex_exit(sc->sc_lock);
+
 	error = audio_exlock_enter(sc);
 	if (error) {
 		/*

Reply via email to