Commit c1c93a5a authored by Vincent Wei's avatar Vincent Wei
Browse files

handle exit of local buddy client

parent 08fc21de
......@@ -139,10 +139,14 @@ static struct _demo_info {
char* const exe_file;
char* const def_mode;
} _demo_list [] = {
{"mguxdemo", "/usr/local/bin/", "/usr/local/bin/mguxdemo", "360x480-16bpp"},
{"mguxdemo", "/usr/local/bin/", "/usr/local/bin/mguemo", "360x480-16bpp"},
{"cbplusui", "/usr/local/bin/", "/usr/local/bin/cbplusui", "240x240-16bpp"},
};
/* return 0: bad request;
return > 0: launched;
return < 0: vfork error;
*/
pid_t us_launch_client (const char* demo_name)
{
int i, found = -1;
......
......@@ -32,6 +32,8 @@
#include <getopt.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#if HAVE_CONFIG_H
#include "config.h"
......@@ -111,17 +113,28 @@ cmd_help (void)
static void
handle_signal_action (int sig_number)
{
if (sig_number == SIGINT) {
printf ("SIGINT caught!\n");
/* if it fails to write, force stop */
ws_stop (server);
}
else if (sig_number == SIGPIPE) {
printf ("SIGPIPE caught!\n");
}
else if (sig_number == SIGCHLD) {
printf ("SIGCHLD caught!\n");
}
if (sig_number == SIGINT) {
printf ("SIGINT caught!\n");
/* if it fails to write, force stop */
ws_stop (server);
}
else if (sig_number == SIGPIPE) {
printf ("SIGPIPE caught!\n");
}
else if (sig_number == SIGCHLD) {
int pid;
int status;
while ((pid = waitpid (-1, &status, WNOHANG)) > 0) {
if (WIFEXITED (status)) {
printf ("Child #%d exited with status: %x (return value: %d)\n",
pid, status, WEXITSTATUS (status));
ws_handle_buddy_exit (server, pid);
}
else if (WIFSIGNALED(status))
printf ("Child #%d signaled by %d\n", pid, WTERMSIG (status));
}
}
}
static int
......@@ -145,16 +158,11 @@ setup_signals (void)
return 0;
}
static int
static pid_t
onopen (WSClient * client)
{
pid_t pid_usc;
pid_usc = us_launch_client (client->headers->path + 1);
client->pid_buddy = pid_usc;
printf ("INFO: Got a request from client (%d) %s and fork a child %d\n", client->listener, client->headers->path, pid_usc);
return 0;
printf ("INFO: Got a request from client (%d) %s and will launch a child\n", client->listener, client->headers->path);
return us_launch_client (client->headers->path + 1);
}
static int
......
......@@ -1534,8 +1534,24 @@ ws_get_handshake (WSClient * client, WSServer * server)
ws_send_handshake_headers (client, client->headers);
/* upon success, call onopen() callback */
if (server->onopen && !wsconfig.echomode)
server->onopen (client);
if (server->onopen && !wsconfig.echomode) {
pid_t pid_buddy = server->onopen (client);
if (pid_buddy > 0) {
client->pid_buddy = pid_buddy;
client->status_buddy = WS_BUDDY_LAUNCHED;
client->launched_time_buddy = time (NULL);
}
else if (pid_buddy == 0) {
http_error (client, WS_BAD_REQUEST_STR);
return ws_set_status (client, WS_CLOSE, bytes);
}
else {
http_error (client, WS_INTERNAL_ERROR_STR);
return ws_set_status (client, WS_CLOSE, bytes);
}
}
client->headers->reading = 0;
/* do access logging */
......@@ -2190,8 +2206,7 @@ handle_write_close (int conn, WSClient * client, WSServer * server)
static int
handle_ws_writes (int conn, WSServer * server)
{
WSClient *client = NULL;
WSClient *client = NULL;
if (!(client = ws_get_client_from_list (conn, &server->colist)))
return 1;
......@@ -2358,6 +2373,20 @@ ws_get_client_from_list_by_buddy (pid_t pid, GSLList ** colist)
return (WSClient *) match->data;
}
/* Handle the exit of a UnixSocket buddy */
void ws_handle_buddy_exit (WSServer * server, pid_t pid)
{
WSClient *client = NULL;
client = ws_get_client_from_list_by_buddy (pid, &server->colist);
if (client == NULL) {
printf ("ws_handle_exit_buddy: does not find client by PID: %d\n", pid);
return;
}
client->status_buddy = WS_BUDDY_EXITED;
}
/* Handle a new UNIX socket connection. */
static void
handle_us_accept (int listener, WSServer * server)
......@@ -2378,6 +2407,7 @@ handle_us_accept (int listener, WSServer * server)
return;
}
client->status_buddy = WS_BUDDY_CONNECTED;
client->us_buddy->fd = newfd;
client->us_buddy->pid = pid_buddy;
......
......@@ -96,6 +96,7 @@
#define WS_BAD_REQUEST_STR "HTTP/1.1 400 Invalid Request\r\n\r\n"
#define WS_SWITCH_PROTO_STR "HTTP/1.1 101 Switching Protocols"
#define WS_TOO_BUSY_STR "HTTP/1.1 503 Service Unavailable\r\n\r\n"
#define WS_INTERNAL_ERROR_STR "HTTP/1.1 505 Internal Server Error\r\n\r\n"
#define CRLF "\r\n"
#define SHA_DIGEST_LENGTH 20
......@@ -140,6 +141,14 @@ typedef enum WSSTATUS
WS_TLS_SHUTTING = (1 << 8),
} WSStatus;
typedef enum WSBUDDYSTATUS
{
WS_BUDDY_UNKNOWN = 0x00,
WS_BUDDY_LAUNCHED = 0x01,
WS_BUDDY_CONNECTED = 0x02,
WS_BUDDY_EXITED = 0x03,
} WSBuddyStatus;
typedef enum WSOPCODE
{
WS_OPCODE_CONTINUATION = 0x00,
......@@ -253,6 +262,9 @@ typedef struct WSClient_
#endif
pid_t pid_buddy; /* PID of local buddy */
WSBuddyStatus status_buddy; /* buddy status */
time_t launched_time_buddy; /* Epoch time launched the buddy */
struct USClient_* us_buddy; /* UNIX socket */
} WSClient;
......@@ -281,7 +293,7 @@ typedef struct WSServer_
/* Callbacks */
int (*onclose) (WSClient * client);
int (*onmessage) (WSClient * client);
int (*onopen) (WSClient * client);
pid_t (*onopen) (WSClient * client);
/* Connected Clients */
GSLList *colist;
......@@ -293,11 +305,11 @@ typedef struct WSServer_
size_t pack_uint32 (void *buf, uint32_t val, int convert);
size_t unpack_uint32 (const void *buf, uint32_t * val, int convert);
void set_nonblocking (int listener);
int ws_send_data (WSClient * client, WSOpcode opcode, const char *p, int sz);
int ws_setfifo (const char *pipename);
int ws_validate_string (const char *str, int len);
void set_nonblocking (int listener);
void ws_handle_buddy_exit (WSServer * server, pid_t pid);
void ws_set_config_accesslog (const char *accesslog);
void ws_set_config_echomode (int echomode);
void ws_set_config_frame_size (int max_frm_size);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment