Merge branch 'v0.10' into v1.x

Conflicts:
	AUTHORS
	ChangeLog
	README.md
	config-unix.mk
	include/uv.h
	src/unix/internal.h
	src/unix/kqueue.c
	src/unix/linux-core.c
	src/unix/stream.c
	src/uv-common.c
	src/uv-common.h
	src/version.c
	test/test-osx-select.c
This commit is contained in:
Ben Noordhuis 2014-12-05 19:18:36 +01:00
commit a6f2a4f834
12 changed files with 133 additions and 16 deletions

View File

@ -85,6 +85,17 @@ Changes since version 1.0.0-rc1:
* windows: fix fs_write with nbufs > 1 and offset (Unknown W. Brackets)
2014.10.21, Version 0.10.29 (Stable), 2d728542d3790183417f8f122a110693cd85db14
Changes since version 0.10.28:
* darwin: allocate enough space for select() hack (Fedor Indutny)
* linux: try epoll_pwait if epoll_wait is missing (Michael Hudson-Doyle)
* windows: map ERROR_INVALID_DRIVE to UV_ENOENT (Saúl Ibarra Corretgé)
2014.09.18, Version 1.0.0-rc1 (Unstable), 0c28bbf7b42882853d1799ab96ff68b07f7f8d49
Changes since version 0.11.29:
@ -273,6 +284,20 @@ Changes since version 0.11.26:
* windows: relay TCP bind errors via ipc (Alexis Campailla)
2014.07.32, Version 0.10.28 (Stable), 9c14b616f5fb84bfd7d45707bab4bbb85894443e
Changes since version 0.10.27:
* windows: fix handling closed socket while poll handle is closing (Saúl Ibarra
Corretgé)
* unix: return system error on EAI_SYSTEM (Saúl Ibarra Corretgé)
* unix: fix bogus structure field name (Saúl Ibarra Corretgé)
* darwin: invoke `mach_timebase_info` only once (Fedor Indutny)
2014.06.28, Version 0.11.26 (Unstable), 115281a1058c4034d5c5ccedacb667fe3f6327ea
Changes since version 0.11.25:

View File

@ -229,6 +229,9 @@ typedef struct uv_cpu_info_s uv_cpu_info_t;
typedef struct uv_interface_address_s uv_interface_address_t;
typedef struct uv_dirent_s uv_dirent_t;
typedef enum {
UV_LOOP_BLOCK_SIGNAL
} uv_loop_option;
typedef enum {
UV_RUN_DEFAULT = 0,
@ -257,6 +260,7 @@ UV_EXTERN uv_loop_t* uv_loop_new(void);
UV_EXTERN void uv_loop_delete(uv_loop_t*);
UV_EXTERN size_t uv_loop_size(void);
UV_EXTERN int uv_loop_alive(const uv_loop_t* loop);
UV_EXTERN int uv_loop_configure(uv_loop_t* loop, uv_loop_option option, ...);
UV_EXTERN int uv_run(uv_loop_t*, uv_run_mode mode);
UV_EXTERN void uv_stop(uv_loop_t*);

View File

@ -146,6 +146,11 @@ enum {
UV_HANDLE_IPV6 = 0x10000 /* Handle is bound to a IPv6 socket. */
};
/* loop flags */
enum {
UV_LOOP_BLOCK_SIGPROF = 1
};
typedef enum {
UV_CLOCK_PRECISE = 0, /* Use the highest resolution clock available. */
UV_CLOCK_FAST = 1 /* Use the fastest clock with <= 1ms granularity. */

View File

@ -55,9 +55,11 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
unsigned int nevents;
unsigned int revents;
QUEUE* q;
uv__io_t* w;
sigset_t* pset;
sigset_t set;
uint64_t base;
uint64_t diff;
uv__io_t* w;
int filter;
int fflags;
int count;
@ -117,6 +119,13 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
w->events = w->pevents;
}
pset = NULL;
if (loop->flags & UV_LOOP_BLOCK_SIGPROF) {
pset = &set;
sigemptyset(pset);
sigaddset(pset, SIGPROF);
}
assert(timeout >= -1);
base = loop->time;
count = 48; /* Benchmarks suggest this gives the best throughput. */
@ -127,6 +136,9 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
spec.tv_nsec = (timeout % 1000) * 1000000;
}
if (pset != NULL)
pthread_sigmask(SIG_BLOCK, pset, NULL);
nfds = kevent(loop->backend_fd,
events,
nevents,
@ -134,6 +146,9 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
ARRAY_SIZE(events),
timeout == -1 ? NULL : &spec);
if (pset != NULL)
pthread_sigmask(SIG_UNBLOCK, pset, NULL);
/* Update loop->time unconditionally. It's tempting to skip the update when
* timeout == 0 (i.e. non-blocking poll) but there is no guarantee that the
* operating system didn't reschedule our process while in the syscall.

View File

@ -33,6 +33,7 @@
#include <sys/prctl.h>
#include <sys/sysinfo.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <time.h>
@ -141,6 +142,8 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
struct uv__epoll_event e;
QUEUE* q;
uv__io_t* w;
sigset_t* pset;
sigset_t set;
uint64_t base;
uint64_t diff;
int nevents;
@ -191,12 +194,25 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
w->events = w->pevents;
}
pset = NULL;
if (loop->flags & UV_LOOP_BLOCK_SIGPROF) {
pset = &set;
sigemptyset(pset);
sigaddset(pset, SIGPROF);
}
assert(timeout >= -1);
base = loop->time;
count = 48; /* Benchmarks suggest this gives the best throughput. */
for (;;) {
if (!no_epoll_wait) {
if (no_epoll_wait || pset != NULL) {
nfds = uv__epoll_pwait(loop->backend_fd,
events,
ARRAY_SIZE(events),
timeout,
pset);
} else {
nfds = uv__epoll_wait(loop->backend_fd,
events,
ARRAY_SIZE(events),
@ -205,12 +221,6 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
no_epoll_wait = 1;
continue;
}
} else {
nfds = uv__epoll_pwait(loop->backend_fd,
events,
ARRAY_SIZE(events),
timeout,
NULL);
}
/* Update loop->time unconditionally. It's tempting to skip the update when

View File

@ -21,6 +21,7 @@
#include "linux-syscalls.h"
#include <unistd.h>
#include <signal.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <errno.h>
@ -328,7 +329,7 @@ int uv__epoll_pwait(int epfd,
nevents,
timeout,
sigmask,
sizeof(*sigmask));
_NSIG / 8);
#else
return errno = ENOSYS, -1;
#endif

View File

@ -44,7 +44,7 @@
#if defined(__alpha__)
# define UV__O_NONBLOCK 0x4
#elif defined(__hppa__)
# define UV__O_NONBLOCK 0x10004
# define UV__O_NONBLOCK O_NONBLOCK
#elif defined(__mips__)
# define UV__O_NONBLOCK 0x80
#elif defined(__sparc__)
@ -60,7 +60,11 @@
#define UV__IN_NONBLOCK UV__O_NONBLOCK
#define UV__SOCK_CLOEXEC UV__O_CLOEXEC
#define UV__SOCK_NONBLOCK UV__O_NONBLOCK
#if defined(SOCK_NONBLOCK)
# define UV__SOCK_NONBLOCK SOCK_NONBLOCK
#else
# define UV__SOCK_NONBLOCK UV__O_NONBLOCK
#endif
/* epoll flags */
#define UV__EPOLL_CLOEXEC UV__O_CLOEXEC

View File

@ -192,3 +192,15 @@ static void uv__loop_close(uv_loop_t* loop) {
loop->watchers = NULL;
loop->nwatchers = 0;
}
int uv__loop_configure(uv_loop_t* loop, uv_loop_option option, va_list ap) {
if (option != UV_LOOP_BLOCK_SIGNAL)
return UV_ENOSYS;
if (va_arg(ap, int) != SIGPROF)
return UV_EINVAL;
loop->flags |= UV_LOOP_BLOCK_SIGPROF;
return 0;
}

View File

@ -122,6 +122,8 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
struct timespec spec;
QUEUE* q;
uv__io_t* w;
sigset_t* pset;
sigset_t set;
uint64_t base;
uint64_t diff;
unsigned int nfds;
@ -129,6 +131,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
int saved_errno;
int nevents;
int count;
int err;
int fd;
if (loop->nfds == 0) {
@ -150,6 +153,13 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
w->events = w->pevents;
}
pset = NULL;
if (loop->flags & UV_LOOP_BLOCK_SIGPROF) {
pset = &set;
sigemptyset(pset);
sigaddset(pset, SIGPROF);
}
assert(timeout >= -1);
base = loop->time;
count = 48; /* Benchmarks suggest this gives the best throughput. */
@ -165,11 +175,20 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
nfds = 1;
saved_errno = 0;
if (port_getn(loop->backend_fd,
events,
ARRAY_SIZE(events),
&nfds,
timeout == -1 ? NULL : &spec)) {
if (pset != NULL)
pthread_sigmask(SIG_BLOCK, pset, NULL);
err = port_getn(loop->backend_fd,
events,
ARRAY_SIZE(events),
&nfds,
timeout == -1 ? NULL : &spec);
if (pset != NULL)
pthread_sigmask(SIG_UNBLOCK, pset, NULL);
if (err) {
/* Work around another kernel bug: port_getn() may return events even
* on error.
*/

View File

@ -24,6 +24,7 @@
#include <stdio.h>
#include <assert.h>
#include <stdarg.h>
#include <stddef.h> /* NULL */
#include <stdlib.h> /* malloc */
#include <string.h> /* memset */
@ -442,3 +443,16 @@ int uv_fs_scandir_next(uv_fs_t* req, uv_dirent_t* ent) {
return 0;
}
int uv_loop_configure(uv_loop_t* loop, uv_loop_option option, ...) {
va_list ap;
int err;
va_start(ap, option);
/* Any platform-agnostic options should be handled here. */
err = uv__loop_configure(loop, option, ap);
va_end(ap);
return err;
}

View File

@ -28,6 +28,7 @@
#define UV_COMMON_H_
#include <assert.h>
#include <stdarg.h>
#include <stddef.h>
#if defined(_MSC_VER) && _MSC_VER < 1600
@ -59,6 +60,8 @@ enum {
# define UV__HANDLE_CLOSING 0x01
#endif
int uv__loop_configure(uv_loop_t* loop, uv_loop_option option, va_list ap);
int uv__tcp_bind(uv_tcp_t* tcp,
const struct sockaddr* addr,
unsigned int addrlen,

View File

@ -272,6 +272,11 @@ void uv_loop_delete(uv_loop_t* loop) {
}
int uv__loop_configure(uv_loop_t* loop, uv_loop_option option, va_list ap) {
return UV_ENOSYS;
}
int uv_backend_fd(const uv_loop_t* loop) {
return -1;
}