mirror of https://github.com/F-Stack/f-stack.git
Merge pull request #117 from chadwill/master
Nginx: support kernel network stack
This commit is contained in:
commit
c4e752fc00
|
@ -106,8 +106,8 @@ WIN32_SELECT_SRCS=src/event/modules/ngx_win32_select_module.c
|
|||
POLL_MODULE=ngx_poll_module
|
||||
POLL_SRCS=src/event/modules/ngx_poll_module.c
|
||||
|
||||
KQUEUE_MODULE="ngx_kqueue_module ngx_ff_channel_module"
|
||||
KQUEUE_SRCS="src/event/modules/ngx_kqueue_module.c src/event/modules/ngx_ff_module.c src/event/modules/ngx_ff_channel.c"
|
||||
KQUEUE_MODULE="ngx_kqueue_module ngx_ff_host_event_module"
|
||||
KQUEUE_SRCS="src/event/modules/ngx_kqueue_module.c src/event/modules/ngx_ff_module.c src/event/modules/ngx_ff_host_event_module.c"
|
||||
|
||||
DEVPOLL_MODULE=ngx_devpoll_module
|
||||
DEVPOLL_SRCS=src/event/modules/ngx_devpoll_module.c
|
||||
|
|
|
@ -41,6 +41,10 @@ http {
|
|||
listen 80;
|
||||
server_name localhost;
|
||||
|
||||
# bulid server on kernel network stack
|
||||
#
|
||||
#kernel_network_stack on;
|
||||
|
||||
#charset koi8-r;
|
||||
|
||||
access_log /dev/null;
|
||||
|
|
|
@ -376,6 +376,10 @@ ngx_set_inherited_sockets(ngx_cycle_t *cycle)
|
|||
return NGX_OK;
|
||||
}
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
extern int
|
||||
fstack_territory(int domain, int type, int protocol);
|
||||
#endif
|
||||
|
||||
ngx_int_t
|
||||
ngx_open_listening_sockets(ngx_cycle_t *cycle)
|
||||
|
@ -404,6 +408,36 @@ ngx_open_listening_sockets(ngx_cycle_t *cycle)
|
|||
ls = cycle->listening.elts;
|
||||
for (i = 0; i < cycle->listening.nelts; i++) {
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
|
||||
if (ngx_process <= NGX_PROCESS_MASTER) {
|
||||
|
||||
/* process master, kernel network stack*/
|
||||
if (!ls[i].belong_to_host) {
|
||||
/* We should continue to process the listening socket,
|
||||
if it is not supported by fstack.*/
|
||||
if (fstack_territory(ls[i].sockaddr->sa_family, ls[i].type, 0)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} else if (NGX_PROCESS_WORKER == ngx_process) {
|
||||
/* process worker, fstack */
|
||||
if (ls[i].belong_to_host) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!fstack_territory(ls[i].sockaddr->sa_family, ls[i].type, 0)) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
|
||||
"unexpected process type: %d, ignored",
|
||||
ngx_process);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if (ls[i].ignore) {
|
||||
continue;
|
||||
}
|
||||
|
@ -971,6 +1005,15 @@ ngx_close_listening_sockets(ngx_cycle_t *cycle)
|
|||
ls = cycle->listening.elts;
|
||||
for (i = 0; i < cycle->listening.nelts; i++) {
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
|
||||
// No need to deal with, just skip
|
||||
if (fstack_territory(ls[i].sockaddr->sa_family, ls[i].type, 0)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
#endif //(NGX_HAVE_FSTACK)
|
||||
|
||||
c = ls[i].connection;
|
||||
|
||||
if (c) {
|
||||
|
@ -1032,6 +1075,9 @@ ngx_get_connection(ngx_socket_t s, ngx_log_t *log)
|
|||
ngx_uint_t instance;
|
||||
ngx_event_t *rev, *wev;
|
||||
ngx_connection_t *c;
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
ngx_atomic_uint_t success;
|
||||
#endif
|
||||
|
||||
/* disable warning: Win32 SOCKET is u_int while UNIX socket is int */
|
||||
|
||||
|
@ -1042,7 +1088,35 @@ ngx_get_connection(ngx_socket_t s, ngx_log_t *log)
|
|||
s, ngx_cycle->files_n);
|
||||
return NULL;
|
||||
}
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
#ifndef unlikely
|
||||
#define unlikely(x) __builtin_expect((x),0)
|
||||
#endif
|
||||
/* move ngx_cycle->free_connections atomically */
|
||||
do {
|
||||
/* Restore n as it may change every loop */
|
||||
c = ngx_cycle->free_connections;
|
||||
|
||||
if (c == NULL) {
|
||||
ngx_drain_connections((ngx_cycle_t *) ngx_cycle);
|
||||
c = ngx_cycle->free_connections;
|
||||
}
|
||||
|
||||
if (c == NULL) {
|
||||
ngx_log_error(NGX_LOG_ALERT, log, 0,
|
||||
"%ui worker_connections are not enough",
|
||||
ngx_cycle->connection_n);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
success = ngx_atomic_cmp_set(&ngx_cycle->free_connections, c,
|
||||
c->data);
|
||||
|
||||
} while (unlikely(success == 0));
|
||||
|
||||
ngx_memory_barrier();
|
||||
#else
|
||||
c = ngx_cycle->free_connections;
|
||||
|
||||
if (c == NULL) {
|
||||
|
@ -1059,6 +1133,7 @@ ngx_get_connection(ngx_socket_t s, ngx_log_t *log)
|
|||
}
|
||||
|
||||
ngx_cycle->free_connections = c->data;
|
||||
#endif
|
||||
ngx_cycle->free_connection_n--;
|
||||
|
||||
if (ngx_cycle->files && ngx_cycle->files[s] == NULL) {
|
||||
|
@ -1098,8 +1173,25 @@ ngx_get_connection(ngx_socket_t s, ngx_log_t *log)
|
|||
void
|
||||
ngx_free_connection(ngx_connection_t *c)
|
||||
{
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
ngx_atomic_uint_t success;
|
||||
|
||||
/* move ngx_cycle->free_connections atomically */
|
||||
do {
|
||||
/* Restore n as it may change every loop */
|
||||
c->data = ngx_cycle->free_connections;
|
||||
|
||||
success = ngx_atomic_cmp_set(&ngx_cycle->free_connections, c->data,
|
||||
c);
|
||||
|
||||
} while (unlikely(success == 0));
|
||||
|
||||
ngx_memory_barrier();
|
||||
|
||||
#else
|
||||
ngx_cycle->free_connections = c;
|
||||
|
||||
#endif
|
||||
ngx_cycle->free_connection_n++;
|
||||
|
||||
if (ngx_cycle->files && ngx_cycle->files[c->fd] == c) {
|
||||
|
@ -1129,7 +1221,11 @@ ngx_close_connection(ngx_connection_t *c)
|
|||
}
|
||||
|
||||
if (!c->shared) {
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
if (ngx_event_actions.del_conn) {
|
||||
#else
|
||||
if (ngx_del_conn) {
|
||||
#endif
|
||||
ngx_del_conn(c, NGX_CLOSE_EVENT);
|
||||
|
||||
} else {
|
||||
|
|
|
@ -87,6 +87,9 @@ struct ngx_listening_s {
|
|||
int fastopen;
|
||||
#endif
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
unsigned belong_to_host:1;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -609,11 +609,9 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
|
|||
}
|
||||
}
|
||||
|
||||
#if (!NGX_HAVE_FSTACK)
|
||||
if (ngx_open_listening_sockets(cycle) != NGX_OK) {
|
||||
goto failed;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!ngx_test_config) {
|
||||
ngx_configure_listening_sockets(cycle);
|
||||
|
|
|
@ -4512,7 +4512,11 @@ ngx_tcp_connect(ngx_resolver_connection_t *rec)
|
|||
|
||||
c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1);
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
if (ngx_event_actions.add_conn) {
|
||||
#else
|
||||
if (ngx_add_conn) {
|
||||
#endif
|
||||
if (ngx_add_conn(c) == NGX_ERROR) {
|
||||
goto failed;
|
||||
}
|
||||
|
@ -4564,7 +4568,11 @@ ngx_tcp_connect(ngx_resolver_connection_t *rec)
|
|||
}
|
||||
}
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
if (ngx_event_actions.add_conn) {
|
||||
#else
|
||||
if (ngx_add_conn) {
|
||||
#endif
|
||||
if (rc == -1) {
|
||||
|
||||
/* NGX_EINPROGRESS */
|
||||
|
|
|
@ -33,10 +33,12 @@
|
|||
#include <pthread.h>
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
static void * ngx_ff_channel_create_conf(ngx_cycle_t *cycle);
|
||||
static char * ngx_ff_channel_init_conf(ngx_cycle_t *cycle,
|
||||
static void * ngx_ff_host_event_create_conf(ngx_cycle_t *cycle);
|
||||
static char * ngx_ff_host_event_init_conf(ngx_cycle_t *cycle,
|
||||
void *conf);
|
||||
static ngx_int_t ngx_ff_epoll_init(ngx_cycle_t *cycle);
|
||||
static ngx_int_t ngx_ff_host_event_init_process(ngx_cycle_t *cycle);
|
||||
static void ngx_ff_host_event_exit_process(ngx_cycle_t *cycle);
|
||||
static ngx_int_t ngx_ff_epoll_init(ngx_cycle_t *cycle, ngx_msec_t timer);
|
||||
static ngx_int_t ngx_ff_epoll_add_event(ngx_event_t *ev,
|
||||
ngx_int_t event, ngx_uint_t flags);
|
||||
static ngx_int_t ngx_ff_epoll_del_event(ngx_event_t *ev,
|
||||
|
@ -46,14 +48,19 @@ static ngx_int_t ngx_ff_epoll_process_events(ngx_cycle_t *cycle,
|
|||
static ngx_int_t ngx_ff_create_connection(ngx_cycle_t *cycle);
|
||||
static void ngx_ff_delete_connection();
|
||||
static void ngx_ff_worker_channel_handler(ngx_event_t *ev);
|
||||
static void *ngx_ff_channel_thread_main(void *args);
|
||||
static void *ngx_ff_host_event_thread_main(void *args);
|
||||
static ngx_int_t ngx_ff_add_channel_event(ngx_cycle_t *cycle,
|
||||
ngx_fd_t fd, ngx_int_t event, ngx_event_handler_pt handler);
|
||||
static ngx_int_t ngx_ff_process_channel_events(ngx_cycle_t *cycle);
|
||||
static void ngx_ff_process_events_and_timers(ngx_cycle_t *cycle);
|
||||
|
||||
ngx_int_t ngx_ff_start_worker_channel(ngx_cycle_t *cycle,
|
||||
ngx_fd_t fd, ngx_int_t event);
|
||||
|
||||
void ngx_event_cancel_timers_of_host(void);
|
||||
void ngx_event_expire_timers_of_host(void);
|
||||
ngx_msec_t ngx_event_find_timer_of_host(void);
|
||||
void ngx_event_cancel_timers_of_host(void);
|
||||
|
||||
struct channel_thread_args {
|
||||
ngx_cycle_t *cycle;
|
||||
ngx_fd_t fd;
|
||||
|
@ -69,41 +76,44 @@ static struct epoll_event *event_list;
|
|||
static ngx_uint_t nevents;
|
||||
static ngx_connection_t *channel_connection;
|
||||
|
||||
#include <semaphore.h>
|
||||
static sem_t sem;
|
||||
|
||||
typedef struct {
|
||||
ngx_uint_t events;
|
||||
} ngx_ff_channel_conf_t;
|
||||
} ngx_ff_host_event_conf_t;
|
||||
|
||||
|
||||
static ngx_command_t ngx_ff_channel_commands[] = {
|
||||
static ngx_command_t ngx_ff_host_event_commands[] = {
|
||||
ngx_null_command
|
||||
};
|
||||
|
||||
ngx_core_module_t ngx_ff_channel_module_ctx = {
|
||||
ngx_string("ff_channel"),
|
||||
ngx_ff_channel_create_conf, /* create configuration */
|
||||
ngx_ff_channel_init_conf, /* init configuration */
|
||||
ngx_core_module_t ngx_ff_host_event_module_ctx = {
|
||||
ngx_string("ff_host_event"),
|
||||
ngx_ff_host_event_create_conf, /* create configuration */
|
||||
ngx_ff_host_event_init_conf, /* init configuration */
|
||||
};
|
||||
|
||||
ngx_module_t ngx_ff_channel_module = {
|
||||
ngx_module_t ngx_ff_host_event_module = {
|
||||
NGX_MODULE_V1,
|
||||
&ngx_ff_channel_module_ctx, /* module context */
|
||||
ngx_ff_channel_commands, /* module directives */
|
||||
&ngx_ff_host_event_module_ctx, /* module context */
|
||||
ngx_ff_host_event_commands, /* module directives */
|
||||
NGX_CORE_MODULE, /* module type */
|
||||
NULL, /* init master */
|
||||
NULL, /* init module */
|
||||
ngx_ff_epoll_init, /* init process */
|
||||
ngx_ff_host_event_init_process, /* init process */
|
||||
NULL, /* init thread */
|
||||
NULL, /* exit thread */
|
||||
NULL, /* exit process */
|
||||
ngx_ff_host_event_exit_process, /* exit process */
|
||||
NULL, /* exit master */
|
||||
NGX_MODULE_V1_PADDING
|
||||
};
|
||||
|
||||
static void *
|
||||
ngx_ff_channel_create_conf(ngx_cycle_t *cycle)
|
||||
ngx_ff_host_event_create_conf(ngx_cycle_t *cycle)
|
||||
{
|
||||
ngx_ff_channel_conf_t *cf;
|
||||
cf = ngx_palloc(cycle->pool, sizeof(ngx_ff_channel_conf_t));
|
||||
ngx_ff_host_event_conf_t *cf;
|
||||
cf = ngx_palloc(cycle->pool, sizeof(ngx_ff_host_event_conf_t));
|
||||
if (cf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -112,15 +122,40 @@ ngx_ff_channel_create_conf(ngx_cycle_t *cycle)
|
|||
}
|
||||
|
||||
static char *
|
||||
ngx_ff_channel_init_conf(ngx_cycle_t *cycle, void *conf)
|
||||
ngx_ff_host_event_init_conf(ngx_cycle_t *cycle, void *conf)
|
||||
{
|
||||
ngx_ff_channel_conf_t *cf = conf;
|
||||
ngx_ff_host_event_conf_t *cf = conf;
|
||||
cf->events = 1;
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t ngx_ff_host_event_init_process(ngx_cycle_t *cycle)
|
||||
{
|
||||
if (sem_init(&sem, 0, 0) != 0)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
static void ngx_ff_host_event_exit_process(ngx_cycle_t *cycle)
|
||||
{
|
||||
struct timespec ts;
|
||||
|
||||
if (clock_gettime( CLOCK_REALTIME,&ts ) < 0)
|
||||
return;
|
||||
|
||||
//5s
|
||||
ts.tv_sec += 4;
|
||||
|
||||
(void) sem_timedwait(&sem, &ts);
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_ff_epoll_init(ngx_cycle_t *cycle)
|
||||
ngx_ff_epoll_init(ngx_cycle_t *cycle, ngx_msec_t timer)
|
||||
{
|
||||
if (ep == -1) {
|
||||
ep = epoll_create(1);
|
||||
|
@ -413,6 +448,7 @@ ngx_ff_epoll_process_events(ngx_cycle_t *cycle,
|
|||
|
||||
if ((revents & EPOLLIN) && rev->active) {
|
||||
rev->ready = 1;
|
||||
rev->available = 1;
|
||||
rev->handler(rev);
|
||||
}
|
||||
|
||||
|
@ -531,6 +567,8 @@ ngx_ff_add_channel_event(ngx_cycle_t *cycle, ngx_fd_t fd,
|
|||
rev->channel = 1;
|
||||
wev->channel = 1;
|
||||
|
||||
rev->belong_to_host = wev->belong_to_host = 1;
|
||||
|
||||
ev = (event == NGX_READ_EVENT) ? rev : wev;
|
||||
ev->handler = handler;
|
||||
|
||||
|
@ -623,7 +661,7 @@ ngx_ff_worker_channel_handler(ngx_event_t *ev)
|
|||
}
|
||||
|
||||
static void *
|
||||
ngx_ff_channel_thread_main(void *args)
|
||||
ngx_ff_host_event_thread_main(void *args)
|
||||
{
|
||||
struct channel_thread_args *cta = args;
|
||||
ngx_cycle_t *cycle = cta->cycle;
|
||||
|
@ -634,21 +672,48 @@ ngx_ff_channel_thread_main(void *args)
|
|||
}
|
||||
|
||||
for (;;) {
|
||||
ngx_ff_process_channel_events(cycle);
|
||||
ngx_ff_process_events_and_timers(cycle);
|
||||
if (thread_quit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ngx_event_cancel_timers_of_host();
|
||||
|
||||
ngx_free(cta);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static ngx_int_t
|
||||
ngx_ff_process_channel_events(ngx_cycle_t *cycle)
|
||||
static void
|
||||
ngx_ff_process_events_and_timers(ngx_cycle_t *cycle)
|
||||
{
|
||||
return ngx_ff_epoll_process_events(cycle, 500, NGX_UPDATE_TIME);
|
||||
ngx_uint_t flags;
|
||||
ngx_msec_t timer, delta;
|
||||
|
||||
timer = ngx_event_find_timer_of_host();
|
||||
flags = NGX_UPDATE_TIME;
|
||||
|
||||
/* handle signals from master in case of network inactivity */
|
||||
|
||||
if (timer == NGX_TIMER_INFINITE || timer > 500) {
|
||||
timer = 500;
|
||||
}
|
||||
|
||||
delta = ngx_current_msec;
|
||||
|
||||
(void) ngx_ff_epoll_process_events(cycle, timer, flags);
|
||||
|
||||
delta = ngx_current_msec - delta;
|
||||
|
||||
ngx_event_process_posted(cycle, &ngx_posted_accept_events_of_host);
|
||||
|
||||
if (delta) {
|
||||
ngx_event_expire_timers_of_host();
|
||||
}
|
||||
|
||||
ngx_event_process_posted(cycle, &ngx_posted_events_of_host);
|
||||
|
||||
}
|
||||
|
||||
ngx_int_t
|
||||
|
@ -669,7 +734,7 @@ ngx_ff_start_worker_channel(ngx_cycle_t *cycle, ngx_fd_t fd,
|
|||
cta->handler = ngx_ff_worker_channel_handler;
|
||||
|
||||
ret = pthread_create(&channel_thread, NULL,
|
||||
ngx_ff_channel_thread_main, (void *)cta);
|
||||
ngx_ff_host_event_thread_main, (void *)cta);
|
||||
if (ret != 0) {
|
||||
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
|
||||
"pthread_create() failed");
|
||||
|
@ -681,4 +746,17 @@ ngx_ff_start_worker_channel(ngx_cycle_t *cycle, ngx_fd_t fd,
|
|||
return NGX_OK;
|
||||
}
|
||||
|
||||
ngx_event_actions_t ngx_ff_host_event_actions = {
|
||||
ngx_ff_epoll_add_event, /* add an event */
|
||||
ngx_ff_epoll_del_event, /* delete an event */
|
||||
ngx_ff_epoll_add_event, /* enable an event */
|
||||
ngx_ff_epoll_add_event, /* disable an event */
|
||||
NULL, /* add an connection */
|
||||
NULL, /* delete an connection */
|
||||
NULL, /* trigger a notify */
|
||||
ngx_ff_epoll_process_events, /* process the events */
|
||||
ngx_ff_epoll_init, /* init the events */
|
||||
NULL, /* done the events */
|
||||
};
|
||||
|
||||
#endif
|
|
@ -129,6 +129,35 @@ static int inited;
|
|||
real_##func; \
|
||||
})
|
||||
|
||||
extern intptr_t ngx_max_sockets;
|
||||
|
||||
/*-
|
||||
* Make sockfd assigned by the fstack plus the value of maximum kernel socket.
|
||||
* so we can tell them apart according to different scopes.
|
||||
* Solve the condominium ownership at Application Layer and obtain more freedom.
|
||||
* fstack tried to do this by 'fd_reserve', unfortunately, it doesn't work well.
|
||||
*/
|
||||
static inline int convert_fstack_fd(int sockfd) {
|
||||
return sockfd + ngx_max_sockets;
|
||||
}
|
||||
|
||||
/* Restore socket fd. */
|
||||
static inline int restore_fstack_fd(int sockfd) {
|
||||
if(sockfd <= ngx_max_sockets) {
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
return sockfd - ngx_max_sockets;
|
||||
}
|
||||
|
||||
/* Tell whether a 'sockfd' belongs to fstack. */
|
||||
static inline int is_fstack_fd(int sockfd) {
|
||||
if (unlikely(inited == 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return sockfd >= ngx_max_sockets;
|
||||
}
|
||||
|
||||
// proc_type, 1: primary, 0: secondary.
|
||||
int
|
||||
|
@ -151,8 +180,17 @@ ff_mod_init(const char *conf, int proc_id, int proc_type) {
|
|||
}
|
||||
|
||||
rc = ff_init(ff_argc, ff_argv);
|
||||
if (rc == 0)
|
||||
if (rc == 0) {
|
||||
/* Ensure that the socket we converted
|
||||
does not exceed the maximum value of 'int' */
|
||||
|
||||
if(ngx_max_sockets + (unsigned)ff_getmaxfd() > INT_MAX)
|
||||
{
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
inited = 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < ff_argc; i++) {
|
||||
free(ff_argv[i]);
|
||||
|
@ -163,9 +201,23 @@ ff_mod_init(const char *conf, int proc_id, int proc_type) {
|
|||
return rc;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Verify whether the socket is supported by fstack or not.
|
||||
*/
|
||||
int
|
||||
fstack_territory(int domain, int type, int protocol)
|
||||
{
|
||||
if ((AF_INET != domain) || (SOCK_STREAM != type && SOCK_DGRAM != type)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
socket(int domain, int type, int protocol)
|
||||
{
|
||||
int sock;
|
||||
if (unlikely(inited == 0)) {
|
||||
return SYSCALL(socket)(domain, type, protocol);
|
||||
}
|
||||
|
@ -174,250 +226,217 @@ socket(int domain, int type, int protocol)
|
|||
return SYSCALL(socket)(domain, type, protocol);
|
||||
}
|
||||
|
||||
return ff_socket(domain, type, protocol);
|
||||
sock = ff_socket(domain, type, protocol);
|
||||
|
||||
if (sock != -1) {
|
||||
sock = convert_fstack_fd(sock);
|
||||
}
|
||||
|
||||
return sock;
|
||||
}
|
||||
|
||||
int
|
||||
bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
|
||||
{
|
||||
if (unlikely(inited == 0)) {
|
||||
return SYSCALL(bind)(sockfd, addr, addrlen);
|
||||
if(is_fstack_fd(sockfd)){
|
||||
sockfd = restore_fstack_fd(sockfd);
|
||||
return ff_bind(sockfd, (struct linux_sockaddr *)addr, addrlen);
|
||||
}
|
||||
|
||||
if (ff_fdisused(sockfd)) {
|
||||
return ff_bind(sockfd, (struct linux_sockaddr *)addr, addrlen);
|
||||
} else {
|
||||
return SYSCALL(bind)(sockfd, addr, addrlen);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
|
||||
{
|
||||
if (unlikely(inited == 0)) {
|
||||
return SYSCALL(connect)(sockfd, addr, addrlen);
|
||||
if(is_fstack_fd(sockfd)){
|
||||
sockfd = restore_fstack_fd(sockfd);
|
||||
return ff_connect(sockfd, (struct linux_sockaddr *)addr, addrlen);
|
||||
}
|
||||
|
||||
if (ff_fdisused(sockfd)) {
|
||||
return ff_connect(sockfd, (struct linux_sockaddr *)addr, addrlen);
|
||||
} else {
|
||||
return SYSCALL(connect)(sockfd, addr, addrlen);
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t
|
||||
send(int sockfd, const void *buf, size_t len, int flags)
|
||||
{
|
||||
if (unlikely(inited == 0)) {
|
||||
return SYSCALL(send)(sockfd, buf, len, flags);
|
||||
if(is_fstack_fd(sockfd)){
|
||||
sockfd = restore_fstack_fd(sockfd);
|
||||
return ff_send(sockfd, buf, len, flags);
|
||||
}
|
||||
|
||||
if (ff_fdisused(sockfd)) {
|
||||
return ff_send(sockfd, buf, len, flags);
|
||||
} else {
|
||||
return SYSCALL(send)(sockfd, buf, len, flags);
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t
|
||||
sendto(int sockfd, const void *buf, size_t len, int flags,
|
||||
const struct sockaddr *dest_addr, socklen_t addrlen)
|
||||
{
|
||||
if (unlikely(inited == 0)) {
|
||||
return SYSCALL(sendto)(sockfd, buf, len, flags, dest_addr, addrlen);
|
||||
}
|
||||
|
||||
if (ff_fdisused(sockfd)) {
|
||||
if(is_fstack_fd(sockfd)){
|
||||
sockfd = restore_fstack_fd(sockfd);
|
||||
return ff_sendto(sockfd, buf, len, flags,
|
||||
(struct linux_sockaddr *)dest_addr, addrlen);
|
||||
} else {
|
||||
return SYSCALL(sendto)(sockfd, buf, len, flags, dest_addr, addrlen);
|
||||
}
|
||||
|
||||
return SYSCALL(sendto)(sockfd, buf, len, flags, dest_addr, addrlen);
|
||||
}
|
||||
|
||||
ssize_t
|
||||
sendmsg(int sockfd, const struct msghdr *msg, int flags)
|
||||
{
|
||||
if (unlikely(inited == 0)) {
|
||||
return SYSCALL(sendmsg)(sockfd, msg, flags);
|
||||
if(is_fstack_fd(sockfd)){
|
||||
sockfd = restore_fstack_fd(sockfd);
|
||||
return ff_sendmsg(sockfd, msg, flags);
|
||||
}
|
||||
|
||||
if (ff_fdisused(sockfd)) {
|
||||
return ff_sendmsg(sockfd, msg, flags);
|
||||
} else {
|
||||
return SYSCALL(sendmsg)(sockfd, msg, flags);
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t
|
||||
recv(int sockfd, void *buf, size_t len, int flags)
|
||||
{
|
||||
if (unlikely(inited == 0)) {
|
||||
return SYSCALL(recv)(sockfd, buf, len, flags);
|
||||
if(is_fstack_fd(sockfd)){
|
||||
sockfd = restore_fstack_fd(sockfd);
|
||||
return ff_recv(sockfd, buf, len, flags);
|
||||
}
|
||||
|
||||
if (ff_fdisused(sockfd)) {
|
||||
return ff_recv(sockfd, buf, len, flags);
|
||||
} else {
|
||||
return SYSCALL(recv)(sockfd, buf, len, flags);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
listen(int sockfd, int backlog)
|
||||
{
|
||||
if (unlikely(inited == 0)) {
|
||||
return SYSCALL(listen)(sockfd, backlog);
|
||||
if(is_fstack_fd(sockfd)){
|
||||
sockfd = restore_fstack_fd(sockfd);
|
||||
return ff_listen(sockfd, backlog);
|
||||
}
|
||||
|
||||
if (ff_fdisused(sockfd)) {
|
||||
return ff_listen(sockfd, backlog);
|
||||
} else {
|
||||
return SYSCALL(listen)(sockfd, backlog);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
getsockopt(int sockfd, int level, int optname,
|
||||
void *optval, socklen_t *optlen)
|
||||
{
|
||||
if (unlikely(inited == 0)) {
|
||||
return SYSCALL(getsockopt)(sockfd, level, optname, optval, optlen);
|
||||
if(is_fstack_fd(sockfd)){
|
||||
sockfd = restore_fstack_fd(sockfd);
|
||||
return ff_getsockopt(sockfd, level, optname, optval, optlen);
|
||||
}
|
||||
|
||||
if (ff_fdisused(sockfd)) {
|
||||
return ff_getsockopt(sockfd, level, optname, optval, optlen);
|
||||
} else {
|
||||
return SYSCALL(getsockopt)(sockfd, level, optname, optval, optlen);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
setsockopt (int sockfd, int level, int optname,
|
||||
const void *optval, socklen_t optlen)
|
||||
{
|
||||
if (unlikely(inited == 0)) {
|
||||
return SYSCALL(setsockopt)(sockfd, level, optname, optval, optlen);
|
||||
if(is_fstack_fd(sockfd)){
|
||||
sockfd = restore_fstack_fd(sockfd);
|
||||
return ff_setsockopt(sockfd, level, optname, optval, optlen);
|
||||
}
|
||||
|
||||
if (ff_fdisused(sockfd)) {
|
||||
return ff_setsockopt(sockfd, level, optname, optval, optlen);
|
||||
} else {
|
||||
return SYSCALL(setsockopt)(sockfd, level, optname, optval, optlen);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
|
||||
{
|
||||
if (unlikely(inited == 0)) {
|
||||
return SYSCALL(accept)(sockfd, addr, addrlen);
|
||||
int rc;
|
||||
if(is_fstack_fd(sockfd)){
|
||||
sockfd = restore_fstack_fd(sockfd);
|
||||
rc = ff_accept(sockfd, (struct linux_sockaddr *)addr, addrlen);
|
||||
if (rc != -1) {
|
||||
rc = convert_fstack_fd(rc);
|
||||
}
|
||||
|
||||
if (ff_fdisused(sockfd)) {
|
||||
return ff_accept(sockfd, (struct linux_sockaddr *)addr, addrlen);
|
||||
} else {
|
||||
return SYSCALL(accept)(sockfd, addr, addrlen);
|
||||
return rc;
|
||||
}
|
||||
|
||||
return SYSCALL(accept)(sockfd, addr, addrlen);
|
||||
}
|
||||
|
||||
int
|
||||
accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags)
|
||||
{
|
||||
if (unlikely(inited == 0)) {
|
||||
return SYSCALL(accept4)(sockfd, addr, addrlen, flags);
|
||||
int rc;
|
||||
if(is_fstack_fd(sockfd)){
|
||||
sockfd = restore_fstack_fd(sockfd);
|
||||
rc = ff_accept(sockfd, (struct linux_sockaddr *)addr, addrlen);
|
||||
if (rc != -1) {
|
||||
rc = convert_fstack_fd(rc);
|
||||
}
|
||||
|
||||
if (ff_fdisused(sockfd)) {
|
||||
return ff_accept(sockfd, (struct linux_sockaddr *)addr, addrlen);
|
||||
} else {
|
||||
return SYSCALL(accept4)(sockfd, addr, addrlen, flags);
|
||||
return rc;
|
||||
}
|
||||
|
||||
return SYSCALL(accept4)(sockfd, addr, addrlen, flags);
|
||||
}
|
||||
|
||||
int
|
||||
close(int sockfd)
|
||||
{
|
||||
if (unlikely(inited == 0)) {
|
||||
return SYSCALL(close)(sockfd);
|
||||
if(is_fstack_fd(sockfd)){
|
||||
sockfd = restore_fstack_fd(sockfd);
|
||||
return ff_close(sockfd);
|
||||
}
|
||||
|
||||
if (ff_fdisused(sockfd)) {
|
||||
return ff_close(sockfd);
|
||||
} else {
|
||||
return SYSCALL(close)(sockfd);
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t
|
||||
writev(int sockfd, const struct iovec *iov, int iovcnt)
|
||||
{
|
||||
if (unlikely(inited == 0)) {
|
||||
return SYSCALL(writev)(sockfd, iov, iovcnt);
|
||||
if(is_fstack_fd(sockfd)){
|
||||
sockfd = restore_fstack_fd(sockfd);
|
||||
return ff_writev(sockfd, iov, iovcnt);
|
||||
}
|
||||
|
||||
if (ff_fdisused(sockfd)) {
|
||||
return ff_writev(sockfd, iov, iovcnt);
|
||||
} else {
|
||||
return SYSCALL(writev)(sockfd, iov, iovcnt);
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t
|
||||
readv(int sockfd, const struct iovec *iov, int iovcnt)
|
||||
{
|
||||
if (unlikely(inited == 0)) {
|
||||
return SYSCALL(readv)(sockfd, iov, iovcnt);
|
||||
if(is_fstack_fd(sockfd)){
|
||||
sockfd = restore_fstack_fd(sockfd);
|
||||
return ff_readv(sockfd, iov, iovcnt);
|
||||
}
|
||||
|
||||
if (ff_fdisused(sockfd)) {
|
||||
return ff_readv(sockfd, iov, iovcnt);
|
||||
} else {
|
||||
return SYSCALL(readv)(sockfd, iov, iovcnt);
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t
|
||||
read(int sockfd, void *buf, size_t count)
|
||||
{
|
||||
if (unlikely(inited == 0)) {
|
||||
return SYSCALL(read)(sockfd, buf, count);
|
||||
if(is_fstack_fd(sockfd)){
|
||||
sockfd = restore_fstack_fd(sockfd);
|
||||
return ff_read(sockfd, buf, count);
|
||||
}
|
||||
|
||||
if (ff_fdisused(sockfd)) {
|
||||
return ff_read(sockfd, buf, count);
|
||||
} else {
|
||||
return SYSCALL(read)(sockfd, buf, count);
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t
|
||||
write(int sockfd, const void *buf, size_t count)
|
||||
{
|
||||
if (unlikely(inited == 0)) {
|
||||
return SYSCALL(write)(sockfd, buf, count);
|
||||
if(is_fstack_fd(sockfd)){
|
||||
sockfd = restore_fstack_fd(sockfd);
|
||||
return ff_write(sockfd, buf, count);
|
||||
}
|
||||
|
||||
if (ff_fdisused(sockfd)) {
|
||||
return ff_write(sockfd, buf, count);
|
||||
} else {
|
||||
return SYSCALL(write)(sockfd, buf, count);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ioctl(int sockfd, int request, void *p)
|
||||
{
|
||||
if (unlikely(inited == 0)) {
|
||||
return SYSCALL(ioctl)(sockfd, request, p);
|
||||
if(is_fstack_fd(sockfd)){
|
||||
sockfd = restore_fstack_fd(sockfd);
|
||||
return ff_ioctl(sockfd, request, p);
|
||||
}
|
||||
|
||||
if (ff_fdisused(sockfd)) {
|
||||
return ff_ioctl(sockfd, request, p);
|
||||
} else {
|
||||
return SYSCALL(ioctl)(sockfd, request, p);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
kqueue(void)
|
||||
|
@ -429,6 +448,26 @@ int
|
|||
kevent(int kq, const struct kevent *changelist, int nchanges,
|
||||
struct kevent *eventlist, int nevents, const struct timespec *timeout)
|
||||
{
|
||||
struct kevent *kev;
|
||||
int i = 0;
|
||||
for(i = 0; i < nchanges; i++) {
|
||||
kev = (struct kevent *)&changelist[i];
|
||||
switch (kev->filter) {
|
||||
|
||||
case EVFILT_READ:
|
||||
case EVFILT_WRITE:
|
||||
case EVFILT_VNODE:
|
||||
kev->ident = restore_fstack_fd(kev->ident);
|
||||
break;
|
||||
case EVFILT_AIO:
|
||||
case EVFILT_PROC:
|
||||
case EVFILT_SIGNAL:
|
||||
case EVFILT_TIMER:
|
||||
case EVFILT_USER:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ff_kevent(kq, changelist, nchanges, eventlist, nevents, timeout);
|
||||
}
|
||||
|
||||
|
@ -441,4 +480,3 @@ gettimeofday(struct timeval *tv, struct timezone *tz)
|
|||
|
||||
return ff_gettimeofday(tv, tz);
|
||||
}
|
||||
|
||||
|
|
|
@ -564,6 +564,11 @@ ngx_timer_signal_handler(int signo)
|
|||
|
||||
#endif
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
|
||||
extern ngx_event_actions_t ngx_ff_host_event_actions;
|
||||
|
||||
#endif
|
||||
|
||||
static ngx_int_t
|
||||
ngx_event_process_init(ngx_cycle_t *cycle)
|
||||
|
@ -602,6 +607,11 @@ ngx_event_process_init(ngx_cycle_t *cycle)
|
|||
ngx_queue_init(&ngx_posted_accept_events);
|
||||
ngx_queue_init(&ngx_posted_events);
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
ngx_queue_init(&ngx_posted_accept_events_of_host);
|
||||
ngx_queue_init(&ngx_posted_events_of_host);
|
||||
#endif
|
||||
|
||||
if (ngx_event_timer_init(cycle->log) == NGX_ERROR) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
@ -625,6 +635,13 @@ ngx_event_process_init(ngx_cycle_t *cycle)
|
|||
break;
|
||||
}
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
if (ngx_ff_host_event_actions.init(cycle, ngx_timer_resolution) != NGX_OK) {
|
||||
/* fatal */
|
||||
exit(2);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !(NGX_WIN32)
|
||||
|
||||
if (ngx_timer_resolution && !(ngx_event_flags & NGX_USE_TIMER_EVENT)) {
|
||||
|
@ -663,8 +680,14 @@ ngx_event_process_init(ngx_cycle_t *cycle)
|
|||
|
||||
cycle->files_n = (ngx_uint_t) rlmt.rlim_cur;
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
cycle->files = ngx_calloc(sizeof(ngx_connection_t *) * cycle->files_n * 2,
|
||||
cycle->log);
|
||||
#else
|
||||
cycle->files = ngx_calloc(sizeof(ngx_connection_t *) * cycle->files_n,
|
||||
cycle->log);
|
||||
#endif
|
||||
|
||||
if (cycle->files == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
@ -757,6 +780,12 @@ ngx_event_process_init(ngx_cycle_t *cycle)
|
|||
rev->log = c->log;
|
||||
rev->accept = 1;
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
/* Note when nginx running on fstack,
|
||||
make sure that add the right fd to kqueue !! */
|
||||
c->read->belong_to_host = c->write->belong_to_host = ls[i].belong_to_host;
|
||||
#endif
|
||||
|
||||
#if (NGX_HAVE_DEFERRED_ACCEPT)
|
||||
rev->deferred_accept = ls[i].deferred_accept;
|
||||
#endif
|
||||
|
|
|
@ -142,6 +142,10 @@ struct ngx_event_s {
|
|||
uint32_t padding[NGX_EVENT_T_PADDING];
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
unsigned belong_to_host:1;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
@ -198,7 +202,9 @@ extern ngx_event_actions_t ngx_event_actions;
|
|||
#if (NGX_HAVE_EPOLLRDHUP)
|
||||
extern ngx_uint_t ngx_use_epoll_rdhup;
|
||||
#endif
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
extern ngx_event_actions_t ngx_ff_host_event_actions;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The event filter requires to read/write the whole data:
|
||||
|
@ -407,6 +413,47 @@ extern ngx_uint_t ngx_use_epoll_rdhup;
|
|||
#define NGX_CLEAR_EVENT 0 /* dummy declaration */
|
||||
#endif
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
|
||||
static inline ngx_int_t
|
||||
ngx_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags) {
|
||||
if (1 == ev->belong_to_host) {
|
||||
return ngx_ff_host_event_actions.add(ev, event, flags);
|
||||
} else {
|
||||
return ngx_event_actions.add(ev, event, flags);
|
||||
}
|
||||
}
|
||||
|
||||
static inline ngx_int_t
|
||||
ngx_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags) {
|
||||
if (1 == ev->belong_to_host) {
|
||||
return ngx_ff_host_event_actions.del(ev, event, flags);
|
||||
} else {
|
||||
return ngx_event_actions.del(ev, event, flags);
|
||||
}
|
||||
}
|
||||
|
||||
static inline ngx_int_t ngx_add_conn(ngx_connection_t *c)
|
||||
{
|
||||
return ngx_event_actions.add_conn(c);
|
||||
}
|
||||
|
||||
static inline ngx_int_t ngx_del_conn(
|
||||
ngx_connection_t *c, ngx_uint_t flags) {
|
||||
return ngx_event_actions.del_conn(c, flags);
|
||||
}
|
||||
|
||||
static inline ngx_int_t ngx_notify(ngx_event_handler_pt handler) {
|
||||
return ngx_event_actions.notify(handler);
|
||||
}
|
||||
|
||||
static inline ngx_int_t ngx_process_events(
|
||||
ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
|
||||
{
|
||||
return ngx_event_actions.process_events(cycle, timer, flags);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define ngx_process_events ngx_event_actions.process_events
|
||||
#define ngx_done_events ngx_event_actions.done
|
||||
|
@ -418,6 +465,8 @@ extern ngx_uint_t ngx_use_epoll_rdhup;
|
|||
|
||||
#define ngx_notify ngx_event_actions.notify
|
||||
|
||||
#endif
|
||||
|
||||
#define ngx_add_timer ngx_event_add_timer
|
||||
#define ngx_del_timer ngx_event_del_timer
|
||||
|
||||
|
|
|
@ -230,6 +230,10 @@ ngx_event_accept(ngx_event_t *ev)
|
|||
rev = c->read;
|
||||
wev = c->write;
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
rev->belong_to_host = wev->belong_to_host = ev->belong_to_host;
|
||||
#endif
|
||||
|
||||
wev->ready = 1;
|
||||
|
||||
if (ngx_event_flags & NGX_USE_IOCP_EVENT) {
|
||||
|
@ -296,7 +300,11 @@ ngx_event_accept(ngx_event_t *ev)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
if (ngx_event_actions.add_conn && (ngx_event_flags & NGX_USE_EPOLL_EVENT) == 0) {
|
||||
#else
|
||||
if (ngx_add_conn && (ngx_event_flags & NGX_USE_EPOLL_EVENT) == 0) {
|
||||
#endif
|
||||
if (ngx_add_conn(c) == NGX_ERROR) {
|
||||
ngx_close_accepted_connection(c);
|
||||
return;
|
||||
|
@ -432,6 +440,7 @@ ngx_event_recvmsg(ngx_event_t *ev)
|
|||
- ngx_cycle->free_connection_n;
|
||||
|
||||
c = ngx_get_connection(lc->fd, ev->log);
|
||||
|
||||
if (c == NULL) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -181,7 +181,11 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc)
|
|||
|
||||
c->number = ngx_atomic_fetch_add(ngx_connection_counter, 1);
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
if (ngx_event_actions.add_conn) {
|
||||
#else
|
||||
if (ngx_add_conn) {
|
||||
#endif
|
||||
if (ngx_add_conn(c) == NGX_ERROR) {
|
||||
goto failed;
|
||||
}
|
||||
|
@ -233,7 +237,11 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc)
|
|||
}
|
||||
}
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
if (ngx_event_actions.add_conn) {
|
||||
#else
|
||||
if (ngx_add_conn) {
|
||||
#endif
|
||||
if (rc == -1) {
|
||||
|
||||
/* NGX_EINPROGRESS */
|
||||
|
|
|
@ -13,6 +13,11 @@
|
|||
ngx_queue_t ngx_posted_accept_events;
|
||||
ngx_queue_t ngx_posted_events;
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
ngx_queue_t ngx_posted_accept_events_of_host;
|
||||
ngx_queue_t ngx_posted_events_of_host;
|
||||
#endif
|
||||
|
||||
|
||||
void
|
||||
ngx_event_process_posted(ngx_cycle_t *cycle, ngx_queue_t *posted)
|
||||
|
|
|
@ -14,6 +14,34 @@
|
|||
#include <ngx_event.h>
|
||||
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
#define ngx_post_event(ev, q) \
|
||||
\
|
||||
if (!(ev)->posted) { \
|
||||
(ev)->posted = 1; \
|
||||
if (1 == (ev)->belong_to_host) { \
|
||||
if (q == &ngx_posted_events) { \
|
||||
ngx_queue_insert_tail( \
|
||||
&ngx_posted_events_of_host, &(ev)->queue); \
|
||||
} else if (q == &ngx_posted_accept_events) { \
|
||||
ngx_queue_insert_tail( \
|
||||
&ngx_posted_accept_events_of_host, &(ev)->queue); \
|
||||
} else { \
|
||||
ngx_log_error(NGX_LOG_EMERG, (ev)->log, 0, \
|
||||
"ngx_post_event: unkowned posted queue"); \
|
||||
exit(1); \
|
||||
} \
|
||||
} else { \
|
||||
ngx_queue_insert_tail(q, &(ev)->queue); \
|
||||
} \
|
||||
\
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_CORE, (ev)->log, 0, "post event %p", ev);\
|
||||
\
|
||||
} else { \
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_CORE, (ev)->log, 0, \
|
||||
"update posted event %p", ev); \
|
||||
}
|
||||
#else
|
||||
#define ngx_post_event(ev, q) \
|
||||
\
|
||||
if (!(ev)->posted) { \
|
||||
|
@ -26,6 +54,7 @@
|
|||
ngx_log_debug1(NGX_LOG_DEBUG_CORE, (ev)->log, 0, \
|
||||
"update posted event %p", ev); \
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#define ngx_delete_posted_event(ev) \
|
||||
|
@ -44,5 +73,9 @@ void ngx_event_process_posted(ngx_cycle_t *cycle, ngx_queue_t *posted);
|
|||
extern ngx_queue_t ngx_posted_accept_events;
|
||||
extern ngx_queue_t ngx_posted_events;
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
extern ngx_queue_t ngx_posted_accept_events_of_host;
|
||||
extern ngx_queue_t ngx_posted_events_of_host;
|
||||
#endif
|
||||
|
||||
#endif /* _NGX_EVENT_POSTED_H_INCLUDED_ */
|
||||
|
|
|
@ -13,6 +13,11 @@
|
|||
ngx_rbtree_t ngx_event_timer_rbtree;
|
||||
static ngx_rbtree_node_t ngx_event_timer_sentinel;
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
ngx_rbtree_t ngx_event_timer_rbtree_of_host;
|
||||
static ngx_rbtree_node_t ngx_event_timer_sentinel_of_host;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* the event timer rbtree may contain the duplicate keys, however,
|
||||
* it should not be a problem, because we use the rbtree to find
|
||||
|
@ -25,22 +30,54 @@ ngx_event_timer_init(ngx_log_t *log)
|
|||
ngx_rbtree_init(&ngx_event_timer_rbtree, &ngx_event_timer_sentinel,
|
||||
ngx_rbtree_insert_timer_value);
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
|
||||
ngx_rbtree_init(&ngx_event_timer_rbtree_of_host, &ngx_event_timer_sentinel_of_host,
|
||||
ngx_rbtree_insert_timer_value);
|
||||
|
||||
#endif
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
|
||||
ngx_msec_t
|
||||
ngx_event_find_timer_internal(
|
||||
ngx_rbtree_t *rbtree, ngx_rbtree_node_t *sentinel);
|
||||
ngx_msec_t
|
||||
ngx_event_find_timer(void)
|
||||
{
|
||||
return ngx_event_find_timer_internal(&ngx_event_timer_rbtree, &ngx_event_timer_sentinel);
|
||||
}
|
||||
|
||||
ngx_msec_t
|
||||
ngx_event_find_timer_of_host(void)
|
||||
{
|
||||
return ngx_event_find_timer_internal(&ngx_event_timer_rbtree_of_host, &ngx_event_timer_sentinel_of_host);
|
||||
}
|
||||
|
||||
ngx_msec_t
|
||||
ngx_event_find_timer_internal(
|
||||
ngx_rbtree_t *rbtree, ngx_rbtree_node_t *rbtree_sentinel)
|
||||
{
|
||||
#else
|
||||
ngx_msec_t
|
||||
ngx_event_find_timer(void)
|
||||
{
|
||||
ngx_rbtree_t * rbtree = &ngx_event_timer_rbtree;
|
||||
ngx_rbtree_node_t *rbtree_sentinel = &ngx_event_timer_sentinel;
|
||||
#endif
|
||||
ngx_msec_int_t timer;
|
||||
ngx_rbtree_node_t *node, *root, *sentinel;
|
||||
|
||||
if (ngx_event_timer_rbtree.root == &ngx_event_timer_sentinel) {
|
||||
if (rbtree->root == rbtree_sentinel) {
|
||||
return NGX_TIMER_INFINITE;
|
||||
}
|
||||
|
||||
root = ngx_event_timer_rbtree.root;
|
||||
sentinel = ngx_event_timer_rbtree.sentinel;
|
||||
root = rbtree->root;
|
||||
sentinel = rbtree->sentinel;
|
||||
|
||||
node = ngx_rbtree_min(root, sentinel);
|
||||
|
||||
|
@ -50,16 +87,39 @@ ngx_event_find_timer(void)
|
|||
}
|
||||
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
|
||||
void
|
||||
ngx_event_expire_timers_internal(ngx_rbtree_t *rbtree);
|
||||
|
||||
void
|
||||
ngx_event_expire_timers(void)
|
||||
{
|
||||
ngx_event_expire_timers_internal(&ngx_event_timer_rbtree);
|
||||
}
|
||||
|
||||
void
|
||||
ngx_event_expire_timers_of_host(void)
|
||||
{
|
||||
ngx_event_expire_timers_internal(&ngx_event_timer_rbtree_of_host);
|
||||
}
|
||||
|
||||
void
|
||||
ngx_event_expire_timers_internal(ngx_rbtree_t *rbtree)
|
||||
{
|
||||
#else
|
||||
void
|
||||
ngx_event_expire_timers(void)
|
||||
{
|
||||
ngx_rbtree_t * rbtree = &ngx_event_timer_rbtree;
|
||||
#endif
|
||||
ngx_event_t *ev;
|
||||
ngx_rbtree_node_t *node, *root, *sentinel;
|
||||
|
||||
sentinel = ngx_event_timer_rbtree.sentinel;
|
||||
sentinel = rbtree->sentinel;
|
||||
|
||||
for ( ;; ) {
|
||||
root = ngx_event_timer_rbtree.root;
|
||||
root = rbtree->root;
|
||||
|
||||
if (root == sentinel) {
|
||||
return;
|
||||
|
@ -79,7 +139,7 @@ ngx_event_expire_timers(void)
|
|||
"event timer del: %d: %M",
|
||||
ngx_event_ident(ev->data), ev->timer.key);
|
||||
|
||||
ngx_rbtree_delete(&ngx_event_timer_rbtree, &ev->timer);
|
||||
ngx_rbtree_delete(rbtree, &ev->timer);
|
||||
|
||||
#if (NGX_DEBUG)
|
||||
ev->timer.left = NULL;
|
||||
|
@ -96,16 +156,39 @@ ngx_event_expire_timers(void)
|
|||
}
|
||||
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
|
||||
void
|
||||
ngx_event_cancel_timers_internal(ngx_rbtree_t *rbtree);
|
||||
|
||||
void
|
||||
ngx_event_cancel_timers(void)
|
||||
{
|
||||
ngx_event_cancel_timers_internal(&ngx_event_timer_rbtree);
|
||||
}
|
||||
|
||||
void
|
||||
ngx_event_cancel_timers_of_host(void)
|
||||
{
|
||||
ngx_event_cancel_timers_internal(&ngx_event_timer_rbtree_of_host);
|
||||
}
|
||||
|
||||
void
|
||||
ngx_event_cancel_timers_internal(ngx_rbtree_t *rbtree)
|
||||
{
|
||||
#else
|
||||
void
|
||||
ngx_event_cancel_timers(void)
|
||||
{
|
||||
ngx_rbtree_t * rbtree = &ngx_event_timer_rbtree;
|
||||
#endif
|
||||
ngx_event_t *ev;
|
||||
ngx_rbtree_node_t *node, *root, *sentinel;
|
||||
|
||||
sentinel = ngx_event_timer_rbtree.sentinel;
|
||||
sentinel = rbtree->sentinel;
|
||||
|
||||
for ( ;; ) {
|
||||
root = ngx_event_timer_rbtree.root;
|
||||
root = rbtree->root;
|
||||
|
||||
if (root == sentinel) {
|
||||
return;
|
||||
|
@ -123,7 +206,7 @@ ngx_event_cancel_timers(void)
|
|||
"event timer cancel: %d: %M",
|
||||
ngx_event_ident(ev->data), ev->timer.key);
|
||||
|
||||
ngx_rbtree_delete(&ngx_event_timer_rbtree, &ev->timer);
|
||||
ngx_rbtree_delete(rbtree, &ev->timer);
|
||||
|
||||
#if (NGX_DEBUG)
|
||||
ev->timer.left = NULL;
|
||||
|
|
|
@ -27,6 +27,9 @@ void ngx_event_cancel_timers(void);
|
|||
|
||||
extern ngx_rbtree_t ngx_event_timer_rbtree;
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
extern ngx_rbtree_t ngx_event_timer_rbtree_of_host;
|
||||
#endif
|
||||
|
||||
static ngx_inline void
|
||||
ngx_event_del_timer(ngx_event_t *ev)
|
||||
|
@ -35,7 +38,19 @@ ngx_event_del_timer(ngx_event_t *ev)
|
|||
"event timer del: %d: %M",
|
||||
ngx_event_ident(ev->data), ev->timer.key);
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
|
||||
if(ev->belong_to_host){
|
||||
ngx_rbtree_delete(&ngx_event_timer_rbtree_of_host, &ev->timer);
|
||||
} else {
|
||||
ngx_rbtree_delete(&ngx_event_timer_rbtree, &ev->timer);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
ngx_rbtree_delete(&ngx_event_timer_rbtree, &ev->timer);
|
||||
|
||||
#endif
|
||||
|
||||
#if (NGX_DEBUG)
|
||||
ev->timer.left = NULL;
|
||||
|
@ -81,7 +96,19 @@ ngx_event_add_timer(ngx_event_t *ev, ngx_msec_t timer)
|
|||
"event timer add: %d: %M:%M",
|
||||
ngx_event_ident(ev->data), timer, ev->timer.key);
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
|
||||
if(ev->belong_to_host){
|
||||
ngx_rbtree_insert(&ngx_event_timer_rbtree_of_host, &ev->timer);
|
||||
} else {
|
||||
ngx_rbtree_insert(&ngx_event_timer_rbtree, &ev->timer);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
ngx_rbtree_insert(&ngx_event_timer_rbtree, &ev->timer);
|
||||
|
||||
#endif
|
||||
|
||||
ev->timer_set = 1;
|
||||
}
|
||||
|
|
|
@ -1775,6 +1775,10 @@ ngx_http_add_listening(ngx_conf_t *cf, ngx_http_conf_addr_t *addr)
|
|||
ls->reuseport = addr->opt.reuseport;
|
||||
#endif
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
ls->belong_to_host = cscf->kernel_network_stack;
|
||||
#endif
|
||||
|
||||
return ls;
|
||||
}
|
||||
|
||||
|
|
|
@ -293,6 +293,17 @@ static ngx_command_t ngx_http_core_commands[] = {
|
|||
0,
|
||||
NULL },
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
|
||||
{ ngx_string("kernel_network_stack"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
|
||||
ngx_conf_set_flag_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_http_core_srv_conf_t, kernel_network_stack),
|
||||
NULL },
|
||||
|
||||
#endif
|
||||
|
||||
{ ngx_string("types_hash_max_size"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_num_slot,
|
||||
|
@ -3444,6 +3455,7 @@ ngx_http_core_create_srv_conf(ngx_conf_t *cf)
|
|||
cscf->ignore_invalid_headers = NGX_CONF_UNSET;
|
||||
cscf->merge_slashes = NGX_CONF_UNSET;
|
||||
cscf->underscores_in_headers = NGX_CONF_UNSET;
|
||||
cscf->kernel_network_stack = NGX_CONF_UNSET;
|
||||
|
||||
return cscf;
|
||||
}
|
||||
|
@ -3487,6 +3499,12 @@ ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
ngx_conf_merge_value(conf->underscores_in_headers,
|
||||
prev->underscores_in_headers, 0);
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
/* By default, we set up a server on fstack */
|
||||
ngx_conf_merge_value(conf->kernel_network_stack,
|
||||
prev->kernel_network_stack, 0);
|
||||
#endif
|
||||
|
||||
if (conf->server_names.nelts == 0) {
|
||||
/* the array has 4 empty preallocated elements, so push cannot fail */
|
||||
sn = ngx_array_push(&conf->server_names);
|
||||
|
|
|
@ -199,6 +199,10 @@ typedef struct {
|
|||
ngx_flag_t merge_slashes;
|
||||
ngx_flag_t underscores_in_headers;
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
ngx_flag_t kernel_network_stack; /* kernel_network_stack */
|
||||
#endif
|
||||
|
||||
unsigned listen:1;
|
||||
#if (NGX_PCRE)
|
||||
unsigned captures:1;
|
||||
|
|
|
@ -345,6 +345,10 @@ ngx_mail_optimize_servers(ngx_conf_t *cf, ngx_array_t *ports)
|
|||
ls->ipv6only = addr[i].opt.ipv6only;
|
||||
#endif
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
ls->belong_to_host = cscf->kernel_network_stack;
|
||||
#endif
|
||||
|
||||
mport = ngx_palloc(cf->pool, sizeof(ngx_mail_port_t));
|
||||
if (mport == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
|
|
|
@ -112,6 +112,10 @@ typedef struct {
|
|||
|
||||
ngx_str_t server_name;
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
ngx_flag_t kernel_network_stack; /* kernel_network_stack */
|
||||
#endif
|
||||
|
||||
u_char *file_name;
|
||||
ngx_uint_t line;
|
||||
|
||||
|
|
|
@ -64,6 +64,17 @@ static ngx_command_t ngx_mail_core_commands[] = {
|
|||
offsetof(ngx_mail_core_srv_conf_t, server_name),
|
||||
NULL },
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
|
||||
{ ngx_string("kernel_network_stack"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
|
||||
ngx_conf_set_flag_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_http_core_srv_conf_t, kernel_network_stack),
|
||||
NULL },
|
||||
|
||||
#endif
|
||||
|
||||
{ ngx_string("error_log"),
|
||||
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_1MORE,
|
||||
ngx_mail_core_error_log,
|
||||
|
@ -167,6 +178,9 @@ ngx_mail_core_create_srv_conf(ngx_conf_t *cf)
|
|||
|
||||
cscf->file_name = cf->conf_file->file.name.data;
|
||||
cscf->line = cf->conf_file->line;
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
cscf->kernel_network_stack = NGX_CONF_UNSET;
|
||||
#endif
|
||||
|
||||
return cscf;
|
||||
}
|
||||
|
@ -206,6 +220,12 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
|
||||
ngx_conf_merge_ptr_value(conf->resolver, prev->resolver, NULL);
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
/* By default, we set up a server on fstack */
|
||||
ngx_conf_merge_value(conf->kernel_network_stack,
|
||||
prev->kernel_network_stack, 0);
|
||||
#endif
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -223,7 +223,11 @@ ngx_add_channel_event(ngx_cycle_t *cycle, ngx_fd_t fd, ngx_int_t event,
|
|||
|
||||
ev->handler = handler;
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
if (ngx_event_actions.add_conn && (ngx_event_flags & NGX_USE_EPOLL_EVENT) == 0) {
|
||||
#else
|
||||
if (ngx_add_conn && (ngx_event_flags & NGX_USE_EPOLL_EVENT) == 0) {
|
||||
#endif
|
||||
if (ngx_add_conn(c) == NGX_ERROR) {
|
||||
ngx_free_connection(c);
|
||||
return NGX_ERROR;
|
||||
|
|
|
@ -737,9 +737,7 @@ ngx_master_process_exit(ngx_cycle_t *cycle)
|
|||
}
|
||||
}
|
||||
|
||||
#if (!NGX_HAVE_FSTACK)
|
||||
ngx_close_listening_sockets(cycle);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Copy ngx_cycle->log related data to the special static exit cycle,
|
||||
|
|
|
@ -512,6 +512,10 @@ ngx_stream_optimize_servers(ngx_conf_t *cf, ngx_array_t *ports)
|
|||
ls->reuseport = addr[i].opt.reuseport;
|
||||
#endif
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
ls->belong_to_host = cscf->kernel_network_stack;
|
||||
#endif
|
||||
|
||||
stport = ngx_palloc(cf->pool, sizeof(ngx_stream_port_t));
|
||||
if (stport == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
|
|
|
@ -185,6 +185,10 @@ typedef struct {
|
|||
|
||||
ngx_msec_t proxy_protocol_timeout;
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
ngx_flag_t kernel_network_stack; /* kernel_network_stack */
|
||||
#endif
|
||||
|
||||
ngx_uint_t listen; /* unsigned listen:1; */
|
||||
} ngx_stream_core_srv_conf_t;
|
||||
|
||||
|
|
|
@ -56,6 +56,17 @@ static ngx_command_t ngx_stream_core_commands[] = {
|
|||
0,
|
||||
NULL },
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
|
||||
{ ngx_string("kernel_network_stack"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
|
||||
ngx_conf_set_flag_slot,
|
||||
NGX_HTTP_SRV_CONF_OFFSET,
|
||||
offsetof(ngx_http_core_srv_conf_t, kernel_network_stack),
|
||||
NULL },
|
||||
|
||||
#endif
|
||||
|
||||
{ ngx_string("error_log"),
|
||||
NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_1MORE,
|
||||
ngx_stream_core_error_log,
|
||||
|
@ -425,6 +436,9 @@ ngx_stream_core_create_srv_conf(ngx_conf_t *cf)
|
|||
cscf->tcp_nodelay = NGX_CONF_UNSET;
|
||||
cscf->preread_buffer_size = NGX_CONF_UNSET_SIZE;
|
||||
cscf->preread_timeout = NGX_CONF_UNSET_MSEC;
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
cscf->kernel_network_stack = NGX_CONF_UNSET;
|
||||
#endif
|
||||
|
||||
return cscf;
|
||||
}
|
||||
|
@ -483,6 +497,12 @@ ngx_stream_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
ngx_conf_merge_msec_value(conf->preread_timeout,
|
||||
prev->preread_timeout, 30000);
|
||||
|
||||
#if (NGX_HAVE_FSTACK)
|
||||
/* By default, we set up a server on fstack */
|
||||
ngx_conf_merge_value(conf->kernel_network_stack,
|
||||
prev->kernel_network_stack, 0);
|
||||
#endif
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -4134,5 +4134,13 @@ ff_fdused_range(int max)
|
|||
fdalloc(td, 0, &result);
|
||||
}
|
||||
|
||||
int
|
||||
ff_getmaxfd(void)
|
||||
{
|
||||
struct thread *td = curthread;
|
||||
return getmaxfd(td);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -117,6 +117,7 @@ int ff_gettimeofday(struct timeval *tv, struct timezone *tz);
|
|||
/* Tests if fd is used by F-Stack */
|
||||
extern int ff_fdisused(int fd);
|
||||
|
||||
extern int ff_getmaxfd(void);
|
||||
|
||||
/* route api begin */
|
||||
enum FF_ROUTE_CTL {
|
||||
|
|
|
@ -43,4 +43,5 @@ ff_route_ctl
|
|||
ff_rtioctl
|
||||
ff_gettimeofday
|
||||
ff_fdisused
|
||||
ff_getmaxfd
|
||||
ff_ngctl
|
||||
|
|
|
@ -32,5 +32,6 @@
|
|||
|
||||
void ff_fdused_range(int max);
|
||||
int ff_fdisused(int fd);
|
||||
int ff_getmaxfd(void);
|
||||
|
||||
#endif /* _FSTACK_SYS_FILEDESC_H_ */
|
||||
|
|
Loading…
Reference in New Issue