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