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];
|
unsigned char mac[6];
|
||||||
struct client_type_s *type;
|
struct client_type_s *type;
|
||||||
time_t age;
|
time_t age;
|
||||||
|
int connections;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct client_type_s client_types[];
|
extern struct client_type_s client_types[];
|
||||||
|
14
minidlna.c
14
minidlna.c
@ -372,7 +372,7 @@ rescan:
|
|||||||
#if USE_FORK
|
#if USE_FORK
|
||||||
scanning = 1;
|
scanning = 1;
|
||||||
sqlite3_close(db);
|
sqlite3_close(db);
|
||||||
*scanner_pid = process_fork();
|
*scanner_pid = fork();
|
||||||
open_db(&db);
|
open_db(&db);
|
||||||
if (*scanner_pid == 0) /* child (scanner) process */
|
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",
|
DPRINTF(E_FATAL, L_GENERAL, "Failed to switch to uid '%d'. [%s] EXITING.\n",
|
||||||
uid, strerror(errno));
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1285,7 +1292,10 @@ main(int argc, char **argv)
|
|||||||
shutdown:
|
shutdown:
|
||||||
/* kill the scanner */
|
/* kill the scanner */
|
||||||
if (scanning && scanner_pid)
|
if (scanning && scanner_pid)
|
||||||
kill(scanner_pid, 9);
|
kill(scanner_pid, SIGKILL);
|
||||||
|
|
||||||
|
/* kill other child processes */
|
||||||
|
process_reap_children();
|
||||||
|
|
||||||
/* close out open sockets */
|
/* close out open sockets */
|
||||||
while (upnphttphead.lh_first != NULL)
|
while (upnphttphead.lh_first != NULL)
|
||||||
|
68
process.c
68
process.c
@ -43,10 +43,47 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "log.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
|
pid_t
|
||||||
process_fork(void)
|
process_fork(struct client_cache_s *client)
|
||||||
{
|
{
|
||||||
if (number_of_children >= runtime_vars.max_connections)
|
if (number_of_children >= runtime_vars.max_connections)
|
||||||
{
|
{
|
||||||
@ -58,7 +95,13 @@ process_fork(void)
|
|||||||
|
|
||||||
pid_t pid = fork();
|
pid_t pid = fork();
|
||||||
if (pid > 0)
|
if (pid > 0)
|
||||||
++number_of_children;
|
{
|
||||||
|
number_of_children++;
|
||||||
|
if (client)
|
||||||
|
client->connections++;
|
||||||
|
add_process_info(pid, client);
|
||||||
|
}
|
||||||
|
|
||||||
return pid;
|
return pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,7 +119,8 @@ process_handle_child_termination(int signal)
|
|||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
--number_of_children;
|
number_of_children--;
|
||||||
|
remove_process_info(pid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,7 +131,7 @@ process_daemonize(void)
|
|||||||
#ifndef USE_DAEMON
|
#ifndef USE_DAEMON
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
switch(process_fork())
|
switch(fork())
|
||||||
{
|
{
|
||||||
/* fork error */
|
/* fork error */
|
||||||
case -1:
|
case -1:
|
||||||
@ -157,3 +201,17 @@ process_check_if_running(const char *fname)
|
|||||||
|
|
||||||
return 0;
|
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__
|
#define __PROCESS_H__
|
||||||
|
|
||||||
#include <unistd.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
|
* 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
|
* @return -1 if it couldn't fork, 0 in the child process, the pid of the
|
||||||
* child process in the parent process.
|
* 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
|
* 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);
|
int process_check_if_running(const char *fname);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kill all child processes
|
||||||
|
*/
|
||||||
|
void process_reap_children(void);
|
||||||
|
|
||||||
#endif // __PROCESS_H__
|
#endif // __PROCESS_H__
|
||||||
|
18
upnphttp.c
18
upnphttp.c
@ -83,8 +83,7 @@
|
|||||||
|
|
||||||
#include "sendfile.h"
|
#include "sendfile.h"
|
||||||
|
|
||||||
//#define MAX_BUFFER_SIZE 4194304 // 4MB -- Too much?
|
#define MAX_BUFFER_SIZE 2147483647
|
||||||
#define MAX_BUFFER_SIZE 2147483647 // 2GB -- Too much?
|
|
||||||
#define MIN_BUFFER_SIZE 65536
|
#define MIN_BUFFER_SIZE 65536
|
||||||
|
|
||||||
#include "icons.c"
|
#include "icons.c"
|
||||||
@ -615,17 +614,20 @@ SendResp_presentation(struct upnphttp * h)
|
|||||||
strcatf(&str,
|
strcatf(&str,
|
||||||
"<h3>Connected clients</h3>"
|
"<h3>Connected clients</h3>"
|
||||||
"<table border=1 cellpadding=10>"
|
"<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++)
|
for (i = 0; i < CLIENT_CACHE_SLOTS; i++)
|
||||||
{
|
{
|
||||||
if (!clients[i].addr.s_addr)
|
if (!clients[i].addr.s_addr)
|
||||||
continue;
|
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),
|
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[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);
|
BuildResp_upnphttp(h, str.data, str.off);
|
||||||
SendResp_upnphttp(h);
|
SendResp_upnphttp(h);
|
||||||
@ -1633,7 +1635,7 @@ SendResp_resizedimg(struct upnphttp * h, char * object)
|
|||||||
|
|
||||||
#if USE_FORK
|
#if USE_FORK
|
||||||
pid_t newpid = 0;
|
pid_t newpid = 0;
|
||||||
newpid = process_fork();
|
newpid = process_fork(h->req_client);
|
||||||
if( newpid > 0 )
|
if( newpid > 0 )
|
||||||
{
|
{
|
||||||
CloseSocket_upnphttp(h);
|
CloseSocket_upnphttp(h);
|
||||||
@ -1875,7 +1877,7 @@ SendResp_dlnafile(struct upnphttp *h, char *object)
|
|||||||
sqlite3_free_table(result);
|
sqlite3_free_table(result);
|
||||||
}
|
}
|
||||||
#if USE_FORK
|
#if USE_FORK
|
||||||
newpid = process_fork();
|
newpid = process_fork(h->req_client);
|
||||||
if( newpid > 0 )
|
if( newpid > 0 )
|
||||||
{
|
{
|
||||||
CloseSocket_upnphttp(h);
|
CloseSocket_upnphttp(h);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user