From 1a78a94f7036aee13e62eef8dbfb430eb65df5c3 Mon Sep 17 00:00:00 2001 From: Justin Maggard Date: Mon, 3 Mar 2014 13:32:20 -0800 Subject: [PATCH] process: make max number of children (connections) configurable At least some Panasonic clients try to open more than 5 simultaneous connections to the server. If we keep the default of 5 max children, it results in choppy playback on those clients. Make this setting configurable, and default to 50 max connections. Our process is pretty lightweight, so 50 children should not be a problem on most systems. --- minidlna.c | 6 +++++- minidlna.conf | 4 ++++ minidlnatypes.h | 1 + options.c | 3 ++- options.h | 3 ++- process.c | 23 +++++++++++++++++++---- 6 files changed, 33 insertions(+), 7 deletions(-) diff --git a/minidlna.c b/minidlna.c index a45039b..0f1fbef 100644 --- a/minidlna.c +++ b/minidlna.c @@ -509,6 +509,7 @@ init(int argc, char **argv) runtime_vars.port = 8200; runtime_vars.notify_interval = 895; /* seconds between SSDP announces */ + runtime_vars.max_connections = 50; runtime_vars.root_container = NULL; runtime_vars.ifaces[0] = NULL; @@ -706,9 +707,12 @@ init(int argc, char **argv) case FORCE_SORT_CRITERIA: force_sort_criteria = ary_options[i].value; break; + case MAX_CONNECTIONS: + runtime_vars.max_connections = atoi(ary_options[i].value); + break; default: DPRINTF(E_ERROR, L_GENERAL, "Unknown option in file %s\n", - optionsfile); + optionsfile); } } if (log_path[0] == '\0') diff --git a/minidlna.conf b/minidlna.conf index 42698ff..a56330e 100644 --- a/minidlna.conf +++ b/minidlna.conf @@ -72,3 +72,7 @@ model_number=1 # always force SortCriteria to this value, regardless of the SortCriteria passed by the client #force_sort_criteria=+upnp:class,+upnp:originalTrackNumber,+dc:title + +# maximum number of simultaneous connections +# note: many clients open several simultaneous connections while streaming +#max_connections=50 diff --git a/minidlnatypes.h b/minidlnatypes.h index 9cee2a3..bc4e195 100644 --- a/minidlnatypes.h +++ b/minidlnatypes.h @@ -48,6 +48,7 @@ struct lan_addr_s { struct runtime_vars_s { int port; /* HTTP Port */ int notify_interval; /* seconds between SSDP announces */ + int max_connections; /* max number of simultaneous conenctions */ char *root_container; /* root ObjectID (instead of "0") */ char *ifaces[MAX_LAN_ADDR]; /* list of configured network interfaces */ }; diff --git a/options.c b/options.c index 873fc36..e211b33 100644 --- a/options.c +++ b/options.c @@ -62,7 +62,8 @@ static const struct { { ENABLE_DLNA_STRICT, "strict_dlna" }, { ROOT_CONTAINER, "root_container" }, { USER_ACCOUNT, "user" }, - { FORCE_SORT_CRITERIA, "force_sort_criteria" } + { FORCE_SORT_CRITERIA, "force_sort_criteria" }, + { MAX_CONNECTIONS, "max_connections" } }; int diff --git a/options.h b/options.h index 14060ee..42686fc 100644 --- a/options.h +++ b/options.h @@ -56,7 +56,8 @@ enum upnpconfigoptions { ENABLE_DLNA_STRICT, /* strictly adhere to DLNA specs */ ROOT_CONTAINER, /* root ObjectID (instead of "0") */ USER_ACCOUNT, /* user account to run as */ - FORCE_SORT_CRITERIA /* force sorting by a given sort criteria */ + FORCE_SORT_CRITERIA, /* force sorting by a given sort criteria */ + MAX_CONNECTIONS /* maximum number of simultaneous connections */ }; /* readoptionsfile() diff --git a/process.c b/process.c index 22f5207..efe3ca6 100644 --- a/process.c +++ b/process.c @@ -38,18 +38,20 @@ #include #include +#include "upnpglobalvars.h" #include "process.h" #include "config.h" #include "log.h" -static const int max_number_of_children = 5; static int number_of_children = 0; pid_t process_fork(void) { - if (number_of_children >= max_number_of_children) + if (number_of_children >= runtime_vars.max_connections) { + DPRINTF(E_WARN, L_GENERAL, "Exceeded max connections [%d], not forking\n", + runtime_vars.max_connections); errno = EAGAIN; return -1; } @@ -63,8 +65,21 @@ process_fork(void) void process_handle_child_termination(int signal) { - waitpid(-1, NULL, WNOHANG); - --number_of_children; + pid_t pid; + + while ((pid = waitpid(-1, NULL, WNOHANG))) + { + if (pid == -1) + { + if (errno == EINTR) + continue; + else + break; + } + else if (pid == 0) + break; + --number_of_children; + } } int