From 27c9224f699b2f387d21213f3c99eca97e121e75 Mon Sep 17 00:00:00 2001
From: Christian Meffert <christian.meffert@googlemail.com>
Date: Fri, 27 Dec 2024 10:58:54 +0000
Subject: [PATCH] [listener] Support passing context arg to listener callbacks

---
 src/cache.c       | 4 ++--
 src/httpd.c       | 4 ++--
 src/httpd_dacp.c  | 4 ++--
 src/inputs/pipe.c | 6 +++---
 src/listener.c    | 6 ++++--
 src/listener.h    | 5 +++--
 src/mpd.c         | 4 ++--
 src/websocket.c   | 4 ++--
 8 files changed, 20 insertions(+), 17 deletions(-)

diff --git a/src/cache.c b/src/cache.c
index 76dc3291..21642d8c 100644
--- a/src/cache.c
+++ b/src/cache.c
@@ -1307,7 +1307,7 @@ cache_database_update(void *arg, int *retval)
 
 /* Callback from filescanner thread */
 static void
-cache_daap_listener_cb(short event_mask)
+cache_daap_listener_cb(short event_mask, void *ctx)
 {
   commands_exec_async(cmdbase, cache_database_update, NULL);
 }
@@ -1715,7 +1715,7 @@ cache(void *arg)
   for (i = 0; i < ARRAY_SIZE(cache_xcode_jobs); i++)
     CHECK_NULL(L_CACHE, cache_xcode_jobs[i].ev = evtimer_new(evbase_cache, cache_xcode_job_complete_cb, &cache_xcode_jobs[i]));
 
-  CHECK_ERR(L_CACHE, listener_add(cache_daap_listener_cb, LISTENER_DATABASE));
+  CHECK_ERR(L_CACHE, listener_add(cache_daap_listener_cb, LISTENER_DATABASE, NULL));
 
   cache_is_initialized = 1;
 
diff --git a/src/httpd.c b/src/httpd.c
index 8bdf5bb3..b9c41343 100644
--- a/src/httpd.c
+++ b/src/httpd.c
@@ -971,7 +971,7 @@ speaker_update_handler_cb(void *arg)
 
 // Thread: player (must not block)
 static void
-httpd_speaker_update_handler(short event_mask)
+httpd_speaker_update_handler(short event_mask, void *ctx)
 {
   worker_execute(speaker_update_handler_cb, NULL, 0, 0);
 }
@@ -1636,7 +1636,7 @@ httpd_init(const char *webroot)
 
   // We need to know about speaker format changes so we can ask the cache to
   // start preparing headers for mp4/alac if selected
-  listener_add(httpd_speaker_update_handler, LISTENER_SPEAKER);
+  listener_add(httpd_speaker_update_handler, LISTENER_SPEAKER, NULL);
 
   return 0;
 
diff --git a/src/httpd_dacp.c b/src/httpd_dacp.c
index b861f61d..ef8ba943 100644
--- a/src/httpd_dacp.c
+++ b/src/httpd_dacp.c
@@ -787,7 +787,7 @@ update_fail_cb(void *arg)
 
 /* Thread: player */
 static void
-dacp_playstatus_update_handler(short event_mask)
+dacp_playstatus_update_handler(short event_mask, void *ctx)
 {
   struct dacp_update_request *ur;
 
@@ -2818,7 +2818,7 @@ dacp_init(void)
 
   CHECK_ERR(L_DACP, mutex_init(&update_request_lck));
   update_current_rev = 2;
-  listener_add(dacp_playstatus_update_handler, LISTENER_PLAYER | LISTENER_VOLUME | LISTENER_QUEUE);
+  listener_add(dacp_playstatus_update_handler, LISTENER_PLAYER | LISTENER_VOLUME | LISTENER_QUEUE, NULL);
 
   return 0;
 }
diff --git a/src/inputs/pipe.c b/src/inputs/pipe.c
index 861a57da..21d3800a 100644
--- a/src/inputs/pipe.c
+++ b/src/inputs/pipe.c
@@ -999,7 +999,7 @@ pipelist_create(void)
 // the pipe thread to watch the pipes. If no pipes in library, it will shut down
 // the pipe thread.
 static void
-pipe_listener_cb(short event_mask)
+pipe_listener_cb(short event_mask, void *ctx)
 {
   union pipe_arg *cmdarg;
 
@@ -1146,8 +1146,8 @@ init(void)
   pipe_autostart = cfg_getbool(cfg_getsec(cfg, "library"), "pipe_autostart");
   if (pipe_autostart)
     {
-      pipe_listener_cb(0);
-      CHECK_ERR(L_PLAYER, listener_add(pipe_listener_cb, LISTENER_DATABASE));
+      pipe_listener_cb(0, NULL);
+      CHECK_ERR(L_PLAYER, listener_add(pipe_listener_cb, LISTENER_DATABASE, NULL));
     }
 
   pipe_sample_rate = cfg_getint(cfg_getsec(cfg, "library"), "pipe_sample_rate");
diff --git a/src/listener.c b/src/listener.c
index 121b836f..51e63e37 100644
--- a/src/listener.c
+++ b/src/listener.c
@@ -27,13 +27,14 @@ struct listener
 {
   notify notify_cb;
   short events;
+  void *ctx;
   struct listener *next;
 };
 
 struct listener *listener_list = NULL;
 
 int
-listener_add(notify notify_cb, short events)
+listener_add(notify notify_cb, short events, void *ctx)
 {
   struct listener *listener;
 
@@ -44,6 +45,7 @@ listener_add(notify notify_cb, short events)
     }
   listener->notify_cb = notify_cb;
   listener->events = events;
+  listener->ctx = ctx;
   listener->next = listener_list;
   listener_list = listener;
 
@@ -88,7 +90,7 @@ listener_notify(short event_mask)
   while (listener)
     {
       if (event_mask & listener->events)
-	listener->notify_cb(event_mask & listener->events);
+	listener->notify_cb(event_mask & listener->events, listener->ctx);
       listener = listener->next;
     }
 }
diff --git a/src/listener.h b/src/listener.h
index b5e717ab..0a91cb26 100644
--- a/src/listener.h
+++ b/src/listener.h
@@ -30,7 +30,7 @@ enum listener_event_type
   LISTENER_RATING = (1 << 11),
 };
 
-typedef void (*notify)(short event_mask);
+typedef void (*notify)(short event_mask, void *ctx);
 
 /*
  * Registers the given callback function to the given event types.
@@ -39,10 +39,11 @@ typedef void (*notify)(short event_mask);
  * @param notify_cb Callback function (should be a non-blocking function,
  *        especially when the event is from the player)
  * @param event_mask Event mask, one or more of LISTENER_*
+ * @param ctx Context will be passed to the notify callback
  * @return 0 on success, -1 on failure
  */
 int
-listener_add(notify notify_cb, short event_mask);
+listener_add(notify notify_cb, short event_mask, void *ctx);
 
 /*
  * Removes the given callback function
diff --git a/src/mpd.c b/src/mpd.c
index ced05c14..afc68b53 100644
--- a/src/mpd.c
+++ b/src/mpd.c
@@ -4117,7 +4117,7 @@ mpd_notify_idle(void *arg, int *retval)
 }
 
 static void
-mpd_listener_cb(short event_mask)
+mpd_listener_cb(short event_mask, void *ctx)
 {
   short *ptr;
 
@@ -4381,7 +4381,7 @@ mpd_init(void)
   thread_setname(tid_mpd, "mpd");
 
   mpd_clients = NULL;
-  listener_add(mpd_listener_cb, MPD_ALL_IDLE_LISTENER_EVENTS);
+  listener_add(mpd_listener_cb, MPD_ALL_IDLE_LISTENER_EVENTS, NULL);
 
   return 0;
 
diff --git a/src/websocket.c b/src/websocket.c
index 13133ed6..89f4c916 100644
--- a/src/websocket.c
+++ b/src/websocket.c
@@ -50,7 +50,7 @@ static short websocket_write_events;
 
 /* Thread: library (the thread the event occurred) */
 static void
-listener_cb(short event_mask)
+listener_cb(short event_mask, void *ctx)
 {
   pthread_mutex_lock(&websocket_write_event_lock);
   websocket_write_events |= event_mask;
@@ -416,7 +416,7 @@ static void *
 websocket(void *arg)
 {
   listener_add(listener_cb, LISTENER_UPDATE | LISTENER_DATABASE | LISTENER_PAIRING | LISTENER_SPOTIFY | LISTENER_LASTFM | LISTENER_SPEAKER
-               | LISTENER_PLAYER | LISTENER_OPTIONS | LISTENER_VOLUME | LISTENER_QUEUE);
+               | LISTENER_PLAYER | LISTENER_OPTIONS | LISTENER_VOLUME | LISTENER_QUEUE, NULL);
 
   while(!websocket_exit)
   {