git: 6819621ec999 - stable/14 - sound: Safely remove channel from list in one pass
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 28 Jan 2025 14:05:06 UTC
The branch stable/14 has been updated by christos:
URL: https://cgit.FreeBSD.org/src/commit/?id=6819621ec9994689cd8626af3e935fbbaa20cd5a
commit 6819621ec9994689cd8626af3e935fbbaa20cd5a
Author: Florian Walpen <dev@submerge.ch>
AuthorDate: 2025-01-21 11:59:12 +0000
Commit: Christos Margiolis <christos@FreeBSD.org>
CommitDate: 2025-01-28 14:04:52 +0000
sound: Safely remove channel from list in one pass
The CHN_REMOVE_SAFE() macro did two traversals of the channel list to
remove a channel, one to check whether the channel is an element of the
list, and a second traversal through SLIST_REMOVE(). Reduce this to one
traversal, while still preventing a NULL dereference in case the channel
in question is not present in the list.
While here, rename the macro arguments to something more descriptive.
MFC after: 1 week
Reviewed by: christos
Differential Revision: https://reviews.freebsd.org/D48207
(cherry picked from commit 27b932e32faba1137ff307d05b787d837ccadda8)
---
sys/dev/sound/pcm/channel.h | 25 +++++++++++++++----------
1 file changed, 15 insertions(+), 10 deletions(-)
diff --git a/sys/dev/sound/pcm/channel.h b/sys/dev/sound/pcm/channel.h
index 67f5019f4727..58fedd284ecb 100644
--- a/sys/dev/sound/pcm/channel.h
+++ b/sys/dev/sound/pcm/channel.h
@@ -175,6 +175,7 @@ struct pcm_channel {
#define CHN_LINK(y) y.link
#define CHN_EMPTY(x, y) SLIST_EMPTY(CHN_HEAD(x, y))
#define CHN_FIRST(x, y) SLIST_FIRST(CHN_HEAD(x, y))
+#define CHN_NEXT(elm, list) SLIST_NEXT((elm), CHN_LINK(list))
#define CHN_FOREACH(x, y, z) \
SLIST_FOREACH(x, CHN_HEAD(y, z), CHN_LINK(z))
@@ -188,8 +189,8 @@ struct pcm_channel {
#define CHN_INSERT_AFTER(x, y, z) \
SLIST_INSERT_AFTER(x, y, CHN_LINK(z))
-#define CHN_REMOVE(x, y, z) \
- SLIST_REMOVE(CHN_HEAD(x, z), y, pcm_channel, CHN_LINK(z))
+#define CHN_REMOVE(holder, elm, list) \
+ SLIST_REMOVE(CHN_HEAD(holder, list), elm, pcm_channel, CHN_LINK(list))
#define CHN_INSERT_HEAD_SAFE(x, y, z) do { \
struct pcm_channel *t = NULL; \
@@ -211,14 +212,18 @@ struct pcm_channel {
CHN_INSERT_AFTER(x, y, z); \
} while (0)
-#define CHN_REMOVE_SAFE(x, y, z) do { \
- struct pcm_channel *t = NULL; \
- CHN_FOREACH(t, x, z) { \
- if (t == y) \
- break; \
- } \
- if (t == y) \
- CHN_REMOVE(x, y, z); \
+#define CHN_REMOVE_SAFE(holder, elm, list) do { \
+ if (CHN_FIRST(holder, list) == (elm)) { \
+ SLIST_REMOVE_HEAD(CHN_HEAD(holder, list), CHN_LINK(list)); \
+ } else { \
+ struct pcm_channel *t = NULL; \
+ CHN_FOREACH(t, holder, list) { \
+ if (CHN_NEXT(t, list) == (elm)) { \
+ SLIST_REMOVE_AFTER(t, CHN_LINK(list)); \
+ break; \
+ } \
+ } \
+ } \
} while (0)
#define CHN_INSERT_SORT(w, x, y, z) do { \