uv: Upgrade to v0.11.8
This commit is contained in:
parent
41f55dc59b
commit
a784abaff6
53
deps/uv/ChangeLog
vendored
53
deps/uv/ChangeLog
vendored
@ -1,4 +1,55 @@
|
||||
2013.08.07, Version 0.11.7 (Unstable)
|
||||
2013.08.22, Version 0.11.8 (Unstable)
|
||||
|
||||
Changes since version 0.11.7:
|
||||
|
||||
* unix: fix missing return value warning in stream.c (Ben Noordhuis)
|
||||
|
||||
* build: serial-tests was added in automake v1.12 (Ben Noordhuis)
|
||||
|
||||
* windows: fix uninitialized local variable warning (Ben Noordhuis)
|
||||
|
||||
* windows: fix missing return value warning (Ben Noordhuis)
|
||||
|
||||
* build: fix string comparisons in autogen.sh (Ben Noordhuis)
|
||||
|
||||
* windows: move INLINE macro, remove UNUSED (Ben Noordhuis)
|
||||
|
||||
* unix: clean up __attribute__((quux)) usage (Ben Noordhuis)
|
||||
|
||||
* sunos: remove futimes() macro (Ben Noordhuis)
|
||||
|
||||
* unix: fix uv__signal_unlock() prototype (Ben Noordhuis)
|
||||
|
||||
* unix, windows: allow NULL async callback (Ben Noordhuis)
|
||||
|
||||
* build: apply dtrace -G to all object files (Timothy J. Fontaine)
|
||||
|
||||
* darwin: fix indentation in uv__hrtime() (Ben Noordhuis)
|
||||
|
||||
* darwin: create fsevents thread on demand (Ben Noordhuis)
|
||||
|
||||
* darwin: reduce fsevents thread stack size (Ben Noordhuis)
|
||||
|
||||
* darwin: call pthread_setname_np() if available (Ben Noordhuis)
|
||||
|
||||
* build: fix automake serial-tests check again (Ben Noordhuis)
|
||||
|
||||
* unix: retry waitpid() on EINTR (Ben Noordhuis)
|
||||
|
||||
* darwin: fix ios build error (Ben Noordhuis)
|
||||
|
||||
* darwin: fix ios compiler warning (Ben Noordhuis)
|
||||
|
||||
* test: simplify test-ip6-addr.c (Ben Noordhuis)
|
||||
|
||||
* unix, windows: fix ipv6 link-local address parsing (Ben Noordhuis)
|
||||
|
||||
* fsevents: FSEvents is most likely not thread-safe (Fedor Indutny)
|
||||
|
||||
* windows: omit stdint.h, fix msvc 2008 build error (Ben Noordhuis)
|
||||
|
||||
|
||||
2013.08.07, Version 0.11.7 (Unstable), 3cad361f8776f70941b39d65bd9426bcb1aa817b
|
||||
|
||||
Changes since version 0.11.6:
|
||||
|
||||
|
3
deps/uv/Makefile.am
vendored
3
deps/uv/Makefile.am
vendored
@ -63,6 +63,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
|
||||
test/task.h \
|
||||
test/test-active.c \
|
||||
test/test-async.c \
|
||||
test/test-async-null-cb.c \
|
||||
test/test-barrier.c \
|
||||
test/test-callback-order.c \
|
||||
test/test-callback-stack.c \
|
||||
@ -215,7 +216,7 @@ src/unix/uv-dtrace.o: src/unix/uv-dtrace.d ${libuv_la_OBJECTS}
|
||||
# every created .o, most projects don't need to include more than one .d
|
||||
.d.o:
|
||||
$(AM_V_GEN)$(DTRACE) $(DTRACEFLAGS) -G -o $(top_builddir)/uv-dtrace.o -s $< \
|
||||
`grep '^pic_object' $$(find ${top_builddir} -name "*.lo") | cut -f 2 -d\'`
|
||||
`find ${top_builddir}/src -name "*.o"`
|
||||
$(AM_V_GEN)printf %s\\n \
|
||||
'# ${top_builddir}/uv-dtrace.lo - a libtool object file' \
|
||||
'# Generated by libtool (GNU libtool) 2.4' \
|
||||
|
31
deps/uv/autogen.sh
vendored
31
deps/uv/autogen.sh
vendored
@ -14,12 +14,33 @@
|
||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
if [ "$LIBTOOLIZE" == "" ] && [ "`uname`" == "Darwin" ]; then
|
||||
cd `dirname "$0"`
|
||||
|
||||
if [ "$LIBTOOLIZE" = "" ] && [ "`uname`" = "Darwin" ]; then
|
||||
LIBTOOLIZE=glibtoolize
|
||||
fi
|
||||
|
||||
ACLOCAL=${ACLOCAL:-aclocal}
|
||||
AUTOCONF=${AUTOCONF:-autoconf}
|
||||
AUTOMAKE=${AUTOMAKE:-automake}
|
||||
LIBTOOLIZE=${LIBTOOLIZE:-libtoolize}
|
||||
|
||||
automake_version=`"$AUTOMAKE" --version | head -n 1 | sed 's/[^.0-9]//g'`
|
||||
automake_version_major=`echo "$automake_version" | cut -d. -f1`
|
||||
automake_version_minor=`echo "$automake_version" | cut -d. -f2`
|
||||
|
||||
UV_EXTRA_AUTOMAKE_FLAGS=
|
||||
if test "$automake_version_major" -gt 1 || \
|
||||
test "$automake_version_major" -eq 1 && \
|
||||
test "$automake_version_minor" -gt 11; then
|
||||
# serial-tests is available in v0.12 and newer.
|
||||
UV_EXTRA_AUTOMAKE_FLAGS="$UV_EXTRA_AUTOMAKE_FLAGS serial-tests"
|
||||
fi
|
||||
echo "m4_define([UV_EXTRA_AUTOMAKE_FLAGS], [$UV_EXTRA_AUTOMAKE_FLAGS])" \
|
||||
> m4/libuv-extra-automake-flags.m4
|
||||
|
||||
set -ex
|
||||
${LIBTOOLIZE:-libtoolize}
|
||||
${ACLOCAL:-aclocal -I m4}
|
||||
${AUTOCONF:-autoconf}
|
||||
${AUTOMAKE:-automake} --add-missing
|
||||
"$LIBTOOLIZE"
|
||||
"$ACLOCAL" -I m4
|
||||
"$AUTOCONF"
|
||||
"$AUTOMAKE" --add-missing --copy
|
||||
|
7
deps/uv/configure.ac
vendored
7
deps/uv/configure.ac
vendored
@ -14,12 +14,9 @@
|
||||
|
||||
AC_PREREQ(2.57)
|
||||
AC_INIT([libuv], [0.11.5], [https://github.com/joyent/libuv/issues])
|
||||
# Use AM_SILENT_RULES as an ad-hoc version check to find out if it's safe
|
||||
# to use the serial-tests directive. Both were added in automake v0.11.
|
||||
AM_INIT_AUTOMAKE(m4_ifdef([AM_SILENT_RULES],
|
||||
[-Wall -Werror foreign subdir-objects serial-tests],
|
||||
[-Wall -Werror foreign subdir-objects]))
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
m4_include([m4/libuv-extra-automake-flags.m4])
|
||||
AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects] UV_EXTRA_AUTOMAKE_FLAGS)
|
||||
AC_CANONICAL_HOST
|
||||
AC_ENABLE_SHARED
|
||||
AC_ENABLE_STATIC
|
||||
|
6
deps/uv/include/uv.h
vendored
6
deps/uv/include/uv.h
vendored
@ -1239,6 +1239,12 @@ struct uv_async_s {
|
||||
UV_ASYNC_PRIVATE_FIELDS
|
||||
};
|
||||
|
||||
/*
|
||||
* Initialize the uv_async_t handle. A NULL callback is allowed.
|
||||
*
|
||||
* Note that uv_async_init(), unlike other libuv functions, immediately
|
||||
* starts the handle. To stop the handle again, close it with uv_close().
|
||||
*/
|
||||
UV_EXTERN int uv_async_init(uv_loop_t*, uv_async_t* async,
|
||||
uv_async_cb async_cb);
|
||||
|
||||
|
4
deps/uv/src/queue.h
vendored
4
deps/uv/src/queue.h
vendored
@ -16,8 +16,6 @@
|
||||
#ifndef QUEUE_H_
|
||||
#define QUEUE_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef void *QUEUE[2];
|
||||
|
||||
/* Private macros. */
|
||||
@ -28,7 +26,7 @@ typedef void *QUEUE[2];
|
||||
|
||||
/* Public macros. */
|
||||
#define QUEUE_DATA(ptr, type, field) \
|
||||
((type *) ((char *) (ptr) - ((uintptr_t) &((type *) 0)->field)))
|
||||
((type *) ((char *) (ptr) - ((char *) &((type *) 0)->field)))
|
||||
|
||||
#define QUEUE_FOREACH(q, h) \
|
||||
for ((q) = (QUEUE *) (*(h))[0]; (q) != (h); (q) = (QUEUE *) (*(q))[0])
|
||||
|
7
deps/uv/src/unix/async.c
vendored
7
deps/uv/src/unix/async.c
vendored
@ -78,8 +78,13 @@ static void uv__async_event(uv_loop_t* loop,
|
||||
|
||||
QUEUE_FOREACH(q, &loop->async_handles) {
|
||||
h = QUEUE_DATA(q, uv_async_t, queue);
|
||||
if (!h->pending) continue;
|
||||
|
||||
if (h->pending == 0)
|
||||
continue;
|
||||
h->pending = 0;
|
||||
|
||||
if (h->async_cb == NULL)
|
||||
continue;
|
||||
h->async_cb(h, 0);
|
||||
}
|
||||
}
|
||||
|
29
deps/uv/src/unix/darwin-proctitle.c
vendored
29
deps/uv/src/unix/darwin-proctitle.c
vendored
@ -18,6 +18,10 @@
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <TargetConditionals.h>
|
||||
|
||||
#if !TARGET_OS_IPHONE
|
||||
@ -26,9 +30,30 @@
|
||||
#endif
|
||||
|
||||
|
||||
static int uv__pthread_setname_np(const char* name) {
|
||||
int (*dynamic_pthread_setname_np)(const char* name);
|
||||
char namebuf[64]; /* MAXTHREADNAMESIZE */
|
||||
int err;
|
||||
|
||||
/* pthread_setname_np() first appeared in OS X 10.6 and iOS 3.2. */
|
||||
dynamic_pthread_setname_np = dlsym(RTLD_DEFAULT, "pthread_setname_np");
|
||||
if (dynamic_pthread_setname_np == NULL)
|
||||
return -ENOSYS;
|
||||
|
||||
strncpy(namebuf, name, sizeof(namebuf) - 1);
|
||||
namebuf[sizeof(namebuf) - 1] = '\0';
|
||||
|
||||
err = dynamic_pthread_setname_np(namebuf);
|
||||
if (err)
|
||||
return -err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv__set_process_title(const char* title) {
|
||||
#if TARGET_OS_IPHONE
|
||||
return -ENOSYS;
|
||||
return uv__pthread_setname_np(title);
|
||||
#else
|
||||
typedef CFTypeRef (*LSGetCurrentApplicationASNType)(void);
|
||||
typedef OSStatus (*LSSetApplicationInformationItemType)(int,
|
||||
@ -84,6 +109,8 @@ int uv__set_process_title(const char* title) {
|
||||
if (err != noErr)
|
||||
return -ENOENT;
|
||||
|
||||
uv__pthread_setname_np(title); /* Don't care if it fails. */
|
||||
|
||||
return 0;
|
||||
#endif /* !TARGET_OS_IPHONE */
|
||||
}
|
||||
|
139
deps/uv/src/unix/darwin.c
vendored
139
deps/uv/src/unix/darwin.c
vendored
@ -29,8 +29,6 @@
|
||||
#include <net/if.h>
|
||||
#include <net/if_dl.h>
|
||||
|
||||
#include <CoreFoundation/CFRunLoop.h>
|
||||
|
||||
#include <mach/mach.h>
|
||||
#include <mach/mach_time.h>
|
||||
#include <mach-o/dyld.h> /* _NSGetExecutablePath */
|
||||
@ -38,154 +36,29 @@
|
||||
#include <sys/sysctl.h>
|
||||
#include <unistd.h> /* sysconf */
|
||||
|
||||
/* Forward declarations */
|
||||
static void uv__cf_loop_runner(void* arg);
|
||||
static void uv__cf_loop_cb(void* arg);
|
||||
|
||||
typedef struct uv__cf_loop_signal_s uv__cf_loop_signal_t;
|
||||
struct uv__cf_loop_signal_s {
|
||||
void* arg;
|
||||
cf_loop_signal_cb cb;
|
||||
QUEUE member;
|
||||
};
|
||||
|
||||
|
||||
int uv__platform_loop_init(uv_loop_t* loop, int default_loop) {
|
||||
CFRunLoopSourceContext ctx;
|
||||
int r;
|
||||
loop->cf_loop = NULL;
|
||||
|
||||
if (uv__kqueue_init(loop))
|
||||
return -errno;
|
||||
|
||||
loop->cf_loop = NULL;
|
||||
if ((r = uv_mutex_init(&loop->cf_mutex)))
|
||||
return r;
|
||||
if ((r = uv_sem_init(&loop->cf_sem, 0)))
|
||||
return r;
|
||||
QUEUE_INIT(&loop->cf_signals);
|
||||
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
ctx.info = loop;
|
||||
ctx.perform = uv__cf_loop_cb;
|
||||
loop->cf_cb = CFRunLoopSourceCreate(NULL, 0, &ctx);
|
||||
|
||||
if ((r = uv_thread_create(&loop->cf_thread, uv__cf_loop_runner, loop)))
|
||||
return r;
|
||||
|
||||
/* Synchronize threads */
|
||||
uv_sem_wait(&loop->cf_sem);
|
||||
assert(ACCESS_ONCE(CFRunLoopRef, loop->cf_loop) != NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void uv__platform_loop_delete(uv_loop_t* loop) {
|
||||
QUEUE* item;
|
||||
uv__cf_loop_signal_t* s;
|
||||
|
||||
assert(loop->cf_loop != NULL);
|
||||
uv__cf_loop_signal(loop, NULL, NULL);
|
||||
uv_thread_join(&loop->cf_thread);
|
||||
|
||||
uv_sem_destroy(&loop->cf_sem);
|
||||
uv_mutex_destroy(&loop->cf_mutex);
|
||||
|
||||
/* Free any remaining data */
|
||||
while (!QUEUE_EMPTY(&loop->cf_signals)) {
|
||||
item = QUEUE_HEAD(&loop->cf_signals);
|
||||
|
||||
s = QUEUE_DATA(item, uv__cf_loop_signal_t, member);
|
||||
|
||||
QUEUE_REMOVE(item);
|
||||
free(s);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void uv__cf_loop_runner(void* arg) {
|
||||
uv_loop_t* loop;
|
||||
|
||||
loop = arg;
|
||||
|
||||
/* Get thread's loop */
|
||||
ACCESS_ONCE(CFRunLoopRef, loop->cf_loop) = CFRunLoopGetCurrent();
|
||||
|
||||
CFRunLoopAddSource(loop->cf_loop,
|
||||
loop->cf_cb,
|
||||
kCFRunLoopDefaultMode);
|
||||
|
||||
uv_sem_post(&loop->cf_sem);
|
||||
|
||||
CFRunLoopRun();
|
||||
|
||||
CFRunLoopRemoveSource(loop->cf_loop,
|
||||
loop->cf_cb,
|
||||
kCFRunLoopDefaultMode);
|
||||
}
|
||||
|
||||
|
||||
static void uv__cf_loop_cb(void* arg) {
|
||||
uv_loop_t* loop;
|
||||
QUEUE* item;
|
||||
QUEUE split_head;
|
||||
uv__cf_loop_signal_t* s;
|
||||
|
||||
loop = arg;
|
||||
|
||||
uv_mutex_lock(&loop->cf_mutex);
|
||||
QUEUE_INIT(&split_head);
|
||||
if (!QUEUE_EMPTY(&loop->cf_signals)) {
|
||||
QUEUE* split_pos = QUEUE_HEAD(&loop->cf_signals);
|
||||
QUEUE_SPLIT(&loop->cf_signals, split_pos, &split_head);
|
||||
}
|
||||
uv_mutex_unlock(&loop->cf_mutex);
|
||||
|
||||
while (!QUEUE_EMPTY(&split_head)) {
|
||||
item = QUEUE_HEAD(&split_head);
|
||||
|
||||
s = QUEUE_DATA(item, uv__cf_loop_signal_t, member);
|
||||
|
||||
/* This was a termination signal */
|
||||
if (s->cb == NULL)
|
||||
CFRunLoopStop(loop->cf_loop);
|
||||
else
|
||||
s->cb(s->arg);
|
||||
|
||||
QUEUE_REMOVE(item);
|
||||
free(s);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void uv__cf_loop_signal(uv_loop_t* loop, cf_loop_signal_cb cb, void* arg) {
|
||||
uv__cf_loop_signal_t* item;
|
||||
|
||||
item = malloc(sizeof(*item));
|
||||
/* XXX: Fail */
|
||||
if (item == NULL)
|
||||
abort();
|
||||
|
||||
item->arg = arg;
|
||||
item->cb = cb;
|
||||
|
||||
uv_mutex_lock(&loop->cf_mutex);
|
||||
QUEUE_INSERT_TAIL(&loop->cf_signals, &item->member);
|
||||
uv_mutex_unlock(&loop->cf_mutex);
|
||||
|
||||
assert(loop->cf_loop != NULL);
|
||||
CFRunLoopSourceSignal(loop->cf_cb);
|
||||
CFRunLoopWakeUp(loop->cf_loop);
|
||||
uv__fsevents_loop_delete(loop);
|
||||
}
|
||||
|
||||
|
||||
uint64_t uv__hrtime(void) {
|
||||
mach_timebase_info_data_t info;
|
||||
mach_timebase_info_data_t info;
|
||||
|
||||
if (mach_timebase_info(&info) != KERN_SUCCESS)
|
||||
abort();
|
||||
if (mach_timebase_info(&info) != KERN_SUCCESS)
|
||||
abort();
|
||||
|
||||
return mach_absolute_time() * info.numer / info.denom;
|
||||
return mach_absolute_time() * info.numer / info.denom;
|
||||
}
|
||||
|
||||
|
||||
|
4
deps/uv/src/unix/fs.c
vendored
4
deps/uv/src/unix/fs.c
vendored
@ -176,7 +176,11 @@ skip:
|
||||
tv[0].tv_usec = (unsigned long)(req->atime * 1000000) % 1000000;
|
||||
tv[1].tv_sec = req->mtime;
|
||||
tv[1].tv_usec = (unsigned long)(req->mtime * 1000000) % 1000000;
|
||||
# if defined(__sun)
|
||||
return futimesat(req->file, NULL, tv);
|
||||
# else
|
||||
return futimes(req->file, tv);
|
||||
# endif
|
||||
#else
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
|
267
deps/uv/src/unix/fsevents.c
vendored
267
deps/uv/src/unix/fsevents.c
vendored
@ -34,13 +34,28 @@ int uv__fsevents_close(uv_fs_event_t* handle) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void uv__fsevents_loop_delete(uv_loop_t* loop) {
|
||||
}
|
||||
|
||||
#else /* TARGET_OS_IPHONE */
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <CoreFoundation/CFRunLoop.h>
|
||||
#include <CoreServices/CoreServices.h>
|
||||
|
||||
typedef struct uv__fsevents_event_s uv__fsevents_event_t;
|
||||
typedef struct uv__cf_loop_signal_s uv__cf_loop_signal_t;
|
||||
typedef void (*cf_loop_signal_cb)(void* arg);
|
||||
|
||||
struct uv__cf_loop_signal_s {
|
||||
cf_loop_signal_cb cb;
|
||||
QUEUE member;
|
||||
void* arg;
|
||||
};
|
||||
|
||||
struct uv__fsevents_event_s {
|
||||
int events;
|
||||
@ -48,6 +63,12 @@ struct uv__fsevents_event_s {
|
||||
char path[1];
|
||||
};
|
||||
|
||||
/* Forward declarations */
|
||||
static void uv__cf_loop_cb(void* arg);
|
||||
static void* uv__cf_loop_runner(void* arg);
|
||||
static void uv__cf_loop_signal(uv_loop_t* loop,
|
||||
cf_loop_signal_cb cb,
|
||||
void* arg);
|
||||
|
||||
#define UV__FSEVENTS_WALK(handle, block) \
|
||||
{ \
|
||||
@ -75,7 +96,7 @@ struct uv__fsevents_event_s {
|
||||
}
|
||||
|
||||
|
||||
void uv__fsevents_cb(uv_async_t* cb, int status) {
|
||||
static void uv__fsevents_cb(uv_async_t* cb, int status) {
|
||||
uv_fs_event_t* handle;
|
||||
|
||||
handle = cb->data;
|
||||
@ -92,12 +113,12 @@ void uv__fsevents_cb(uv_async_t* cb, int status) {
|
||||
}
|
||||
|
||||
|
||||
void uv__fsevents_event_cb(ConstFSEventStreamRef streamRef,
|
||||
void* info,
|
||||
size_t numEvents,
|
||||
void* eventPaths,
|
||||
const FSEventStreamEventFlags eventFlags[],
|
||||
const FSEventStreamEventId eventIds[]) {
|
||||
static void uv__fsevents_event_cb(ConstFSEventStreamRef streamRef,
|
||||
void* info,
|
||||
size_t numEvents,
|
||||
void* eventPaths,
|
||||
const FSEventStreamEventFlags eventFlags[],
|
||||
const FSEventStreamEventId eventIds[]) {
|
||||
size_t i;
|
||||
int len;
|
||||
char** paths;
|
||||
@ -190,19 +211,8 @@ void uv__fsevents_event_cb(ConstFSEventStreamRef streamRef,
|
||||
}
|
||||
|
||||
|
||||
void uv__fsevents_schedule(void* arg) {
|
||||
static void uv__fsevents_schedule(void* arg) {
|
||||
uv_fs_event_t* handle;
|
||||
|
||||
handle = arg;
|
||||
FSEventStreamScheduleWithRunLoop(handle->cf_eventstream,
|
||||
handle->loop->cf_loop,
|
||||
kCFRunLoopDefaultMode);
|
||||
FSEventStreamStart(handle->cf_eventstream);
|
||||
uv_sem_post(&handle->cf_sem);
|
||||
}
|
||||
|
||||
|
||||
int uv__fsevents_init(uv_fs_event_t* handle) {
|
||||
FSEventStreamContext ctx;
|
||||
FSEventStreamRef ref;
|
||||
CFStringRef path;
|
||||
@ -210,6 +220,8 @@ int uv__fsevents_init(uv_fs_event_t* handle) {
|
||||
CFAbsoluteTime latency;
|
||||
FSEventStreamCreateFlags flags;
|
||||
|
||||
handle = arg;
|
||||
|
||||
/* Initialize context */
|
||||
ctx.version = 0;
|
||||
ctx.info = handle;
|
||||
@ -217,16 +229,13 @@ int uv__fsevents_init(uv_fs_event_t* handle) {
|
||||
ctx.release = NULL;
|
||||
ctx.copyDescription = NULL;
|
||||
|
||||
/* Get absolute path to file */
|
||||
handle->realpath = realpath(handle->filename, NULL);
|
||||
if (handle->realpath != NULL)
|
||||
handle->realpath_len = strlen(handle->realpath);
|
||||
|
||||
/* Initialize paths array */
|
||||
path = CFStringCreateWithCString(NULL,
|
||||
handle->filename,
|
||||
CFStringGetSystemEncoding());
|
||||
assert(path != NULL);
|
||||
paths = CFArrayCreate(NULL, (const void**)&path, 1, NULL);
|
||||
assert(paths != NULL);
|
||||
|
||||
latency = 0.15;
|
||||
|
||||
@ -240,8 +249,203 @@ int uv__fsevents_init(uv_fs_event_t* handle) {
|
||||
kFSEventStreamEventIdSinceNow,
|
||||
latency,
|
||||
flags);
|
||||
assert(ref != NULL);
|
||||
handle->cf_eventstream = ref;
|
||||
|
||||
FSEventStreamScheduleWithRunLoop(handle->cf_eventstream,
|
||||
handle->loop->cf_loop,
|
||||
kCFRunLoopDefaultMode);
|
||||
if (!FSEventStreamStart(handle->cf_eventstream))
|
||||
abort();
|
||||
}
|
||||
|
||||
|
||||
static void uv__fsevents_unschedule(void* arg) {
|
||||
uv_fs_event_t* handle;
|
||||
|
||||
handle = arg;
|
||||
|
||||
/* Stop emitting events */
|
||||
FSEventStreamStop(handle->cf_eventstream);
|
||||
|
||||
/* Release stream */
|
||||
FSEventStreamInvalidate(handle->cf_eventstream);
|
||||
FSEventStreamRelease(handle->cf_eventstream);
|
||||
handle->cf_eventstream = NULL;
|
||||
|
||||
/* Notify main thread that we're done here */
|
||||
uv_sem_post(&handle->cf_sem);
|
||||
}
|
||||
|
||||
|
||||
static int uv__fsevents_loop_init(uv_loop_t* loop) {
|
||||
CFRunLoopSourceContext ctx;
|
||||
pthread_attr_t attr_storage;
|
||||
pthread_attr_t* attr;
|
||||
int err;
|
||||
|
||||
if (loop->cf_loop != NULL)
|
||||
return 0;
|
||||
|
||||
err = uv_mutex_init(&loop->cf_mutex);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = uv_sem_init(&loop->cf_sem, 0);
|
||||
if (err)
|
||||
goto fail_sem_init;
|
||||
|
||||
QUEUE_INIT(&loop->cf_signals);
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
ctx.info = loop;
|
||||
ctx.perform = uv__cf_loop_cb;
|
||||
loop->cf_cb = CFRunLoopSourceCreate(NULL, 0, &ctx);
|
||||
|
||||
/* In the unlikely event that pthread_attr_init() fails, create the thread
|
||||
* with the default stack size. We'll use a little more address space but
|
||||
* that in itself is not a fatal error.
|
||||
*/
|
||||
attr = &attr_storage;
|
||||
if (pthread_attr_init(attr))
|
||||
attr = NULL;
|
||||
|
||||
if (attr != NULL)
|
||||
if (pthread_attr_setstacksize(attr, 3 * PTHREAD_STACK_MIN))
|
||||
abort();
|
||||
|
||||
/* uv_thread_t is an alias for pthread_t. */
|
||||
err = -pthread_create(&loop->cf_thread, attr, uv__cf_loop_runner, loop);
|
||||
|
||||
if (attr != NULL)
|
||||
pthread_attr_destroy(attr);
|
||||
|
||||
if (err)
|
||||
goto fail_thread_create;
|
||||
|
||||
/* Synchronize threads */
|
||||
uv_sem_wait(&loop->cf_sem);
|
||||
assert(loop->cf_loop != NULL);
|
||||
return 0;
|
||||
|
||||
fail_thread_create:
|
||||
uv_sem_destroy(&loop->cf_sem);
|
||||
|
||||
fail_sem_init:
|
||||
uv_mutex_destroy(&loop->cf_mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
void uv__fsevents_loop_delete(uv_loop_t* loop) {
|
||||
uv__cf_loop_signal_t* s;
|
||||
QUEUE* q;
|
||||
|
||||
if (loop->cf_loop == NULL)
|
||||
return;
|
||||
|
||||
uv__cf_loop_signal(loop, NULL, NULL);
|
||||
uv_thread_join(&loop->cf_thread);
|
||||
uv_sem_destroy(&loop->cf_sem);
|
||||
uv_mutex_destroy(&loop->cf_mutex);
|
||||
|
||||
/* Free any remaining data */
|
||||
while (!QUEUE_EMPTY(&loop->cf_signals)) {
|
||||
q = QUEUE_HEAD(&loop->cf_signals);
|
||||
s = QUEUE_DATA(q, uv__cf_loop_signal_t, member);
|
||||
QUEUE_REMOVE(q);
|
||||
free(s);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void* uv__cf_loop_runner(void* arg) {
|
||||
uv_loop_t* loop;
|
||||
|
||||
loop = arg;
|
||||
loop->cf_loop = CFRunLoopGetCurrent();
|
||||
|
||||
CFRunLoopAddSource(loop->cf_loop,
|
||||
loop->cf_cb,
|
||||
kCFRunLoopDefaultMode);
|
||||
|
||||
uv_sem_post(&loop->cf_sem);
|
||||
|
||||
CFRunLoopRun();
|
||||
CFRunLoopRemoveSource(loop->cf_loop,
|
||||
loop->cf_cb,
|
||||
kCFRunLoopDefaultMode);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void uv__cf_loop_cb(void* arg) {
|
||||
uv_loop_t* loop;
|
||||
QUEUE* item;
|
||||
QUEUE split_head;
|
||||
uv__cf_loop_signal_t* s;
|
||||
|
||||
loop = arg;
|
||||
|
||||
uv_mutex_lock(&loop->cf_mutex);
|
||||
QUEUE_INIT(&split_head);
|
||||
if (!QUEUE_EMPTY(&loop->cf_signals)) {
|
||||
QUEUE* split_pos = QUEUE_HEAD(&loop->cf_signals);
|
||||
QUEUE_SPLIT(&loop->cf_signals, split_pos, &split_head);
|
||||
}
|
||||
uv_mutex_unlock(&loop->cf_mutex);
|
||||
|
||||
while (!QUEUE_EMPTY(&split_head)) {
|
||||
item = QUEUE_HEAD(&split_head);
|
||||
|
||||
s = QUEUE_DATA(item, uv__cf_loop_signal_t, member);
|
||||
|
||||
/* This was a termination signal */
|
||||
if (s->cb == NULL)
|
||||
CFRunLoopStop(loop->cf_loop);
|
||||
else
|
||||
s->cb(s->arg);
|
||||
|
||||
QUEUE_REMOVE(item);
|
||||
free(s);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void uv__cf_loop_signal(uv_loop_t* loop, cf_loop_signal_cb cb, void* arg) {
|
||||
uv__cf_loop_signal_t* item;
|
||||
|
||||
item = malloc(sizeof(*item));
|
||||
/* XXX: Fail */
|
||||
if (item == NULL)
|
||||
abort();
|
||||
|
||||
item->arg = arg;
|
||||
item->cb = cb;
|
||||
|
||||
uv_mutex_lock(&loop->cf_mutex);
|
||||
QUEUE_INSERT_TAIL(&loop->cf_signals, &item->member);
|
||||
uv_mutex_unlock(&loop->cf_mutex);
|
||||
|
||||
assert(loop->cf_loop != NULL);
|
||||
CFRunLoopSourceSignal(loop->cf_cb);
|
||||
CFRunLoopWakeUp(loop->cf_loop);
|
||||
}
|
||||
|
||||
|
||||
int uv__fsevents_init(uv_fs_event_t* handle) {
|
||||
int err;
|
||||
|
||||
err = uv__fsevents_loop_init(handle->loop);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Get absolute path to file */
|
||||
handle->realpath = realpath(handle->filename, NULL);
|
||||
if (handle->realpath != NULL)
|
||||
handle->realpath_len = strlen(handle->realpath);
|
||||
|
||||
handle->cf_eventstream = NULL;
|
||||
/*
|
||||
* Events will occur in other thread.
|
||||
* Initialize callback for getting them back into event loop's thread
|
||||
@ -266,21 +470,16 @@ int uv__fsevents_init(uv_fs_event_t* handle) {
|
||||
|
||||
|
||||
int uv__fsevents_close(uv_fs_event_t* handle) {
|
||||
if (handle->cf_eventstream == NULL)
|
||||
if (handle->cf_cb == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
/* Ensure that event stream was scheduled */
|
||||
uv__cf_loop_signal(handle->loop, uv__fsevents_unschedule, handle);
|
||||
|
||||
/* Wait for deinitialization */
|
||||
uv_sem_wait(&handle->cf_sem);
|
||||
|
||||
/* Stop emitting events */
|
||||
FSEventStreamStop(handle->cf_eventstream);
|
||||
|
||||
/* Release stream */
|
||||
FSEventStreamInvalidate(handle->cf_eventstream);
|
||||
FSEventStreamRelease(handle->cf_eventstream);
|
||||
handle->cf_eventstream = NULL;
|
||||
|
||||
uv_close((uv_handle_t*) handle->cf_cb, (uv_close_cb) free);
|
||||
handle->cf_cb = NULL;
|
||||
|
||||
/* Free data in queue */
|
||||
UV__FSEVENTS_WALK(handle, {
|
||||
|
31
deps/uv/src/unix/internal.h
vendored
31
deps/uv/src/unix/internal.h
vendored
@ -39,7 +39,6 @@
|
||||
#if defined(__sun)
|
||||
# include <sys/port.h>
|
||||
# include <port.h>
|
||||
# define futimes(fd, tv) futimesat(fd, (void*)0, tv)
|
||||
#endif /* __sun */
|
||||
|
||||
#if defined(__APPLE__) && !TARGET_OS_IPHONE
|
||||
@ -67,6 +66,21 @@
|
||||
} \
|
||||
while (0)
|
||||
|
||||
/* The __clang__ and __INTEL_COMPILER checks are superfluous because they
|
||||
* define __GNUC__. They are here to convey to you, dear reader, that these
|
||||
* macros are enabled when compiling with clang or icc.
|
||||
*/
|
||||
#if defined(__clang__) || \
|
||||
defined(__GNUC__) || \
|
||||
defined(__INTEL_COMPILER) || \
|
||||
defined(__SUNPRO_C)
|
||||
# define UV_DESTRUCTOR(declaration) __attribute__((destructor)) declaration
|
||||
# define UV_UNUSED(declaration) __attribute__((unused)) declaration
|
||||
#else
|
||||
# define UV_DESTRUCTOR(declaration) declaration
|
||||
# define UV_UNUSED(declaration) declaration
|
||||
#endif
|
||||
|
||||
#if defined(__linux__)
|
||||
# define UV__POLLIN UV__EPOLLIN
|
||||
# define UV__POLLOUT UV__EPOLLOUT
|
||||
@ -215,12 +229,10 @@ int uv__make_socketpair(int fds[2], int flags);
|
||||
int uv__make_pipe(int fds[2], int flags);
|
||||
|
||||
#if defined(__APPLE__)
|
||||
typedef void (*cf_loop_signal_cb)(void*);
|
||||
|
||||
void uv__cf_loop_signal(uv_loop_t* loop, cf_loop_signal_cb cb, void* arg);
|
||||
|
||||
int uv__fsevents_init(uv_fs_event_t* handle);
|
||||
int uv__fsevents_close(uv_fs_event_t* handle);
|
||||
void uv__fsevents_loop_delete(uv_loop_t* loop);
|
||||
|
||||
/* OSX < 10.7 has no file events, polyfill them */
|
||||
#ifndef MAC_OS_X_VERSION_10_7
|
||||
@ -242,21 +254,20 @@ static const int kFSEventStreamEventFlagItemIsSymlink = 0x00040000;
|
||||
|
||||
#endif /* defined(__APPLE__) */
|
||||
|
||||
__attribute__((unused))
|
||||
static void uv__req_init(uv_loop_t* loop, uv_req_t* req, uv_req_type type) {
|
||||
UV_UNUSED(static void uv__req_init(uv_loop_t* loop,
|
||||
uv_req_t* req,
|
||||
uv_req_type type)) {
|
||||
req->type = type;
|
||||
uv__req_register(loop, req);
|
||||
}
|
||||
#define uv__req_init(loop, req, type) \
|
||||
uv__req_init((loop), (uv_req_t*)(req), (type))
|
||||
|
||||
__attribute__((unused))
|
||||
static void uv__update_time(uv_loop_t* loop) {
|
||||
UV_UNUSED(static void uv__update_time(uv_loop_t* loop)) {
|
||||
loop->time = uv__hrtime() / 1000000;
|
||||
}
|
||||
|
||||
__attribute__((unused))
|
||||
static char* uv__basename_r(const char* path) {
|
||||
UV_UNUSED(static char* uv__basename_r(const char* path)) {
|
||||
char* s;
|
||||
|
||||
s = strrchr(path, '/');
|
||||
|
1
deps/uv/src/unix/kqueue.c
vendored
1
deps/uv/src/unix/kqueue.c
vendored
@ -319,6 +319,7 @@ int uv_fs_event_init(uv_loop_t* loop,
|
||||
|
||||
#if defined(__APPLE__)
|
||||
/* Nullify field to perform checks later */
|
||||
handle->cf_cb = NULL;
|
||||
handle->cf_eventstream = NULL;
|
||||
handle->realpath = NULL;
|
||||
handle->realpath_len = 0;
|
||||
|
4
deps/uv/src/unix/process.c
vendored
4
deps/uv/src/unix/process.c
vendored
@ -73,7 +73,9 @@ static void uv__chld(uv_signal_t* handle, int signum) {
|
||||
assert(signum == SIGCHLD);
|
||||
|
||||
for (;;) {
|
||||
pid = waitpid(-1, &status, WNOHANG);
|
||||
do
|
||||
pid = waitpid(-1, &status, WNOHANG);
|
||||
while (pid == -1 && errno == EINTR);
|
||||
|
||||
if (pid == 0)
|
||||
return;
|
||||
|
3
deps/uv/src/unix/proctitle.c
vendored
3
deps/uv/src/unix/proctitle.c
vendored
@ -96,8 +96,7 @@ int uv_get_process_title(char* buffer, size_t size) {
|
||||
}
|
||||
|
||||
|
||||
__attribute__((destructor))
|
||||
static void free_args_mem(void) {
|
||||
UV_DESTRUCTOR(static void free_args_mem(void)) {
|
||||
free(args_mem); /* Keep valgrind happy. */
|
||||
args_mem = NULL;
|
||||
}
|
||||
|
2
deps/uv/src/unix/signal.c
vendored
2
deps/uv/src/unix/signal.c
vendored
@ -37,7 +37,7 @@ typedef struct {
|
||||
RB_HEAD(uv__signal_tree_s, uv_signal_s);
|
||||
|
||||
|
||||
static int uv__signal_unlock();
|
||||
static int uv__signal_unlock(void);
|
||||
static void uv__signal_event(uv_loop_t* loop, uv__io_t* w, unsigned int events);
|
||||
static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2);
|
||||
static void uv__signal_stop(uv_signal_t* handle);
|
||||
|
2
deps/uv/src/unix/stream.c
vendored
2
deps/uv/src/unix/stream.c
vendored
@ -1443,4 +1443,6 @@ void uv__stream_close(uv_stream_t* handle) {
|
||||
|
||||
int uv_stream_set_blocking(uv_stream_t* handle, int blocking) {
|
||||
assert(0 && "implement me");
|
||||
abort();
|
||||
return 0;
|
||||
}
|
||||
|
5
deps/uv/src/unix/threadpool.c
vendored
5
deps/uv/src/unix/threadpool.c
vendored
@ -129,9 +129,7 @@ static void init_once(void) {
|
||||
}
|
||||
|
||||
|
||||
#if defined(__GNUC__)
|
||||
__attribute__((destructor))
|
||||
static void cleanup(void) {
|
||||
UV_DESTRUCTOR(static void cleanup(void)) {
|
||||
unsigned int i;
|
||||
|
||||
if (initialized == 0)
|
||||
@ -153,7 +151,6 @@ static void cleanup(void) {
|
||||
nthreads = 0;
|
||||
initialized = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void uv__work_submit(uv_loop_t* loop,
|
||||
|
10
deps/uv/src/uv-common.c
vendored
10
deps/uv/src/uv-common.c
vendored
@ -154,11 +154,12 @@ struct sockaddr_in6 uv_ip6_addr(const char* ip, int port) {
|
||||
#if defined(UV_PLATFORM_HAS_IP6_LINK_LOCAL_ADDRESS)
|
||||
zone_index = strchr(ip, '%');
|
||||
if (zone_index != NULL) {
|
||||
address_part_size = sizeof(address_part);
|
||||
assert((unsigned)(zone_index - ip) < address_part_size);
|
||||
strncpy(address_part, ip, zone_index - ip);
|
||||
address_part[address_part_size - 1] = '\0';
|
||||
address_part_size = zone_index - ip;
|
||||
if (address_part_size >= sizeof(address_part))
|
||||
address_part_size = sizeof(address_part) - 1;
|
||||
|
||||
memcpy(address_part, ip, address_part_size);
|
||||
address_part[address_part_size] = '\0';
|
||||
ip = address_part;
|
||||
|
||||
zone_index++; /* skip '%' */
|
||||
@ -473,4 +474,5 @@ int uv__getaddrinfo_translate_error(int sys_err) {
|
||||
}
|
||||
assert(!"unknown EAI_* error code");
|
||||
abort();
|
||||
return 0; /* Pacify compiler. */
|
||||
}
|
||||
|
10
deps/uv/src/uv-common.h
vendored
10
deps/uv/src/uv-common.h
vendored
@ -40,21 +40,11 @@
|
||||
#include "tree.h"
|
||||
#include "queue.h"
|
||||
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||
|
||||
#define container_of(ptr, type, member) \
|
||||
((type *) ((char *) (ptr) - offsetof(type, member)))
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# define UNUSED /* empty */
|
||||
# define INLINE __inline
|
||||
#else
|
||||
# define UNUSED __attribute__((unused))
|
||||
# define INLINE inline
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef _WIN32
|
||||
enum {
|
||||
UV__HANDLE_INTERNAL = 0x8000,
|
||||
|
2
deps/uv/src/version.c
vendored
2
deps/uv/src/version.c
vendored
@ -31,7 +31,7 @@
|
||||
|
||||
#define UV_VERSION_MAJOR 0
|
||||
#define UV_VERSION_MINOR 11
|
||||
#define UV_VERSION_PATCH 7
|
||||
#define UV_VERSION_PATCH 8
|
||||
#define UV_VERSION_IS_RELEASE 1
|
||||
|
||||
|
||||
|
6
deps/uv/src/win/async.c
vendored
6
deps/uv/src/win/async.c
vendored
@ -91,9 +91,9 @@ void uv_process_async_wakeup_req(uv_loop_t* loop, uv_async_t* handle,
|
||||
|
||||
handle->async_sent = 0;
|
||||
|
||||
if (!(handle->flags & UV__HANDLE_CLOSING)) {
|
||||
handle->async_cb((uv_async_t*) handle, 0);
|
||||
} else {
|
||||
if (handle->flags & UV__HANDLE_CLOSING) {
|
||||
uv_want_endgame(loop, (uv_handle_t*)handle);
|
||||
} else if (handle->async_cb != NULL) {
|
||||
handle->async_cb(handle, 0);
|
||||
}
|
||||
}
|
||||
|
5
deps/uv/src/win/internal.h
vendored
5
deps/uv/src/win/internal.h
vendored
@ -29,6 +29,11 @@
|
||||
#include "winapi.h"
|
||||
#include "winsock.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# define INLINE __inline
|
||||
#else
|
||||
# define INLINE inline
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Handles
|
||||
|
2
deps/uv/src/win/tcp.c
vendored
2
deps/uv/src/win/tcp.c
vendored
@ -436,7 +436,7 @@ static void uv_tcp_queue_read(uv_loop_t* loop, uv_tcp_t* handle) {
|
||||
handle->flags &= ~UV_HANDLE_ZERO_READ;
|
||||
handle->read_buffer = handle->alloc_cb((uv_handle_t*) handle, 65536);
|
||||
if (handle->read_buffer.len == 0) {
|
||||
handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, buf);
|
||||
handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, handle->read_buffer);
|
||||
return;
|
||||
}
|
||||
assert(handle->read_buffer.base != NULL);
|
||||
|
55
deps/uv/test/test-async-null-cb.c
vendored
Normal file
55
deps/uv/test/test-async-null-cb.c
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "uv.h"
|
||||
#include "task.h"
|
||||
|
||||
static uv_async_t async_handle;
|
||||
static uv_check_t check_handle;
|
||||
static int check_cb_called;
|
||||
static uv_thread_t thread;
|
||||
|
||||
|
||||
static void thread_cb(void* dummy) {
|
||||
(void) &dummy;
|
||||
uv_async_send(&async_handle);
|
||||
}
|
||||
|
||||
|
||||
static void check_cb(uv_check_t* handle, int status) {
|
||||
ASSERT(check_cb_called == 0);
|
||||
uv_close((uv_handle_t*) &async_handle, NULL);
|
||||
uv_close((uv_handle_t*) &check_handle, NULL);
|
||||
check_cb_called++;
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(async_null_cb) {
|
||||
ASSERT(0 == uv_async_init(uv_default_loop(), &async_handle, NULL));
|
||||
ASSERT(0 == uv_check_init(uv_default_loop(), &check_handle));
|
||||
ASSERT(0 == uv_check_start(&check_handle, check_cb));
|
||||
ASSERT(0 == uv_thread_create(&thread, thread_cb, NULL));
|
||||
ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
|
||||
ASSERT(0 == uv_thread_join(&thread));
|
||||
ASSERT(1 == check_cb_called);
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
}
|
102
deps/uv/test/test-ip6-addr.c
vendored
102
deps/uv/test/test-ip6-addr.c
vendored
@ -30,72 +30,68 @@
|
||||
# include <net/if.h>
|
||||
#endif
|
||||
|
||||
typedef void (*iface_info_cb)(const char* ip6_addr, const char* device_name,
|
||||
unsigned iface_index);
|
||||
|
||||
void call_iface_info_cb(iface_info_cb iface_cb,
|
||||
char const* iface_name,
|
||||
struct sockaddr_in6 const* address) {
|
||||
TEST_IMPL(ip6_addr_link_local) {
|
||||
#ifdef UV_PLATFORM_HAS_IP6_LINK_LOCAL_ADDRESS
|
||||
char string_address[INET6_ADDRSTRLEN];
|
||||
|
||||
ASSERT(0 == uv_inet_ntop(AF_INET6,
|
||||
&address->sin6_addr,
|
||||
string_address,
|
||||
INET6_ADDRSTRLEN));
|
||||
iface_cb(string_address, iface_name, address->sin6_scope_id);
|
||||
}
|
||||
|
||||
|
||||
void foreach_ip6_interface(iface_info_cb iface_cb) {
|
||||
int count, ix;
|
||||
uv_interface_address_t* addresses;
|
||||
uv_interface_address_t* address;
|
||||
struct sockaddr_in6 addr;
|
||||
unsigned int iface_index;
|
||||
const char* device_name;
|
||||
/* 40 bytes address, 16 bytes device name, plus reserve. */
|
||||
char scoped_addr[128];
|
||||
int count;
|
||||
int ix;
|
||||
|
||||
ASSERT(0 == uv_interface_addresses(&addresses, &count));
|
||||
|
||||
for (ix = 0; ix < count; ix++) {
|
||||
if (addresses[ix].address.address4.sin_family != AF_INET6)
|
||||
address = addresses + ix;
|
||||
|
||||
if (address->address.address6.sin6_family != AF_INET6)
|
||||
continue;
|
||||
|
||||
call_iface_info_cb(iface_cb,
|
||||
addresses[ix].name,
|
||||
&addresses[ix].address.address6);
|
||||
ASSERT(0 == uv_inet_ntop(AF_INET6,
|
||||
&address->address.address6.sin6_addr,
|
||||
string_address,
|
||||
sizeof(string_address)));
|
||||
|
||||
/* Skip addresses that are not link-local. */
|
||||
if (strncmp(string_address, "fe80::", 6) != 0)
|
||||
continue;
|
||||
|
||||
iface_index = address->address.address6.sin6_scope_id;
|
||||
device_name = address->name;
|
||||
|
||||
#ifdef _WIN32
|
||||
snprintf(scoped_addr,
|
||||
sizeof(scoped_addr),
|
||||
"%s%%%d",
|
||||
string_address,
|
||||
iface_index);
|
||||
#else
|
||||
snprintf(scoped_addr,
|
||||
sizeof(scoped_addr),
|
||||
"%s%%%s",
|
||||
string_address,
|
||||
device_name);
|
||||
#endif
|
||||
|
||||
LOGF("Testing link-local address %s "
|
||||
"(iface_index: 0x%02x, device_name: %s)\n",
|
||||
scoped_addr,
|
||||
iface_index,
|
||||
device_name);
|
||||
|
||||
addr = uv_ip6_addr(scoped_addr, TEST_PORT);
|
||||
LOGF("Got scope_id 0x%02x\n", addr.sin6_scope_id);
|
||||
ASSERT(iface_index == addr.sin6_scope_id);
|
||||
}
|
||||
|
||||
uv_free_interface_addresses(addresses, count);
|
||||
}
|
||||
|
||||
|
||||
void test_ip6_addr_scope(const char* ip6_addr,
|
||||
const char* device_name,
|
||||
unsigned iface_index) {
|
||||
/* 40 bytes address, 16 bytes device name, plus reserve */
|
||||
char scoped_addr[128];
|
||||
struct sockaddr_in6 addr;
|
||||
|
||||
/* skip addresses that are not link-local */
|
||||
if (strncmp(ip6_addr, "fe80::", 6) != 0) return;
|
||||
|
||||
#ifdef _WIN32
|
||||
snprintf(scoped_addr, sizeof(scoped_addr), "%s%%%d", ip6_addr, iface_index);
|
||||
#else
|
||||
snprintf(scoped_addr, sizeof(scoped_addr), "%s%%%s", ip6_addr, device_name);
|
||||
#endif
|
||||
|
||||
LOGF("Testing link-local address %s (iface_index: 0x%02x, device_name: %s)\n",
|
||||
scoped_addr,
|
||||
iface_index,
|
||||
device_name);
|
||||
|
||||
addr = uv_ip6_addr(scoped_addr, TEST_PORT);
|
||||
|
||||
LOGF("Got scope_id 0x%02x\n", addr.sin6_scope_id);
|
||||
ASSERT(iface_index == addr.sin6_scope_id);
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(ip6_addr_link_local) {
|
||||
#ifdef UV_PLATFORM_HAS_IP6_LINK_LOCAL_ADDRESS
|
||||
foreach_ip6_interface(&test_ip6_addr_scope);
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
#else
|
||||
RETURN_SKIP("Qualified link-local addresses are not supported.");
|
||||
|
2
deps/uv/test/test-list.h
vendored
2
deps/uv/test/test-list.h
vendored
@ -134,6 +134,7 @@ TEST_DECLARE (has_ref)
|
||||
TEST_DECLARE (active)
|
||||
TEST_DECLARE (embed)
|
||||
TEST_DECLARE (async)
|
||||
TEST_DECLARE (async_null_cb)
|
||||
TEST_DECLARE (get_currentexe)
|
||||
TEST_DECLARE (process_title)
|
||||
TEST_DECLARE (cwd_and_chdir)
|
||||
@ -396,6 +397,7 @@ TASK_LIST_START
|
||||
TEST_ENTRY (embed)
|
||||
|
||||
TEST_ENTRY (async)
|
||||
TEST_ENTRY (async_null_cb)
|
||||
|
||||
TEST_ENTRY (get_currentexe)
|
||||
|
||||
|
1
deps/uv/uv.gyp
vendored
1
deps/uv/uv.gyp
vendored
@ -302,6 +302,7 @@
|
||||
'test/test-util.c',
|
||||
'test/test-active.c',
|
||||
'test/test-async.c',
|
||||
'test/test-async-null-cb.c',
|
||||
'test/test-callback-stack.c',
|
||||
'test/test-callback-order.c',
|
||||
'test/test-connection-fail.c',
|
||||
|
Loading…
x
Reference in New Issue
Block a user