stream: use kevent() information before accept()
Limit number of syscalls by using backlog length information provided by kevent().
This commit is contained in:
parent
da33bba7c0
commit
c15d4a7c62
@ -25,4 +25,10 @@
|
||||
#define UV_PLATFORM_FS_EVENT_FIELDS \
|
||||
uv__io_t event_watcher; \
|
||||
|
||||
#define UV_IO_PRIVATE_PLATFORM_FIELDS \
|
||||
int rcount; \
|
||||
int wcount; \
|
||||
|
||||
#define UV_HAVE_KQUEUE 1
|
||||
|
||||
#endif /* UV_BSD_H */
|
||||
|
||||
@ -30,6 +30,10 @@
|
||||
# define UV_PLATFORM_SEM_T semaphore_t
|
||||
#endif
|
||||
|
||||
#define UV_IO_PRIVATE_PLATFORM_FIELDS \
|
||||
int rcount; \
|
||||
int wcount; \
|
||||
|
||||
#define UV_PLATFORM_LOOP_FIELDS \
|
||||
uv_thread_t cf_thread; \
|
||||
void* cf_cb; \
|
||||
@ -52,4 +56,6 @@
|
||||
#define UV_STREAM_PRIVATE_PLATFORM_FIELDS \
|
||||
void* select; \
|
||||
|
||||
#define UV_HAVE_KQUEUE 1
|
||||
|
||||
#endif /* UV_DARWIN_H */
|
||||
|
||||
@ -41,9 +41,29 @@
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
|
||||
#if defined(__linux__)
|
||||
# include "uv-linux.h"
|
||||
#elif defined(__sun)
|
||||
# include "uv-sunos.h"
|
||||
#elif defined(__APPLE__)
|
||||
# include "uv-darwin.h"
|
||||
#elif defined(__DragonFly__) || \
|
||||
defined(__FreeBSD__) || \
|
||||
defined(__OpenBSD__) || \
|
||||
defined(__NetBSD__)
|
||||
# include "uv-bsd.h"
|
||||
#endif
|
||||
|
||||
struct uv__io_s;
|
||||
struct uv_loop_s;
|
||||
|
||||
#ifndef UV_IO_PRIVATE_PLATFORM_FIELDS
|
||||
# define UV_IO_PRIVATE_PLATFORM_FIELDS /* empty */
|
||||
#endif
|
||||
|
||||
#define UV_IO_PRIVATE_FIELDS \
|
||||
UV_IO_PRIVATE_PLATFORM_FIELDS \
|
||||
|
||||
typedef void (*uv__io_cb)(struct uv_loop_s* loop,
|
||||
struct uv__io_s* w,
|
||||
unsigned int events);
|
||||
@ -56,6 +76,7 @@ struct uv__io_s {
|
||||
unsigned int pevents; /* Pending event mask i.e. mask at next tick. */
|
||||
unsigned int events; /* Current event mask. */
|
||||
int fd;
|
||||
UV_IO_PRIVATE_FIELDS
|
||||
};
|
||||
|
||||
struct uv__work {
|
||||
@ -65,19 +86,6 @@ struct uv__work {
|
||||
ngx_queue_t wq;
|
||||
};
|
||||
|
||||
#if defined(__linux__)
|
||||
# include "uv-linux.h"
|
||||
#elif defined(__sun)
|
||||
# include "uv-sunos.h"
|
||||
#elif defined(__APPLE__)
|
||||
# include "uv-darwin.h"
|
||||
#elif defined(__DragonFly__) || \
|
||||
defined(__FreeBSD__) || \
|
||||
defined(__OpenBSD__) || \
|
||||
defined(__NetBSD__)
|
||||
# include "uv-bsd.h"
|
||||
#endif
|
||||
|
||||
#ifndef UV_PLATFORM_SEM_T
|
||||
# define UV_PLATFORM_SEM_T sem_t
|
||||
#endif
|
||||
|
||||
@ -595,6 +595,11 @@ void uv__io_init(uv__io_t* w, uv__io_cb cb, int fd) {
|
||||
w->fd = fd;
|
||||
w->events = 0;
|
||||
w->pevents = 0;
|
||||
|
||||
#if defined(UV_HAVE_KQUEUE)
|
||||
w->rcount = 0;
|
||||
w->wcount = 0;
|
||||
#endif /* defined(UV_HAVE_KQUEUE) */
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -197,9 +197,10 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
revents = 0;
|
||||
|
||||
if (ev->filter == EVFILT_READ) {
|
||||
if (w->events & UV__POLLIN)
|
||||
if (w->events & UV__POLLIN) {
|
||||
revents |= UV__POLLIN;
|
||||
else {
|
||||
w->rcount = ev->data;
|
||||
} else {
|
||||
/* TODO batch up */
|
||||
struct kevent events[1];
|
||||
EV_SET(events + 0, fd, ev->filter, EV_DELETE, 0, 0, 0);
|
||||
@ -210,9 +211,10 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
}
|
||||
|
||||
if (ev->filter == EVFILT_WRITE) {
|
||||
if (w->events & UV__POLLOUT)
|
||||
if (w->events & UV__POLLOUT) {
|
||||
revents |= UV__POLLOUT;
|
||||
else {
|
||||
w->wcount = ev->data;
|
||||
} else {
|
||||
/* TODO batch up */
|
||||
struct kevent events[1];
|
||||
EV_SET(events + 0, fd, ev->filter, EV_DELETE, 0, 0, 0);
|
||||
|
||||
@ -484,6 +484,13 @@ static int uv__emfile_trick(uv_loop_t* loop, int accept_fd) {
|
||||
}
|
||||
|
||||
|
||||
#if defined(UV_HAVE_KQUEUE)
|
||||
# define UV_DEC_BACKLOG(w) w->rcount--;
|
||||
#else
|
||||
# define UV_DEC_BACKLOG(w) /* no-op */
|
||||
#endif /* defined(UV_HAVE_KQUEUE) */
|
||||
|
||||
|
||||
void uv__server_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
||||
static int use_emfile_trick = -1;
|
||||
uv_stream_t* stream;
|
||||
@ -503,6 +510,10 @@ void uv__server_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
||||
*/
|
||||
while (uv__stream_fd(stream) != -1) {
|
||||
assert(stream->accepted_fd == -1);
|
||||
#if defined(UV_HAVE_KQUEUE)
|
||||
if (w->rcount <= 0)
|
||||
return;
|
||||
#endif /* defined(UV_HAVE_KQUEUE) */
|
||||
fd = uv__accept(uv__stream_fd(stream));
|
||||
|
||||
if (fd == -1) {
|
||||
@ -514,6 +525,7 @@ void uv__server_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
||||
return; /* Not an error. */
|
||||
|
||||
case ECONNABORTED:
|
||||
UV_DEC_BACKLOG(w)
|
||||
continue; /* Ignore. */
|
||||
|
||||
case EMFILE:
|
||||
@ -525,8 +537,10 @@ void uv__server_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
||||
|
||||
if (use_emfile_trick) {
|
||||
SAVE_ERRNO(r = uv__emfile_trick(loop, uv__stream_fd(stream)));
|
||||
if (r == 0)
|
||||
if (r == 0) {
|
||||
UV_DEC_BACKLOG(w)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fall through. */
|
||||
@ -538,6 +552,8 @@ void uv__server_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
||||
}
|
||||
}
|
||||
|
||||
UV_DEC_BACKLOG(w)
|
||||
|
||||
stream->accepted_fd = fd;
|
||||
stream->connection_cb(stream, 0);
|
||||
|
||||
@ -556,6 +572,9 @@ void uv__server_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
||||
}
|
||||
|
||||
|
||||
#undef UV_DEC_BACKLOG
|
||||
|
||||
|
||||
int uv_accept(uv_stream_t* server, uv_stream_t* client) {
|
||||
uv_stream_t* streamServer;
|
||||
uv_stream_t* streamClient;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user