Multi-process operation are not directly integrated

The multi-process model is presented as sample code.

Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
This commit is contained in:
Jianhui Zhao committed 2021-01-09 00:04:50 +08:00
1 parent 808bb3785b
commit c28eaa2bb7
12 files changed
+545 -231

No files matched your search

+1
View File
@@ -142,6 +142,7 @@ install(
FILES
uhttpd.h
log.h
utils.h
buffer/buffer.h
http-parser/http_parser.h
${CMAKE_CURRENT_BINARY_DIR}/config.h
+25 -120
View File
@@ -31,8 +31,6 @@
#ifdef HAVE_DLOPEN
#include <dlfcn.h>
#endif
#include <sys/sysinfo.h>
#include <sys/prctl.h>
#include "uhttpd_internal.h"
#include "connection.h"
@@ -125,110 +123,6 @@ static void uh_accept_cb(struct ev_loop *loop, struct ev_io *w, int revents)
srv->conns = conn;
}
static void uh_start_accept(struct uh_server_internal *srv)
{
ev_io_init(&srv->ior, uh_accept_cb, srv->sock, EV_READ);
ev_io_start(srv->loop, &srv->ior);
}
static void uh_stop_accept(struct uh_server_internal *srv)
{
ev_io_stop(srv->loop, &srv->ior);
}
static void uh_worker_exit(struct ev_loop *loop, struct ev_child *w, int revents)
{
struct worker *wk = container_of(w, struct worker, w);
uh_log_info("worker %d exit\n", wk->i);
free(wk);
}
static int uh_socket(int family)
{
int on = 1;
int sock;
sock = socket(family, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
if (sock < 0) {
uh_log_err("socket: %s\n", strerror(errno));
return -1;
}
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(int)) < 0) {
uh_log_err("setsockopt: %s\n", strerror(errno));
close(sock);
return -1;
}
setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(int));
return sock;
}
static int uh_listen(int sock, struct sockaddr *addr, socklen_t addrlen)
{
if (bind(sock, addr, addrlen) < 0) {
uh_log_err("bind: %s\n", strerror(errno));
return -1;
}
listen(sock, SOMAXCONN);
return 0;
}
static void uh_start_worker(struct uh_server *srv, int n)
{
struct uh_server_internal *srvi = (struct uh_server_internal *)srv;
pid_t pids[20];
int i;
if (n < 0)
n = get_nprocs();
if (n < 2)
return;
uh_stop_accept(srvi);
if (srvi->reuseport)
close(srvi->sock);
for (i = 0; i < n; i++) {
pids[i] = fork();
switch (pids[i]) {
case -1:
uh_log_err("fork: %s\n", strerror(errno));
return;
case 0:
prctl(PR_SET_PDEATHSIG, SIGKILL);
ev_loop_fork(srvi->loop);
if (srvi->reuseport) {
srvi->sock = uh_socket(srvi->addr.sa.sa_family);
uh_listen(srvi->sock, &srvi->addr.sa, srvi->addrlen);
}
uh_start_accept(srvi);
uh_log_info("worker %d started\n", i);
ev_run(srvi->loop, 0);
return;
}
}
while (i-- > 0) {
struct worker *w = calloc(1, sizeof(struct worker));
w->i = i;
ev_child_init(&w->w, uh_worker_exit, pids[i], 0);
ev_child_start(srvi->loop, &w->w);
}
}
struct uh_server *uh_server_new(struct ev_loop *loop, const char *host, int port)
{
struct uh_server *srv;
@@ -389,6 +283,7 @@ int uh_server_init(struct uh_server *srv, struct ev_loop *loop, const char *host
char addr_str[INET6_ADDRSTRLEN];
socklen_t addrlen;
int sock = -1;
int on = 1;
if (!host || *host == '\0') {
addr.sin.sin_family = AF_INET;
@@ -428,34 +323,41 @@ int uh_server_init(struct uh_server *srv, struct ev_loop *loop, const char *host
inet_ntop(AF_INET6, &addr.sin6.sin6_addr, addr_str, sizeof(addr_str));
}
memset(srvi, 0, sizeof(struct uh_server_internal));
srvi->loop = loop ? loop : EV_DEFAULT;
srvi->reuseport = support_so_reuseport();
sock = uh_socket(addr.sa.sa_family);
if (sock < 0)
sock = socket(addr.sa.sa_family, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
if (sock < 0) {
uh_log_err("socket: %s\n", strerror(errno));
return -1;
}
if (uh_listen(sock, &addr.sa, addrlen) < 0)
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(int)) < 0) {
uh_log_err("setsockopt: %s\n", strerror(errno));
goto err;
}
srvi->sock = sock;
setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(int));
uh_start_accept(srvi);
if (bind(sock, &addr.sa, addrlen) < 0) {
uh_log_err("bind: %s\n", strerror(errno));
goto err;
}
srvi->addrlen = addrlen;
memcpy(&srvi->addr, &addr, sizeof(addr));
if (listen(sock, SOMAXCONN) < 0) {
uh_log_err("bind: %s\n", strerror(errno));
goto err;
}
if (uh_log_get_threshold() == LOG_DEBUG) {
saddr2str(&addr.sa, addr_str, sizeof(addr_str), &port);
uh_log_debug("Listen on: %s %d\n", addr_str, port);
}
memset(srvi, 0, sizeof(struct uh_server_internal));
srvi->loop = loop ? loop : EV_DEFAULT;
srvi->sock = sock;
srv->get_loop = uh_get_loop;
srv->free = uh_server_free;
srv->start_worker = uh_start_worker;
#if UHTTPD_SSL_SUPPORT
srv->ssl_init = uh_server_ssl_init;
@@ -469,6 +371,9 @@ int uh_server_init(struct uh_server *srv, struct ev_loop *loop, const char *host
srv->set_docroot = uh_set_docroot;
srv->set_index_page = uh_set_index_page;
ev_io_init(&srvi->ior, uh_accept_cb, sock, EV_READ);
ev_io_start(srvi->loop, &srvi->ior);
return 0;
err:
+1 -6
View File
@@ -32,6 +32,7 @@
#include "http_parser.h"
#include "config.h"
#include "utils.h"
#include "log.h"
struct uh_str {
@@ -84,12 +85,6 @@ typedef void (*uh_path_handler_prototype)(struct uh_connection *conn, int event)
struct uh_server {
struct ev_loop *(*get_loop)(struct uh_server *srv);
void (*free)(struct uh_server *srv);
/*
** Start n worker processes to process the requests
** Must be called after the Server has been initialized
** If n is -1, automatically to available CPUs
*/
void (*start_worker)(struct uh_server *srv, int n);
#if UHTTPD_SSL_SUPPORT
int (*ssl_init)(struct uh_server *srv, const char *cert, const char *key);
#endif
-7
View File
@@ -34,13 +34,6 @@ struct uh_connection_internal;
struct uh_server_internal {
struct uh_server com;
int sock;
bool reuseport;
union {
struct sockaddr sa;
struct sockaddr_in sin;
struct sockaddr_in6 sin6;
} addr;
socklen_t addrlen;
char *docroot;
char *index_page;
struct ev_loop *loop;