From: Andre Noll <maan@tuebingen.mpg.de>
Date: Mon, 30 Jun 2025 18:27:11 +0000 (+0200)
Subject: server: Allocate the scheduler structure after calling afs_init().
X-Git-Url: https://git.tuebingen.mpg.de/?a=commitdiff_plain;h=HEAD;p=paraslash.git

server: Allocate the scheduler structure after calling afs_init().

Since the audio file selector allocates its own scheduler instance, we
currently allocate two instances and free only one. Avoid this memory leak
by delaying the allocation until after the afs process is born.

The latest possible point to allocate the scheduler instance is in
server_init(), just before the signal task is initialized, so move the call
to sched_new() there. Since that passes a pointer to server_poll() and this
function calls status_refresh() we have to move those two functions up.
---

diff --git a/server.c b/server.c
index 46dbfd54..604b5ad6 100644
--- a/server.c
+++ b/server.c
@@ -520,11 +520,47 @@ static void handle_help_flags(void)
 	exit(EXIT_SUCCESS);
 }
 
-static void server_init(int argc, char **argv, struct sched *sched,
+static void status_refresh(void)
+{
+	static int prev_uptime = -1, prev_events = -1;
+	int uptime = daemon_get_uptime(now);
+
+	if (prev_events != mmd->events)
+		goto out;
+	if (mmd->new_vss_status_flags != mmd->vss_status_flags)
+		goto out_inc_events;
+	if (uptime / 60 != prev_uptime / 60)
+		goto out_inc_events;
+	return;
+out_inc_events:
+	mmd->events++;
+out:
+	prev_uptime = uptime;
+	prev_events = mmd->events;
+	mmd->vss_status_flags = mmd->new_vss_status_flags;
+	PARA_DEBUG_LOG("%u events, forcing status update\n", mmd->events);
+	killpg(0, SIGUSR1);
+}
+
+static int server_poll(struct pollfd *fds, nfds_t nfds, int timeout)
+{
+	int ret;
+
+	daemon_set_loglevel(mmd->loglevel);
+	status_refresh();
+	mutex_unlock(mmd_mutex);
+	ret = xpoll(fds, nfds, timeout);
+	mutex_lock(mmd_mutex);
+	return ret;
+}
+
+/* exit on errors, never return NULL */
+static struct sched *server_init(int argc, char **argv,
 		struct server_command_task *sct)
 {
 	int ret, afs_socket, daemon_pipe = -1;
 	char *errctx;
+	struct sched *sched;
 
 	valid_fd_012();
 	/* parse command line options */
@@ -562,6 +598,7 @@ static void server_init(int argc, char **argv, struct sched *sched,
 	para_block_signal(SIGCHLD);
 	PARA_NOTICE_LOG("initializing the audio file selector\n");
 	afs_socket = init_afs(argc, argv);
+	sched = sched_new(server_poll);
 	init_signal_task(sched);
 	para_unblock_signal(SIGCHLD);
 	PARA_NOTICE_LOG("initializing virtual streaming system\n");
@@ -575,7 +612,7 @@ static void server_init(int argc, char **argv, struct sched *sched,
 		close(daemon_pipe);
 	}
 	PARA_NOTICE_LOG("server init complete\n");
-	return;
+	return sched;
 fail:
 	assert(ret < 0);
 	if (errctx)
@@ -584,40 +621,6 @@ fail:
 	exit(EXIT_FAILURE);
 }
 
-static void status_refresh(void)
-{
-	static int prev_uptime = -1, prev_events = -1;
-	int uptime = daemon_get_uptime(now);
-
-	if (prev_events != mmd->events)
-		goto out;
-	if (mmd->new_vss_status_flags != mmd->vss_status_flags)
-		goto out_inc_events;
-	if (uptime / 60 != prev_uptime / 60)
-		goto out_inc_events;
-	return;
-out_inc_events:
-	mmd->events++;
-out:
-	prev_uptime = uptime;
-	prev_events = mmd->events;
-	mmd->vss_status_flags = mmd->new_vss_status_flags;
-	PARA_DEBUG_LOG("%u events, forcing status update\n", mmd->events);
-	killpg(0, SIGUSR1);
-}
-
-static int server_poll(struct pollfd *fds, nfds_t nfds, int timeout)
-{
-	int ret;
-
-	daemon_set_loglevel(mmd->loglevel);
-	status_refresh();
-	mutex_unlock(mmd_mutex);
-	ret = xpoll(fds, nfds, timeout);
-	mutex_lock(mmd_mutex);
-	return ret;
-}
-
 /**
  * Deallocate all lopsub parse results.
  *
@@ -646,9 +649,8 @@ int main(int argc, char *argv[])
 	int ret;
 	struct server_command_task server_command_task_struct,
 		*sct = &server_command_task_struct;
-	struct sched *sched = sched_new(server_poll);
+	struct sched *sched = server_init(argc, argv, sct);
 
-	server_init(argc, argv, sched, sct);
 	mutex_lock(mmd_mutex);
 	ret = schedule(sched);
 	/*