Support multi-process model

The same multi-process model as Nginx

Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>
main^2
Jianhui Zhao 2021-01-03 16:19:24 +08:00
parent 55a9b04d31
commit ffa199a647
5 changed files with 51 additions and 3 deletions

View File

@ -33,6 +33,7 @@ A very flexible, lightweight and fully asynchronous HTTP server library based on
* Support IPv6 * Support IPv6
* Support plugin * Support plugin
* Support upload large file * Support upload large file
* Support multi-process model - The same multi-process model as Nginx
* Flexible - you can easily extend your application to have HTTP/HTTPS services * Flexible - you can easily extend your application to have HTTP/HTTPS services
* Code structure is concise and understandable, also suitable for learning * Code structure is concise and understandable, also suitable for learning

View File

@ -33,6 +33,7 @@
* 支持 IPv6 * 支持 IPv6
* 支持插件 * 支持插件
* 支持上传大文件 * 支持上传大文件
* 支持多进程模型 - 和 Nginx 一样的多进程模型
* 可伸缩 - 你可以非常方便的扩展你的应用程序使之具备HTTP/HTTPS服务 * 可伸缩 - 你可以非常方便的扩展你的应用程序使之具备HTTP/HTTPS服务
* 代码结构简洁通俗易懂,亦适合学习 * 代码结构简洁通俗易懂,亦适合学习

View File

@ -196,6 +196,8 @@ int main(int argc, char **argv)
goto err; goto err;
#endif #endif
srv->start_worker(srv, -1); /* -1 means automatically to available CPUs */
srv->set_docroot(srv, docroot); srv->set_docroot(srv, docroot);
srv->set_index_page(srv, index_page); srv->set_index_page(srv, index_page);

View File

@ -32,6 +32,7 @@
#ifdef HAVE_DLOPEN #ifdef HAVE_DLOPEN
#include <dlfcn.h> #include <dlfcn.h>
#endif #endif
#include <sys/sysinfo.h>
#include "uhttpd_internal.h" #include "uhttpd_internal.h"
#include "connection.h" #include "connection.h"
@ -100,7 +101,8 @@ static void uh_accept_cb(struct ev_loop *loop, struct ev_io *w, int revents)
sock = accept4(srv->sock, (struct sockaddr *)&addr, &addr_len, SOCK_NONBLOCK | SOCK_CLOEXEC); sock = accept4(srv->sock, (struct sockaddr *)&addr, &addr_len, SOCK_NONBLOCK | SOCK_CLOEXEC);
if (sock < 0) { if (sock < 0) {
uh_log_err("accept: %s\n", strerror(errno)); if (errno != EAGAIN)
uh_log_err("accept: %s\n", strerror(errno));
return; return;
} }
@ -123,6 +125,43 @@ static void uh_accept_cb(struct ev_loop *loop, struct ev_io *w, int revents)
srv->conns = conn; 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_start_worker(struct uh_server *srv, int n)
{
struct uh_server_internal *srvi = (struct uh_server_internal *)srv;
pid_t pid;
int i;
if (n < 0)
n = get_nprocs();
if (n > 0)
uh_stop_accept(srvi);
for (i = 0; i < n; i++) {
pid = fork();
switch (pid) {
case -1:
uh_log_err("fork: %s\n", strerror(errno));
return;
case 0:
ev_loop_fork(srvi->loop);
uh_start_accept(srvi);
return;
}
}
}
struct uh_server *uh_server_new(struct ev_loop *loop, const char *host, int port) struct uh_server *uh_server_new(struct ev_loop *loop, const char *host, int port)
{ {
struct uh_server *srv; struct uh_server *srv;
@ -345,6 +384,7 @@ int uh_server_init(struct uh_server *srv, struct ev_loop *loop, const char *host
srvi->loop = loop ? loop : EV_DEFAULT; srvi->loop = loop ? loop : EV_DEFAULT;
srvi->sock = sock; srvi->sock = sock;
srv->free = uh_server_free; srv->free = uh_server_free;
srv->start_worker = uh_start_worker;
#if UHTTPD_SSL_SUPPORT #if UHTTPD_SSL_SUPPORT
srv->ssl_init = uh_server_ssl_init; srv->ssl_init = uh_server_ssl_init;
@ -358,8 +398,7 @@ int uh_server_init(struct uh_server *srv, struct ev_loop *loop, const char *host
srv->set_docroot = uh_set_docroot; srv->set_docroot = uh_set_docroot;
srv->set_index_page = uh_set_index_page; srv->set_index_page = uh_set_index_page;
ev_io_init(&srvi->ior, uh_accept_cb, sock, EV_READ); uh_start_accept(srvi);
ev_io_start(srvi->loop, &srvi->ior);
return 0; return 0;

View File

@ -79,6 +79,11 @@ typedef void (*uh_path_handler_prototype)(struct uh_connection *conn, int event)
struct uh_server { struct uh_server {
void (*free)(struct uh_server *srv); void (*free)(struct uh_server *srv);
/*
** Start n worker processes to process the requests
** If n is -1, automatically to available CPUs
*/
void (*start_worker)(struct uh_server *srv, int n);
#if UHTTPD_SSL_SUPPORT #if UHTTPD_SSL_SUPPORT
int (*ssl_init)(struct uh_server *srv, const char *cert, const char *key); int (*ssl_init)(struct uh_server *srv, const char *cert, const char *key);
#endif #endif