Support multi-process model
The same multi-process model as Nginx Signed-off-by: Jianhui Zhao <zhaojh329@gmail.com>main^2
parent
55a9b04d31
commit
ffa199a647
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
* 支持 IPv6
|
* 支持 IPv6
|
||||||
* 支持插件
|
* 支持插件
|
||||||
* 支持上传大文件
|
* 支持上传大文件
|
||||||
|
* 支持多进程模型 - 和 Nginx 一样的多进程模型
|
||||||
* 可伸缩 - 你可以非常方便的扩展你的应用程序,使之具备HTTP/HTTPS服务
|
* 可伸缩 - 你可以非常方便的扩展你的应用程序,使之具备HTTP/HTTPS服务
|
||||||
* 代码结构简洁通俗易懂,亦适合学习
|
* 代码结构简洁通俗易懂,亦适合学习
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
45
src/uhttpd.c
45
src/uhttpd.c
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue