process: associate open connections with clients
This commit is contained in:
parent
e9a653d6e8
commit
a46a8e5e89
@ -93,6 +93,7 @@ struct client_cache_s {
|
||||
unsigned char mac[6];
|
||||
struct client_type_s *type;
|
||||
time_t age;
|
||||
int connections;
|
||||
};
|
||||
|
||||
extern struct client_type_s client_types[];
|
||||
|
14
minidlna.c
14
minidlna.c
@ -372,7 +372,7 @@ rescan:
|
||||
#if USE_FORK
|
||||
scanning = 1;
|
||||
sqlite3_close(db);
|
||||
*scanner_pid = process_fork();
|
||||
*scanner_pid = fork();
|
||||
open_db(&db);
|
||||
if (*scanner_pid == 0) /* child (scanner) process */
|
||||
{
|
||||
@ -969,6 +969,13 @@ init(int argc, char **argv)
|
||||
DPRINTF(E_FATAL, L_GENERAL, "Failed to switch to uid '%d'. [%s] EXITING.\n",
|
||||
uid, strerror(errno));
|
||||
|
||||
children = calloc(runtime_vars.max_connections, sizeof(struct child));
|
||||
if (!children)
|
||||
{
|
||||
DPRINTF(E_ERROR, L_GENERAL, "Allocation failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1285,7 +1292,10 @@ main(int argc, char **argv)
|
||||
shutdown:
|
||||
/* kill the scanner */
|
||||
if (scanning && scanner_pid)
|
||||
kill(scanner_pid, 9);
|
||||
kill(scanner_pid, SIGKILL);
|
||||
|
||||
/* kill other child processes */
|
||||
process_reap_children();
|
||||
|
||||
/* close out open sockets */
|
||||
while (upnphttphead.lh_first != NULL)
|
||||
|
68
process.c
68
process.c
@ -43,10 +43,47 @@
|
||||
#include "config.h"
|
||||
#include "log.h"
|
||||
|
||||
static int number_of_children = 0;
|
||||
struct child *children = NULL;
|
||||
int number_of_children = 0;
|
||||
|
||||
static void
|
||||
add_process_info(pid_t pid, struct client_cache_s *client)
|
||||
{
|
||||
struct child *child;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < runtime_vars.max_connections; i++)
|
||||
{
|
||||
child = children+i;
|
||||
if (child->pid)
|
||||
continue;
|
||||
child->pid = pid;
|
||||
child->client = client;
|
||||
child->age = time(NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
remove_process_info(pid_t pid)
|
||||
{
|
||||
struct child *child;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < runtime_vars.max_connections; i++)
|
||||
{
|
||||
child = children+i;
|
||||
if (child->pid != pid)
|
||||
continue;
|
||||
child->pid = 0;
|
||||
if (child->client)
|
||||
child->client->connections--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pid_t
|
||||
process_fork(void)
|
||||
process_fork(struct client_cache_s *client)
|
||||
{
|
||||
if (number_of_children >= runtime_vars.max_connections)
|
||||
{
|
||||
@ -58,7 +95,13 @@ process_fork(void)
|
||||
|
||||
pid_t pid = fork();
|
||||
if (pid > 0)
|
||||
++number_of_children;
|
||||
{
|
||||
number_of_children++;
|
||||
if (client)
|
||||
client->connections++;
|
||||
add_process_info(pid, client);
|
||||
}
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
@ -76,7 +119,8 @@ process_handle_child_termination(int signal)
|
||||
else
|
||||
break;
|
||||
}
|
||||
--number_of_children;
|
||||
number_of_children--;
|
||||
remove_process_info(pid);
|
||||
}
|
||||
}
|
||||
|
||||
@ -87,7 +131,7 @@ process_daemonize(void)
|
||||
#ifndef USE_DAEMON
|
||||
int i;
|
||||
|
||||
switch(process_fork())
|
||||
switch(fork())
|
||||
{
|
||||
/* fork error */
|
||||
case -1:
|
||||
@ -157,3 +201,17 @@ process_check_if_running(const char *fname)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
process_reap_children(void)
|
||||
{
|
||||
struct child *child;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < runtime_vars.max_connections; i++)
|
||||
{
|
||||
child = children+i;
|
||||
if (child->pid)
|
||||
kill(child->pid, SIGKILL);
|
||||
}
|
||||
}
|
||||
|
17
process.h
17
process.h
@ -30,6 +30,16 @@
|
||||
#define __PROCESS_H__
|
||||
|
||||
#include <unistd.h>
|
||||
#include "clients.h"
|
||||
|
||||
struct child {
|
||||
pid_t pid;
|
||||
time_t age;
|
||||
struct client_cache_s *client;
|
||||
};
|
||||
|
||||
extern struct child *children;
|
||||
extern int number_of_children;
|
||||
|
||||
/**
|
||||
* Fork a new child (just like fork()) but keep track of how many childs are
|
||||
@ -37,7 +47,7 @@
|
||||
* @return -1 if it couldn't fork, 0 in the child process, the pid of the
|
||||
* child process in the parent process.
|
||||
*/
|
||||
pid_t process_fork(void);
|
||||
pid_t process_fork(struct client_cache_s *client);
|
||||
|
||||
/**
|
||||
* Handler to be called upon receiving SIGCHLD. This signal is received by the
|
||||
@ -63,4 +73,9 @@ int process_daemonize(void);
|
||||
*/
|
||||
int process_check_if_running(const char *fname);
|
||||
|
||||
/**
|
||||
* Kill all child processes
|
||||
*/
|
||||
void process_reap_children(void);
|
||||
|
||||
#endif // __PROCESS_H__
|
||||
|
18
upnphttp.c
18
upnphttp.c
@ -83,8 +83,7 @@
|
||||
|
||||
#include "sendfile.h"
|
||||
|
||||
//#define MAX_BUFFER_SIZE 4194304 // 4MB -- Too much?
|
||||
#define MAX_BUFFER_SIZE 2147483647 // 2GB -- Too much?
|
||||
#define MAX_BUFFER_SIZE 2147483647
|
||||
#define MIN_BUFFER_SIZE 65536
|
||||
|
||||
#include "icons.c"
|
||||
@ -615,17 +614,20 @@ SendResp_presentation(struct upnphttp * h)
|
||||
strcatf(&str,
|
||||
"<h3>Connected clients</h3>"
|
||||
"<table border=1 cellpadding=10>"
|
||||
"<tr><td>ID</td><td>Type</td><td>IP Address</td><td>HW Address</td></tr>");
|
||||
"<tr><td>ID</td><td>Type</td><td>IP Address</td><td>HW Address</td><td>Connections</td></tr>");
|
||||
for (i = 0; i < CLIENT_CACHE_SLOTS; i++)
|
||||
{
|
||||
if (!clients[i].addr.s_addr)
|
||||
continue;
|
||||
strcatf(&str, "<tr><td>%d</td><td>%s</td><td>%s</td><td>%02X:%02X:%02X:%02X:%02X:%02X</td></tr>",
|
||||
strcatf(&str, "<tr><td>%d</td><td>%s</td><td>%s</td><td>%02X:%02X:%02X:%02X:%02X:%02X</td><td>%d</td></tr>",
|
||||
i, clients[i].type->name, inet_ntoa(clients[i].addr),
|
||||
clients[i].mac[0], clients[i].mac[1], clients[i].mac[2],
|
||||
clients[i].mac[3], clients[i].mac[4], clients[i].mac[5]);
|
||||
clients[i].mac[3], clients[i].mac[4], clients[i].mac[5], clients[i].connections);
|
||||
}
|
||||
strcatf(&str, "</table></BODY></HTML>\r\n");
|
||||
strcatf(&str, "</table>");
|
||||
|
||||
strcatf(&str, "<br>%d connection%s currently open<br>", number_of_children, (number_of_children == 1 ? "" : "s"));
|
||||
strcatf(&str, "</BODY></HTML>\r\n");
|
||||
|
||||
BuildResp_upnphttp(h, str.data, str.off);
|
||||
SendResp_upnphttp(h);
|
||||
@ -1633,7 +1635,7 @@ SendResp_resizedimg(struct upnphttp * h, char * object)
|
||||
|
||||
#if USE_FORK
|
||||
pid_t newpid = 0;
|
||||
newpid = process_fork();
|
||||
newpid = process_fork(h->req_client);
|
||||
if( newpid > 0 )
|
||||
{
|
||||
CloseSocket_upnphttp(h);
|
||||
@ -1875,7 +1877,7 @@ SendResp_dlnafile(struct upnphttp *h, char *object)
|
||||
sqlite3_free_table(result);
|
||||
}
|
||||
#if USE_FORK
|
||||
newpid = process_fork();
|
||||
newpid = process_fork(h->req_client);
|
||||
if( newpid > 0 )
|
||||
{
|
||||
CloseSocket_upnphttp(h);
|
||||
|
Loading…
x
Reference in New Issue
Block a user