7789 lines
221 KiB
Diff
7789 lines
221 KiB
Diff
From 3307fabda302b693acbec3a9f11b6542428d5b96 Mon Sep 17 00:00:00 2001
|
|
From: Simon Piriou <spiriou31@gmail.com>
|
|
Date: Fri, 7 Aug 2020 19:48:02 +0200
|
|
Subject: [PATCH] initial libuv port to nuttx
|
|
|
|
---
|
|
include/uv.h | 109 ++-
|
|
include/uv/nuttx.h | 67 ++
|
|
include/uv/unix.h | 155 +++-
|
|
src/inet.c | 50 +-
|
|
src/queue.h | 4 +-
|
|
src/random.c | 42 +-
|
|
src/unix/async.c | 71 +-
|
|
src/unix/core.c | 209 +++++-
|
|
src/unix/fs.c | 77 +-
|
|
src/unix/internal.h | 32 +-
|
|
src/unix/loop.c | 98 ++-
|
|
src/unix/no-proctitle.c | 28 +
|
|
src/unix/nuttx.c | 238 +++++++
|
|
src/unix/nuttx_stream.c | 1016 +++++++++++++++++++++++++++
|
|
src/unix/nuttx_tcp.c | 311 ++++++++
|
|
src/unix/nuttx_threadpool.c | 361 ++++++++++
|
|
src/unix/nuttx_timer.c | 199 ++++++
|
|
src/unix/pipe.c | 24 +-
|
|
src/unix/poll.c | 26 +
|
|
src/unix/process.c | 35 +-
|
|
src/unix/random-devurandom.c | 19 +-
|
|
src/unix/thread.c | 35 +-
|
|
src/uv-common.c | 175 ++++-
|
|
src/uv-common.h | 31 +
|
|
test/echo-server.c | 62 +-
|
|
test/runner.c | 63 +-
|
|
test/runner.h | 28 +-
|
|
test/task.h | 58 +-
|
|
test/test-active.c | 12 +-
|
|
test/test-async.c | 36 +-
|
|
test/test-fs-copyfile.c | 30 +-
|
|
test/test-fs-poll.c | 162 +++--
|
|
test/test-idle.c | 20 +-
|
|
test/test-ip4-addr.c | 2 +-
|
|
test/test-list.h | 85 ++-
|
|
test/test-loop-close.c | 13 +-
|
|
test/test-loop-stop.c | 24 +-
|
|
test/test-loop-time.c | 44 +-
|
|
test/test-ping-pong.c | 92 ++-
|
|
test/test-poll-close.c | 16 +-
|
|
test/test-random.c | 23 +-
|
|
test/test-tcp-read-stop.c | 13 +-
|
|
test/test-tcp-write-after-connect.c | 17 +-
|
|
test/test-threadpool.c | 28 +-
|
|
test/test-timer-again.c | 28 +-
|
|
test/test-timer-from-check.c | 21 +-
|
|
test/test-timer.c | 160 +++--
|
|
test/test-walk-handles.c | 8 +-
|
|
48 files changed, 4024 insertions(+), 433 deletions(-)
|
|
create mode 100644 include/uv/nuttx.h
|
|
create mode 100644 src/unix/nuttx.c
|
|
create mode 100644 src/unix/nuttx_stream.c
|
|
create mode 100644 src/unix/nuttx_tcp.c
|
|
create mode 100644 src/unix/nuttx_threadpool.c
|
|
create mode 100644 src/unix/nuttx_timer.c
|
|
|
|
diff --git a/include/uv.h b/include/uv.h
|
|
index fec663136..d025e8a0b 100644
|
|
--- a/include/uv.h
|
|
+++ b/include/uv.h
|
|
@@ -1,3 +1,23 @@
|
|
+/****************************************************************************
|
|
+ * include/uv.h
|
|
+ *
|
|
+ * Licensed to the Apache Software Foundation (ASF) under one or more
|
|
+ * contributor license agreements. See the NOTICE file distributed with
|
|
+ * this work for additional information regarding copyright ownership. The
|
|
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
+ * "License"); you may not use this file except in compliance with the
|
|
+ * License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
+ * License for the specific language governing permissions and limitations
|
|
+ * under the License.
|
|
+ *
|
|
+ ****************************************************************************/
|
|
+
|
|
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
@@ -23,6 +43,12 @@
|
|
|
|
#ifndef UV_H
|
|
#define UV_H
|
|
+
|
|
+/* FIXME hack to enable NuttX build target */
|
|
+#ifndef __NUTTX__
|
|
+#define __NUTTX__ 1
|
|
+#endif
|
|
+
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
@@ -265,22 +291,46 @@ typedef void* (*uv_realloc_func)(void* ptr, size_t size);
|
|
typedef void* (*uv_calloc_func)(size_t count, size_t size);
|
|
typedef void (*uv_free_func)(void* ptr);
|
|
|
|
-UV_EXTERN void uv_library_shutdown(void);
|
|
+#ifdef CONFIG_LIBUV_CONTEXT
|
|
+struct uv_context_s;
|
|
+typedef struct uv_context_s uv_context_t;
|
|
|
|
-UV_EXTERN int uv_replace_allocator(uv_malloc_func malloc_func,
|
|
- uv_realloc_func realloc_func,
|
|
- uv_calloc_func calloc_func,
|
|
- uv_free_func free_func);
|
|
+UV_EXTERN void uv_library_init(uv_context_t* ctx);
|
|
+UV_EXTERN void uv_library_shutdown(uv_context_t* ctx);
|
|
+
|
|
+UV_EXTERN uv_loop_t* uv_default_loop(uv_context_t *ctx);
|
|
+UV_EXTERN int uv_loop_init(uv_loop_t* loop, uv_context_t* ctx);
|
|
+
|
|
+/*
|
|
+ * NOTE:
|
|
+ * This function is DEPRECATED (to be removed after 0.12), users should
|
|
+ * allocate the loop manually and use uv_loop_init instead.
|
|
+ */
|
|
+UV_EXTERN uv_loop_t* uv_loop_new(uv_context_t *ctx);
|
|
+
|
|
+#else /* CONFIG_LIBUV_CONTEXT */
|
|
+
|
|
+UV_EXTERN void uv_library_shutdown(void);
|
|
|
|
UV_EXTERN uv_loop_t* uv_default_loop(void);
|
|
UV_EXTERN int uv_loop_init(uv_loop_t* loop);
|
|
-UV_EXTERN int uv_loop_close(uv_loop_t* loop);
|
|
+
|
|
/*
|
|
* NOTE:
|
|
* This function is DEPRECATED (to be removed after 0.12), users should
|
|
* allocate the loop manually and use uv_loop_init instead.
|
|
*/
|
|
UV_EXTERN uv_loop_t* uv_loop_new(void);
|
|
+
|
|
+#endif
|
|
+
|
|
+UV_EXTERN int uv_replace_allocator(uv_malloc_func malloc_func,
|
|
+ uv_realloc_func realloc_func,
|
|
+ uv_calloc_func calloc_func,
|
|
+ uv_free_func free_func);
|
|
+
|
|
+UV_EXTERN int uv_loop_close(uv_loop_t* loop);
|
|
+
|
|
/*
|
|
* NOTE:
|
|
* This function is DEPRECATED (to be removed after 0.12). Users should use
|
|
@@ -300,7 +350,7 @@ UV_EXTERN void uv_unref(uv_handle_t*);
|
|
UV_EXTERN int uv_has_ref(const uv_handle_t*);
|
|
|
|
UV_EXTERN void uv_update_time(uv_loop_t*);
|
|
-UV_EXTERN uint64_t uv_now(const uv_loop_t*);
|
|
+UV_EXTERN uv_time_t uv_now(const uv_loop_t*);
|
|
|
|
UV_EXTERN int uv_backend_fd(const uv_loop_t*);
|
|
UV_EXTERN int uv_backend_timeout(const uv_loop_t*);
|
|
@@ -399,7 +449,6 @@ UV_EXTERN char* uv_err_name_r(int err, char* buf, size_t buflen);
|
|
/* read-only */ \
|
|
uv_req_type type; \
|
|
/* private */ \
|
|
- void* reserved[6]; \
|
|
UV_REQ_PRIVATE_FIELDS \
|
|
|
|
/* Abstract base class of all requests. */
|
|
@@ -423,7 +472,7 @@ struct uv_shutdown_s {
|
|
UV_SHUTDOWN_PRIVATE_FIELDS
|
|
};
|
|
|
|
-
|
|
+#ifndef CONFIG_LIBUV_LOW_FOOTPRINT
|
|
#define UV_HANDLE_FIELDS \
|
|
/* public */ \
|
|
void* data; \
|
|
@@ -439,6 +488,20 @@ struct uv_shutdown_s {
|
|
} u; \
|
|
UV_HANDLE_PRIVATE_FIELDS \
|
|
|
|
+#else
|
|
+#define UV_HANDLE_FIELDS \
|
|
+ /* public */ \
|
|
+ void* data; \
|
|
+ /* read-only */ \
|
|
+ uv_loop_t* loop; \
|
|
+ uv_handle_type type; \
|
|
+ /* private */ \
|
|
+ uv_close_cb close_cb; \
|
|
+ void* handle_queue[2]; \
|
|
+ UV_HANDLE_PRIVATE_FIELDS \
|
|
+
|
|
+#endif
|
|
+
|
|
/* The abstract base class of all handles. */
|
|
struct uv_handle_s {
|
|
UV_HANDLE_FIELDS
|
|
@@ -857,12 +920,12 @@ struct uv_timer_s {
|
|
UV_EXTERN int uv_timer_init(uv_loop_t*, uv_timer_t* handle);
|
|
UV_EXTERN int uv_timer_start(uv_timer_t* handle,
|
|
uv_timer_cb cb,
|
|
- uint64_t timeout,
|
|
- uint64_t repeat);
|
|
+ uv_interval_t timeout,
|
|
+ uv_interval_t repeat);
|
|
UV_EXTERN int uv_timer_stop(uv_timer_t* handle);
|
|
UV_EXTERN int uv_timer_again(uv_timer_t* handle);
|
|
-UV_EXTERN void uv_timer_set_repeat(uv_timer_t* handle, uint64_t repeat);
|
|
-UV_EXTERN uint64_t uv_timer_get_repeat(const uv_timer_t* handle);
|
|
+UV_EXTERN void uv_timer_set_repeat(uv_timer_t* handle, uv_interval_t repeat);
|
|
+UV_EXTERN uv_interval_t uv_timer_get_repeat(const uv_timer_t* handle);
|
|
|
|
|
|
/*
|
|
@@ -1770,6 +1833,10 @@ union uv_any_req {
|
|
struct uv_loop_s {
|
|
/* User data - use this for whatever. */
|
|
void* data;
|
|
+#ifdef CONFIG_LIBUV_CONTEXT
|
|
+ uv_context_t *context;
|
|
+#endif
|
|
+#ifndef CONFIG_LIBUV_LOW_FOOTPRINT
|
|
/* Loop reference counting. */
|
|
unsigned int active_handles;
|
|
void* handle_queue[2];
|
|
@@ -1779,12 +1846,28 @@ struct uv_loop_s {
|
|
} active_reqs;
|
|
/* Internal flag to signal loop stop. */
|
|
unsigned int stop_flag;
|
|
+#else
|
|
+ void* handle_queue[2];
|
|
+ union {
|
|
+ uint8_t count;
|
|
+ } active_reqs;
|
|
+ /* Loop reference counting. */
|
|
+ uint8_t active_handles;
|
|
+ /* Internal flag to signal loop stop. */
|
|
+ uint8_t stop_flag;
|
|
+#endif
|
|
UV_LOOP_PRIVATE_FIELDS
|
|
};
|
|
|
|
UV_EXTERN void* uv_loop_get_data(const uv_loop_t*);
|
|
UV_EXTERN void uv_loop_set_data(uv_loop_t*, void* data);
|
|
|
|
+#ifdef CONFIG_LIBUV_CONTEXT
|
|
+struct uv_context_s {
|
|
+ UV_PLATFORM_CONTEXT_FIELDS
|
|
+};
|
|
+#endif
|
|
+
|
|
/* Don't export the private CPP symbols. */
|
|
#undef UV_HANDLE_TYPE_PRIVATE
|
|
#undef UV_REQ_TYPE_PRIVATE
|
|
diff --git a/include/uv/nuttx.h b/include/uv/nuttx.h
|
|
new file mode 100644
|
|
index 000000000..62574f93b
|
|
--- /dev/null
|
|
+++ b/include/uv/nuttx.h
|
|
@@ -0,0 +1,67 @@
|
|
+/****************************************************************************
|
|
+ * libs/libuv/include/uv/nuttx.h
|
|
+ *
|
|
+ * Licensed to the Apache Software Foundation (ASF) under one or more
|
|
+ * contributor license agreements. See the NOTICE file distributed with
|
|
+ * this work for additional information regarding copyright ownership. The
|
|
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
+ * "License"); you may not use this file except in compliance with the
|
|
+ * License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
+ * License for the specific language governing permissions and limitations
|
|
+ * under the License.
|
|
+ *
|
|
+ ****************************************************************************/
|
|
+
|
|
+#ifndef UV_NUTTX_H
|
|
+#define UV_NUTTX_H
|
|
+
|
|
+#include <nuttx/config.h>
|
|
+#include <poll.h>
|
|
+
|
|
+#ifdef CONFIG_LIBUV_WQ
|
|
+typedef struct uv_wq_context_s {
|
|
+#ifndef CONFIG_LIBUV_CONTEXT
|
|
+ pthread_once_t once;
|
|
+#endif
|
|
+ pthread_cond_t cond;
|
|
+ pthread_mutex_t mutex;
|
|
+ unsigned int idle_threads;
|
|
+ pthread_t default_threads[CONFIG_LIBUV_WQ_THREADS_COUNT];
|
|
+ void *exit_message[2];
|
|
+ void *wq[2];
|
|
+} uv_wq_context_t;
|
|
+#endif
|
|
+
|
|
+#ifdef CONFIG_LIBUV_TIMER_NUTTX
|
|
+typedef uint32_t uv_time_t;
|
|
+typedef int32_t uv_interval_t;
|
|
+#else
|
|
+typedef uint64_t uv_time_t;
|
|
+typedef uint64_t uv_interval_t;
|
|
+#endif
|
|
+
|
|
+#define UV_PLATFORM_LOOP_FIELDS \
|
|
+ struct pollfd poll_fds[CONFIG_LIBUV_NPOLLWAITERS]; \
|
|
+ size_t poll_fds_used;
|
|
+
|
|
+#ifdef CONFIG_LIBUV_CONTEXT
|
|
+#ifdef CONFIG_LIBUV_WQ
|
|
+#define UV_PLATFORM_CONTEXT_PRIVATE_WQ_FIELDS \
|
|
+ uv_wq_context_t wq;
|
|
+#else
|
|
+#define UV_PLATFORM_CONTEXT_PRIVATE_WQ_FIELDS
|
|
+#endif /* CONFIG_LIBUV_WQ */
|
|
+
|
|
+#define UV_PLATFORM_CONTEXT_FIELDS \
|
|
+ UV_PLATFORM_CONTEXT_PRIVATE_WQ_FIELDS \
|
|
+ uv_loop_t default_loop; \
|
|
+ uv_loop_t *default_loop_ptr;
|
|
+#endif /* CONFIG_LIBUV_CONTEXT */
|
|
+
|
|
+#endif /* UV_NUTTX_H */
|
|
diff --git a/include/uv/unix.h b/include/uv/unix.h
|
|
index 3a131638f..2c56e8a55 100644
|
|
--- a/include/uv/unix.h
|
|
+++ b/include/uv/unix.h
|
|
@@ -1,3 +1,23 @@
|
|
+/****************************************************************************
|
|
+ * include/uv/unix.h
|
|
+ *
|
|
+ * Licensed to the Apache Software Foundation (ASF) under one or more
|
|
+ * contributor license agreements. See the NOTICE file distributed with
|
|
+ * this work for additional information regarding copyright ownership. The
|
|
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
+ * "License"); you may not use this file except in compliance with the
|
|
+ * License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
+ * License for the specific language governing permissions and limitations
|
|
+ * under the License.
|
|
+ *
|
|
+ ****************************************************************************/
|
|
+
|
|
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
@@ -45,7 +65,9 @@
|
|
|
|
#include "uv/threadpool.h"
|
|
|
|
-#if defined(__linux__)
|
|
+#if defined(__NUTTX__)
|
|
+# include "uv/nuttx.h"
|
|
+#elif defined(__linux__)
|
|
# include "uv/linux.h"
|
|
#elif defined (__MVS__)
|
|
# include "uv/os390.h"
|
|
@@ -93,7 +115,8 @@ typedef struct uv__io_s uv__io_t;
|
|
|
|
struct uv__io_s {
|
|
uv__io_cb cb;
|
|
- void* pending_queue[2];
|
|
+ /* FIXME moved in uv_stream_t for now.
|
|
+ * void* pending_queue[2]; */
|
|
void* watcher_queue[2];
|
|
unsigned int pevents; /* Pending event mask i.e. mask at next tick. */
|
|
unsigned int events; /* Current event mask. */
|
|
@@ -218,37 +241,105 @@ typedef struct {
|
|
char* errmsg;
|
|
} uv_lib_t;
|
|
|
|
-#define UV_LOOP_PRIVATE_FIELDS \
|
|
- unsigned long flags; \
|
|
- int backend_fd; \
|
|
- void* pending_queue[2]; \
|
|
- void* watcher_queue[2]; \
|
|
- uv__io_t** watchers; \
|
|
- unsigned int nwatchers; \
|
|
- unsigned int nfds; \
|
|
- void* wq[2]; \
|
|
- uv_mutex_t wq_mutex; \
|
|
- uv_async_t wq_async; \
|
|
- uv_rwlock_t cloexec_lock; \
|
|
- uv_handle_t* closing_handles; \
|
|
+#ifdef CONFIG_LIBUV_SIGNAL
|
|
+#define UV_LOOP_PRIVATE_SIGNAL_FIELDS \
|
|
+ int signal_pipefd[2]; \
|
|
+ uv__io_t signal_io_watcher;
|
|
+#else
|
|
+#define UV_LOOP_PRIVATE_SIGNAL_FIELDS
|
|
+#endif
|
|
+
|
|
+#ifdef CONFIG_LIBUV_PROCESS
|
|
+#define UV_LOOP_PRIVATE_PROCESS_FIELDS \
|
|
void* process_handles[2]; \
|
|
- void* prepare_handles[2]; \
|
|
- void* check_handles[2]; \
|
|
- void* idle_handles[2]; \
|
|
+ uv_signal_t child_watcher;
|
|
+#else
|
|
+#define UV_LOOP_PRIVATE_PROCESS_FIELDS
|
|
+#endif
|
|
+
|
|
+#ifdef CONFIG_LIBUV_ASYNC
|
|
+#ifndef CONFIG_LIBUV_LOW_FOOTPRINT
|
|
+#define UV_LOOP_PRIVATE_ASYNC_FIELDS \
|
|
void* async_handles[2]; \
|
|
void (*async_unused)(void); /* TODO(bnoordhuis) Remove in libuv v2. */ \
|
|
uv__io_t async_io_watcher; \
|
|
- int async_wfd; \
|
|
+ int async_wfd;
|
|
+#else
|
|
+#define UV_LOOP_PRIVATE_ASYNC_FIELDS \
|
|
+ void* async_handles[2]; \
|
|
+ uv__io_t async_io_watcher;
|
|
+#endif /* CONFIG_LIBUV_LOW_FOOTPRINT */
|
|
+#else
|
|
+#define UV_LOOP_PRIVATE_ASYNC_FIELDS
|
|
+#endif
|
|
+
|
|
+#ifdef CONFIG_LIBUV_TIMER
|
|
+#ifdef CONFIG_LIBUV_TIMER_NUTTX
|
|
+#define UV_LOOP_PRIVATE_TIMER_FIELDS \
|
|
+ uv_timer_t *timer_head;
|
|
+#else
|
|
+#define UV_LOOP_PRIVATE_TIMER_FIELDS \
|
|
struct { \
|
|
void* min; \
|
|
unsigned int nelts; \
|
|
} timer_heap; \
|
|
- uint64_t timer_counter; \
|
|
- uint64_t time; \
|
|
- int signal_pipefd[2]; \
|
|
- uv__io_t signal_io_watcher; \
|
|
- uv_signal_t child_watcher; \
|
|
+ uint64_t timer_counter;
|
|
+#endif
|
|
+#else
|
|
+#define UV_LOOP_PRIVATE_TIMER_FIELDS
|
|
+#endif
|
|
+
|
|
+#ifdef CONFIG_LIBUV_WQ
|
|
+#define UV_LOOP_PRIVATE_WQ_FIELDS \
|
|
+ void* wq[2]; \
|
|
+ uv_mutex_t wq_mutex; \
|
|
+ uv_async_t wq_async;
|
|
+#else
|
|
+#define UV_LOOP_PRIVATE_WQ_FIELDS
|
|
+#endif
|
|
+
|
|
+#ifdef CONFIG_LIBUV_LOOP_WATCHERS
|
|
+#define UV_LOOP_PRIVATE_WATCHERS_FIELDS \
|
|
+ void* prepare_handles[2]; \
|
|
+ void* check_handles[2]; \
|
|
+ void* idle_handles[2];
|
|
+#else
|
|
+#define UV_LOOP_PRIVATE_WATCHERS_FIELDS
|
|
+#endif
|
|
+
|
|
+#ifdef CONFIG_LIBUV_LOW_FOOTPRINT
|
|
+#define UV_LOOP_PRIVATE_PERFS_FIELDS
|
|
+#else
|
|
+#define UV_LOOP_PRIVATE_PERFS_FIELDS \
|
|
+ unsigned long flags; \
|
|
+ int backend_fd; \
|
|
+ uv_rwlock_t cloexec_lock; \
|
|
int emfile_fd; \
|
|
+ uv__io_t** watchers; \
|
|
+ unsigned int nwatchers; \
|
|
+ unsigned int nfds;
|
|
+#endif
|
|
+
|
|
+#ifdef CONFIG_LIBUV_STREAM
|
|
+/* FIXME pending_queue is only required for uv_streams for now */
|
|
+#define UV_LOOP_PRIVATE_STREAM_FIELDS \
|
|
+ void* pending_queue[2];
|
|
+#else
|
|
+#define UV_LOOP_PRIVATE_STREAM_FIELDS
|
|
+#endif
|
|
+
|
|
+#define UV_LOOP_PRIVATE_FIELDS \
|
|
+ void* watcher_queue[2]; \
|
|
+ UV_LOOP_PRIVATE_WQ_FIELDS \
|
|
+ uv_handle_t* closing_handles; \
|
|
+ UV_LOOP_PRIVATE_WATCHERS_FIELDS \
|
|
+ UV_LOOP_PRIVATE_ASYNC_FIELDS \
|
|
+ UV_LOOP_PRIVATE_TIMER_FIELDS \
|
|
+ uv_time_t time; \
|
|
+ UV_LOOP_PRIVATE_SIGNAL_FIELDS \
|
|
+ UV_LOOP_PRIVATE_PROCESS_FIELDS \
|
|
+ UV_LOOP_PRIVATE_STREAM_FIELDS \
|
|
+ UV_LOOP_PRIVATE_PERFS_FIELDS \
|
|
UV_PLATFORM_LOOP_FIELDS \
|
|
|
|
#define UV_REQ_TYPE_PRIVATE /* empty */
|
|
@@ -289,10 +380,10 @@ typedef struct {
|
|
uv__io_t io_watcher; \
|
|
void* write_queue[2]; \
|
|
void* write_completed_queue[2]; \
|
|
+ void* pending_queue[2]; \
|
|
uv_connection_cb connection_cb; \
|
|
- int delayed_error; \
|
|
+ /*int delayed_error;*/ \
|
|
int accepted_fd; \
|
|
- void* queued_fds; \
|
|
UV_STREAM_PRIVATE_PLATFORM_FIELDS \
|
|
|
|
#define UV_TCP_PRIVATE_FIELDS /* empty */
|
|
@@ -327,12 +418,20 @@ typedef struct {
|
|
void* queue[2]; \
|
|
int pending; \
|
|
|
|
+#ifdef CONFIG_LIBUV_TIMER_NUTTX
|
|
+#define UV_TIMER_PRIVATE_FIELDS \
|
|
+ uv_timer_cb timer_cb; \
|
|
+ struct uv_timer_s *next; \
|
|
+ int32_t timeout; \
|
|
+ int32_t repeat;
|
|
+#else
|
|
#define UV_TIMER_PRIVATE_FIELDS \
|
|
uv_timer_cb timer_cb; \
|
|
void* heap_node[3]; \
|
|
uint64_t timeout; \
|
|
uint64_t repeat; \
|
|
uint64_t start_id;
|
|
+#endif
|
|
|
|
#define UV_GETADDRINFO_PRIVATE_FIELDS \
|
|
struct uv__work work_req; \
|
|
@@ -374,9 +473,13 @@ typedef struct {
|
|
#define UV_WORK_PRIVATE_FIELDS \
|
|
struct uv__work work_req;
|
|
|
|
+#ifdef CONFIG_LIBUV_TTY
|
|
#define UV_TTY_PRIVATE_FIELDS \
|
|
struct termios orig_termios; \
|
|
int mode;
|
|
+#else /* CONFIG_LIBUV_TTY */
|
|
+ #define UV_TTY_PRIVATE_FIELDS
|
|
+#endif /* CONFIG_LIBUV_TTY */
|
|
|
|
#define UV_SIGNAL_PRIVATE_FIELDS \
|
|
/* RB_ENTRY(uv_signal_s) tree_entry; */ \
|
|
diff --git a/src/inet.c b/src/inet.c
|
|
index 698ab232e..63aa2b81b 100644
|
|
--- a/src/inet.c
|
|
+++ b/src/inet.c
|
|
@@ -1,3 +1,23 @@
|
|
+/****************************************************************************
|
|
+ * src/inet.c
|
|
+ *
|
|
+ * Licensed to the Apache Software Foundation (ASF) under one or more
|
|
+ * contributor license agreements. See the NOTICE file distributed with
|
|
+ * this work for additional information regarding copyright ownership. The
|
|
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
+ * "License"); you may not use this file except in compliance with the
|
|
+ * License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
+ * License for the specific language governing permissions and limitations
|
|
+ * under the License.
|
|
+ *
|
|
+ ****************************************************************************/
|
|
+
|
|
/*
|
|
* Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
|
|
* Copyright (c) 1996-1999 by Internet Software Consortium.
|
|
@@ -30,26 +50,33 @@
|
|
#define UV__INET_ADDRSTRLEN 16
|
|
#define UV__INET6_ADDRSTRLEN 46
|
|
|
|
-
|
|
+#ifdef CONFIG_NET_IPv4
|
|
static int inet_ntop4(const unsigned char *src, char *dst, size_t size);
|
|
-static int inet_ntop6(const unsigned char *src, char *dst, size_t size);
|
|
static int inet_pton4(const char *src, unsigned char *dst);
|
|
-static int inet_pton6(const char *src, unsigned char *dst);
|
|
+#endif
|
|
|
|
+#ifdef CONFIG_NET_IPv6
|
|
+static int inet_ntop6(const unsigned char *src, char *dst, size_t size);
|
|
+static int inet_pton6(const char *src, unsigned char *dst);
|
|
+#endif
|
|
|
|
int uv_inet_ntop(int af, const void* src, char* dst, size_t size) {
|
|
switch (af) {
|
|
+#ifdef CONFIG_NET_IPv4
|
|
case AF_INET:
|
|
return (inet_ntop4(src, dst, size));
|
|
+#endif
|
|
+#ifdef CONFIG_NET_IPv6
|
|
case AF_INET6:
|
|
return (inet_ntop6(src, dst, size));
|
|
+#endif
|
|
default:
|
|
return UV_EAFNOSUPPORT;
|
|
}
|
|
/* NOTREACHED */
|
|
}
|
|
|
|
-
|
|
+#ifdef CONFIG_NET_IPv4
|
|
static int inet_ntop4(const unsigned char *src, char *dst, size_t size) {
|
|
static const char fmt[] = "%u.%u.%u.%u";
|
|
char tmp[UV__INET_ADDRSTRLEN];
|
|
@@ -62,8 +89,9 @@ static int inet_ntop4(const unsigned char *src, char *dst, size_t size) {
|
|
uv__strscpy(dst, tmp, size);
|
|
return 0;
|
|
}
|
|
+#endif
|
|
|
|
-
|
|
+#ifdef CONFIG_NET_IPv6
|
|
static int inet_ntop6(const unsigned char *src, char *dst, size_t size) {
|
|
/*
|
|
* Note that int32_t and int16_t need only be "at least" large enough
|
|
@@ -145,15 +173,18 @@ static int inet_ntop6(const unsigned char *src, char *dst, size_t size) {
|
|
return UV_ENOSPC;
|
|
return 0;
|
|
}
|
|
-
|
|
+#endif
|
|
|
|
int uv_inet_pton(int af, const char* src, void* dst) {
|
|
if (src == NULL || dst == NULL)
|
|
return UV_EINVAL;
|
|
|
|
switch (af) {
|
|
+#ifdef CONFIG_NET_IPv4
|
|
case AF_INET:
|
|
return (inet_pton4(src, dst));
|
|
+#endif
|
|
+#ifdef CONFIG_NET_IPv6
|
|
case AF_INET6: {
|
|
int len;
|
|
char tmp[UV__INET6_ADDRSTRLEN], *s, *p;
|
|
@@ -169,13 +200,14 @@ int uv_inet_pton(int af, const char* src, void* dst) {
|
|
}
|
|
return inet_pton6(s, dst);
|
|
}
|
|
+#endif
|
|
default:
|
|
return UV_EAFNOSUPPORT;
|
|
}
|
|
/* NOTREACHED */
|
|
}
|
|
|
|
-
|
|
+#ifdef CONFIG_NET_IPv4
|
|
static int inet_pton4(const char *src, unsigned char *dst) {
|
|
static const char digits[] = "0123456789";
|
|
int saw_digit, octets, ch;
|
|
@@ -213,8 +245,9 @@ static int inet_pton4(const char *src, unsigned char *dst) {
|
|
memcpy(dst, tmp, sizeof(struct in_addr));
|
|
return 0;
|
|
}
|
|
+#endif
|
|
|
|
-
|
|
+#ifdef CONFIG_NET_IPv6
|
|
static int inet_pton6(const char *src, unsigned char *dst) {
|
|
static const char xdigits_l[] = "0123456789abcdef",
|
|
xdigits_u[] = "0123456789ABCDEF";
|
|
@@ -300,3 +333,4 @@ static int inet_pton6(const char *src, unsigned char *dst) {
|
|
memcpy(dst, tmp, sizeof tmp);
|
|
return 0;
|
|
}
|
|
+#endif
|
|
diff --git a/src/queue.h b/src/queue.h
|
|
index ff3540a0a..6fa87975f 100644
|
|
--- a/src/queue.h
|
|
+++ b/src/queue.h
|
|
@@ -74,8 +74,8 @@ typedef void *QUEUE[2];
|
|
if (QUEUE_EMPTY(h)) \
|
|
QUEUE_INIT(n); \
|
|
else { \
|
|
- QUEUE* q = QUEUE_HEAD(h); \
|
|
- QUEUE_SPLIT(h, q, n); \
|
|
+ QUEUE* _q = QUEUE_HEAD(h); \
|
|
+ QUEUE_SPLIT(h, _q, n); \
|
|
} \
|
|
} \
|
|
while (0)
|
|
diff --git a/src/random.c b/src/random.c
|
|
index 491bf7033..26e45b334 100644
|
|
--- a/src/random.c
|
|
+++ b/src/random.c
|
|
@@ -31,6 +31,9 @@
|
|
static int uv__random(void* buf, size_t buflen) {
|
|
int rc;
|
|
|
|
+#ifdef __NUTTX__
|
|
+ rc = uv__random_devurandom(buf, buflen);
|
|
+#else /* __NUTTX__ */
|
|
#if defined(__PASE__)
|
|
rc = uv__random_readpath("/dev/urandom", buf, buflen);
|
|
#elif defined(_AIX)
|
|
@@ -65,11 +68,12 @@ static int uv__random(void* buf, size_t buflen) {
|
|
#else
|
|
rc = uv__random_devurandom(buf, buflen);
|
|
#endif
|
|
+#endif /* __NUTTX__ */
|
|
|
|
return rc;
|
|
}
|
|
|
|
-
|
|
+#ifdef CONFIG_LIBUV_WQ
|
|
static void uv__random_work(struct uv__work* w) {
|
|
uv_random_t* req;
|
|
|
|
@@ -89,7 +93,7 @@ static void uv__random_done(struct uv__work* w, int status) {
|
|
|
|
req->cb(req, status, req->buf, req->buflen);
|
|
}
|
|
-
|
|
+#endif
|
|
|
|
int uv_random(uv_loop_t* loop,
|
|
uv_random_t* req,
|
|
@@ -103,21 +107,23 @@ int uv_random(uv_loop_t* loop,
|
|
if (flags != 0)
|
|
return UV_EINVAL;
|
|
|
|
- if (cb == NULL)
|
|
- return uv__random(buf, buflen);
|
|
-
|
|
- uv__req_init(loop, req, UV_RANDOM);
|
|
- req->loop = loop;
|
|
- req->status = 0;
|
|
- req->cb = cb;
|
|
- req->buf = buf;
|
|
- req->buflen = buflen;
|
|
-
|
|
- uv__work_submit(loop,
|
|
- &req->work_req,
|
|
- UV__WORK_CPU,
|
|
- uv__random_work,
|
|
- uv__random_done);
|
|
+#ifdef CONFIG_LIBUV_WQ
|
|
+ if (cb != NULL) {
|
|
+ uv__req_init(loop, req, UV_RANDOM);
|
|
+ req->loop = loop;
|
|
+ req->status = 0;
|
|
+ req->cb = cb;
|
|
+ req->buf = buf;
|
|
+ req->buflen = buflen;
|
|
+
|
|
+ uv__work_submit(loop,
|
|
+ &req->work_req,
|
|
+ UV__WORK_CPU,
|
|
+ uv__random_work,
|
|
+ uv__random_done);
|
|
+ return 0;
|
|
+ }
|
|
+#endif
|
|
|
|
- return 0;
|
|
+ return uv__random(buf, buflen);
|
|
}
|
|
diff --git a/src/unix/async.c b/src/unix/async.c
|
|
index 5f58fb88d..00b6a858c 100644
|
|
--- a/src/unix/async.c
|
|
+++ b/src/unix/async.c
|
|
@@ -1,3 +1,23 @@
|
|
+/****************************************************************************
|
|
+ * libuv/src/unix/async.c
|
|
+ *
|
|
+ * Licensed to the Apache Software Foundation (ASF) under one or more
|
|
+ * contributor license agreements. See the NOTICE file distributed with
|
|
+ * this work for additional information regarding copyright ownership. The
|
|
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
+ * "License"); you may not use this file except in compliance with the
|
|
+ * License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
+ * License for the specific language governing permissions and limitations
|
|
+ * under the License.
|
|
+ *
|
|
+ ****************************************************************************/
|
|
+
|
|
/* 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
|
|
@@ -34,7 +54,7 @@
|
|
#include <unistd.h>
|
|
#include <sched.h> /* sched_yield() */
|
|
|
|
-#ifdef __linux__
|
|
+#if defined (__linux__) || defined(__NUTTX__)
|
|
#include <sys/eventfd.h>
|
|
#endif
|
|
|
|
@@ -72,14 +92,18 @@ int uv_async_send(uv_async_t* handle) {
|
|
/* Wake up the other thread's event loop. */
|
|
uv__async_send(handle->loop);
|
|
|
|
+#ifdef __NUTTX__
|
|
+ cmpxchgi(&handle->pending, 0, 1);
|
|
+#else
|
|
/* Tell the other thread we're done. */
|
|
if (cmpxchgi(&handle->pending, 1, 2) != 1)
|
|
abort();
|
|
+#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
-
|
|
+#ifndef __NUTTX__
|
|
/* Only call this from the event loop thread. */
|
|
static int uv__async_spin(uv_async_t* handle) {
|
|
int i;
|
|
@@ -110,17 +134,26 @@ static int uv__async_spin(uv_async_t* handle) {
|
|
sched_yield();
|
|
}
|
|
}
|
|
-
|
|
+#endif
|
|
|
|
void uv__async_close(uv_async_t* handle) {
|
|
+#ifdef __NUTTX__
|
|
+ /* FIXME: potential race condition were as fd will not be valid for next uv_async_send.
|
|
+ */
|
|
+#else
|
|
uv__async_spin(handle);
|
|
+#endif
|
|
QUEUE_REMOVE(&handle->queue);
|
|
uv__handle_stop(handle);
|
|
}
|
|
|
|
|
|
static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
|
+#ifdef __NUTTX__
|
|
+ char buf[sizeof(eventfd_t)];
|
|
+#else
|
|
char buf[1024];
|
|
+#endif
|
|
ssize_t r;
|
|
QUEUE queue;
|
|
QUEUE* q;
|
|
@@ -154,7 +187,11 @@ static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
|
QUEUE_REMOVE(q);
|
|
QUEUE_INSERT_TAIL(&loop->async_handles, q);
|
|
|
|
+#ifdef __NUTTX__
|
|
+ if (0 == cmpxchgi(&h->pending, 1, 0))
|
|
+#else
|
|
if (0 == uv__async_spin(h))
|
|
+#endif
|
|
continue; /* Not pending. */
|
|
|
|
if (h->async_cb == NULL)
|
|
@@ -166,11 +203,23 @@ static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
|
|
|
|
|
static void uv__async_send(uv_loop_t* loop) {
|
|
+#ifndef __NUTTX__
|
|
const void* buf;
|
|
ssize_t len;
|
|
int fd;
|
|
+#endif
|
|
int r;
|
|
|
|
+#ifdef __NUTTX__
|
|
+ const eventfd_t val = 1;
|
|
+
|
|
+ do {
|
|
+ r = write(loop->async_io_watcher.fd, &val, sizeof(val));
|
|
+ } while (r == -1 && errno == EINTR);
|
|
+
|
|
+ if (r == sizeof(val))
|
|
+ return;
|
|
+#else
|
|
buf = "";
|
|
len = 1;
|
|
fd = loop->async_wfd;
|
|
@@ -190,6 +239,7 @@ static void uv__async_send(uv_loop_t* loop) {
|
|
|
|
if (r == len)
|
|
return;
|
|
+#endif
|
|
|
|
if (r == -1)
|
|
if (errno == EAGAIN || errno == EWOULDBLOCK)
|
|
@@ -200,12 +250,21 @@ static void uv__async_send(uv_loop_t* loop) {
|
|
|
|
|
|
static int uv__async_start(uv_loop_t* loop) {
|
|
+#ifndef __NUTTX__
|
|
int pipefd[2];
|
|
+#endif
|
|
int err;
|
|
|
|
if (loop->async_io_watcher.fd != -1)
|
|
return 0;
|
|
|
|
+#ifdef __NUTTX__
|
|
+ err = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
|
|
+ if (err < 0)
|
|
+ return UV__ERR(errno);
|
|
+ uv__io_init(&loop->async_io_watcher, uv__async_io, err);
|
|
+ uv__io_start(loop, &loop->async_io_watcher, POLLIN);
|
|
+#else
|
|
#ifdef __linux__
|
|
err = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
|
|
if (err < 0)
|
|
@@ -222,11 +281,12 @@ static int uv__async_start(uv_loop_t* loop) {
|
|
uv__io_init(&loop->async_io_watcher, uv__async_io, pipefd[0]);
|
|
uv__io_start(loop, &loop->async_io_watcher, POLLIN);
|
|
loop->async_wfd = pipefd[1];
|
|
+#endif
|
|
|
|
return 0;
|
|
}
|
|
|
|
-
|
|
+#ifndef __NUTTX__
|
|
int uv__async_fork(uv_loop_t* loop) {
|
|
if (loop->async_io_watcher.fd == -1) /* never started */
|
|
return 0;
|
|
@@ -235,17 +295,20 @@ int uv__async_fork(uv_loop_t* loop) {
|
|
|
|
return uv__async_start(loop);
|
|
}
|
|
+#endif
|
|
|
|
|
|
void uv__async_stop(uv_loop_t* loop) {
|
|
if (loop->async_io_watcher.fd == -1)
|
|
return;
|
|
|
|
+#ifndef __NUTTX__
|
|
if (loop->async_wfd != -1) {
|
|
if (loop->async_wfd != loop->async_io_watcher.fd)
|
|
uv__close(loop->async_wfd);
|
|
loop->async_wfd = -1;
|
|
}
|
|
+#endif
|
|
|
|
uv__io_stop(loop, &loop->async_io_watcher, POLLIN);
|
|
uv__close(loop->async_io_watcher.fd);
|
|
diff --git a/src/unix/core.c b/src/unix/core.c
|
|
index 5b0b64dd4..237a6b1bb 100644
|
|
--- a/src/unix/core.c
|
|
+++ b/src/unix/core.c
|
|
@@ -1,3 +1,23 @@
|
|
+/****************************************************************************
|
|
+ * src/unix/core.c
|
|
+ *
|
|
+ * Licensed to the Apache Software Foundation (ASF) under one or more
|
|
+ * contributor license agreements. See the NOTICE file distributed with
|
|
+ * this work for additional information regarding copyright ownership. The
|
|
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
+ * "License"); you may not use this file except in compliance with the
|
|
+ * License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
+ * License for the specific language governing permissions and limitations
|
|
+ * under the License.
|
|
+ *
|
|
+ ****************************************************************************/
|
|
+
|
|
/* 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
|
|
@@ -58,11 +78,14 @@
|
|
# include <crt_externs.h>
|
|
# include <mach-o/dyld.h> /* _NSGetExecutablePath */
|
|
# define environ (*_NSGetEnviron())
|
|
+#elif defined(__NUTTX__)
|
|
+/* environ defined as function in stdlib in NuttX*/
|
|
#else /* defined(__APPLE__) && !TARGET_OS_IPHONE */
|
|
extern char** environ;
|
|
#endif /* !(defined(__APPLE__) && !TARGET_OS_IPHONE) */
|
|
|
|
|
|
+#if 0
|
|
#if defined(__DragonFly__) || \
|
|
defined(__FreeBSD__) || \
|
|
defined(__FreeBSD_kernel__) || \
|
|
@@ -87,8 +110,11 @@ extern char** environ;
|
|
# include <sys/syscall.h>
|
|
# define uv__accept4 accept4
|
|
#endif
|
|
+#endif
|
|
|
|
+#ifdef CONFIG_LIBUV_STREAM
|
|
static int uv__run_pending(uv_loop_t* loop);
|
|
+#endif
|
|
|
|
/* Verify that uv_buf_t is ABI-compatible with struct iovec. */
|
|
STATIC_ASSERT(sizeof(uv_buf_t) == sizeof(struct iovec));
|
|
@@ -112,22 +138,31 @@ void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
|
|
handle->close_cb = close_cb;
|
|
|
|
switch (handle->type) {
|
|
+#ifdef CONFIG_LIBUV_PIPE
|
|
case UV_NAMED_PIPE:
|
|
uv__pipe_close((uv_pipe_t*)handle);
|
|
break;
|
|
+#endif
|
|
|
|
+#if 0
|
|
case UV_TTY:
|
|
uv__stream_close((uv_stream_t*)handle);
|
|
break;
|
|
+#endif
|
|
|
|
+#ifdef CONFIG_LIBUV_TCP
|
|
case UV_TCP:
|
|
uv__tcp_close((uv_tcp_t*)handle);
|
|
break;
|
|
+#endif
|
|
|
|
+#ifdef CONFIG_LIBUV_UDP
|
|
case UV_UDP:
|
|
uv__udp_close((uv_udp_t*)handle);
|
|
break;
|
|
+#endif
|
|
|
|
+#ifdef CONFIG_LIBUV_LOOP_WATCHERS
|
|
case UV_PREPARE:
|
|
uv__prepare_close((uv_prepare_t*)handle);
|
|
break;
|
|
@@ -139,15 +174,20 @@ void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
|
|
case UV_IDLE:
|
|
uv__idle_close((uv_idle_t*)handle);
|
|
break;
|
|
+#endif
|
|
|
|
+#ifdef CONFIG_LIBUV_ASYNC
|
|
case UV_ASYNC:
|
|
uv__async_close((uv_async_t*)handle);
|
|
break;
|
|
+#endif
|
|
|
|
+#ifdef CONFIG_LIBUV_TIMER
|
|
case UV_TIMER:
|
|
uv__timer_close((uv_timer_t*)handle);
|
|
break;
|
|
-
|
|
+#endif
|
|
+#if 0
|
|
case UV_PROCESS:
|
|
uv__process_close((uv_process_t*)handle);
|
|
break;
|
|
@@ -155,21 +195,24 @@ void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
|
|
case UV_FS_EVENT:
|
|
uv__fs_event_close((uv_fs_event_t*)handle);
|
|
break;
|
|
-
|
|
+#endif
|
|
case UV_POLL:
|
|
uv__poll_close((uv_poll_t*)handle);
|
|
break;
|
|
|
|
+#ifdef CONFIG_LIBUV_FS_POLL
|
|
case UV_FS_POLL:
|
|
uv__fs_poll_close((uv_fs_poll_t*)handle);
|
|
/* Poll handles use file system requests, and one of them may still be
|
|
* running. The poll code will call uv__make_close_pending() for us. */
|
|
return;
|
|
+#endif
|
|
|
|
+#ifdef CONFIG_LIBUV_SIGNAL
|
|
case UV_SIGNAL:
|
|
uv__signal_close((uv_signal_t*) handle);
|
|
break;
|
|
-
|
|
+#endif
|
|
default:
|
|
assert(0);
|
|
}
|
|
@@ -177,6 +220,7 @@ void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
|
|
uv__make_close_pending(handle);
|
|
}
|
|
|
|
+#if 0
|
|
int uv__socket_sockopt(uv_handle_t* handle, int optname, int* value) {
|
|
int r;
|
|
int fd;
|
|
@@ -204,6 +248,7 @@ int uv__socket_sockopt(uv_handle_t* handle, int optname, int* value) {
|
|
|
|
return 0;
|
|
}
|
|
+#endif
|
|
|
|
void uv__make_close_pending(uv_handle_t* handle) {
|
|
assert(handle->flags & UV_HANDLE_CLOSING);
|
|
@@ -241,7 +286,9 @@ int uv__getiovmax(void) {
|
|
|
|
|
|
static void uv__finish_close(uv_handle_t* handle) {
|
|
+#ifdef CONFIG_LIBUV_SIGNAL
|
|
uv_signal_t* sh;
|
|
+#endif
|
|
|
|
/* Note: while the handle is in the UV_HANDLE_CLOSING state now, it's still
|
|
* possible for it to be active in the sense that uv__is_active() returns
|
|
@@ -256,17 +303,28 @@ static void uv__finish_close(uv_handle_t* handle) {
|
|
handle->flags |= UV_HANDLE_CLOSED;
|
|
|
|
switch (handle->type) {
|
|
+#ifdef CONFIG_LIBUV_LOOP_WATCHERS
|
|
case UV_PREPARE:
|
|
case UV_CHECK:
|
|
case UV_IDLE:
|
|
+#endif
|
|
+#ifdef CONFIG_LIBUV_ASYNC
|
|
case UV_ASYNC:
|
|
+#endif
|
|
+#ifdef CONFIG_LIBUV_TIMER
|
|
case UV_TIMER:
|
|
+#endif
|
|
+#if 0
|
|
case UV_PROCESS:
|
|
case UV_FS_EVENT:
|
|
+#endif
|
|
+
|
|
+#ifdef CONFIG_LIBUV_FS_POLL
|
|
case UV_FS_POLL:
|
|
+#endif
|
|
case UV_POLL:
|
|
break;
|
|
-
|
|
+#ifdef CONFIG_LIBUV_SIGNAL
|
|
case UV_SIGNAL:
|
|
/* If there are any caught signals "trapped" in the signal pipe,
|
|
* we can't call the close callback yet. Reinserting the handle
|
|
@@ -280,17 +338,26 @@ static void uv__finish_close(uv_handle_t* handle) {
|
|
return;
|
|
}
|
|
break;
|
|
+#endif
|
|
|
|
+#ifdef CONFIG_LIBUV_STREAM
|
|
+#ifdef CONFIG_LIBUV_PIPE
|
|
case UV_NAMED_PIPE:
|
|
- case UV_TCP:
|
|
+#endif
|
|
+#if 0
|
|
case UV_TTY:
|
|
+#endif
|
|
+#ifdef CONFIG_LIBUV_TCP
|
|
+ case UV_TCP:
|
|
+#endif
|
|
uv__stream_destroy((uv_stream_t*)handle);
|
|
break;
|
|
-
|
|
+#endif /* CONFIG_LIBUV_STREAM */
|
|
+#ifdef CONFIG_LIBUV_UDP
|
|
case UV_UDP:
|
|
uv__udp_finish_close((uv_udp_t*)handle);
|
|
break;
|
|
-
|
|
+#endif
|
|
default:
|
|
assert(0);
|
|
break;
|
|
@@ -324,10 +391,11 @@ int uv_is_closing(const uv_handle_t* handle) {
|
|
return uv__is_closing(handle);
|
|
}
|
|
|
|
-
|
|
+#ifndef CONFIG_LIBUV_LOW_FOOTPRINT
|
|
int uv_backend_fd(const uv_loop_t* loop) {
|
|
return loop->backend_fd;
|
|
}
|
|
+#endif
|
|
|
|
|
|
int uv_backend_timeout(const uv_loop_t* loop) {
|
|
@@ -337,16 +405,24 @@ int uv_backend_timeout(const uv_loop_t* loop) {
|
|
if (!uv__has_active_handles(loop) && !uv__has_active_reqs(loop))
|
|
return 0;
|
|
|
|
+#ifdef CONFIG_LIBUV_LOOP_WATCHERS
|
|
if (!QUEUE_EMPTY(&loop->idle_handles))
|
|
return 0;
|
|
+#endif
|
|
|
|
+#ifdef CONFIG_LIBUV_STREAM
|
|
if (!QUEUE_EMPTY(&loop->pending_queue))
|
|
return 0;
|
|
+#endif
|
|
|
|
if (loop->closing_handles)
|
|
return 0;
|
|
|
|
+#ifdef CONFIG_LIBUV_TIMER
|
|
return uv__next_timeout(loop);
|
|
+#else
|
|
+ return -1;
|
|
+#endif
|
|
}
|
|
|
|
|
|
@@ -373,17 +449,30 @@ int uv_run(uv_loop_t* loop, uv_run_mode mode) {
|
|
|
|
while (r != 0 && loop->stop_flag == 0) {
|
|
uv__update_time(loop);
|
|
+
|
|
+#ifdef CONFIG_LIBUV_TIMER
|
|
uv__run_timers(loop);
|
|
+#endif
|
|
+
|
|
+#ifdef CONFIG_LIBUV_STREAM
|
|
ran_pending = uv__run_pending(loop);
|
|
+#else
|
|
+ ran_pending = 0;
|
|
+#endif
|
|
+
|
|
+#ifdef CONFIG_LIBUV_LOOP_WATCHERS
|
|
uv__run_idle(loop);
|
|
uv__run_prepare(loop);
|
|
+#endif
|
|
|
|
timeout = 0;
|
|
if ((mode == UV_RUN_ONCE && !ran_pending) || mode == UV_RUN_DEFAULT)
|
|
timeout = uv_backend_timeout(loop);
|
|
|
|
uv__io_poll(loop, timeout);
|
|
+#ifdef CONFIG_LIBUV_LOOP_WATCHERS
|
|
uv__run_check(loop);
|
|
+#endif
|
|
uv__run_closing_handles(loop);
|
|
|
|
if (mode == UV_RUN_ONCE) {
|
|
@@ -396,7 +485,10 @@ int uv_run(uv_loop_t* loop, uv_run_mode mode) {
|
|
* the check.
|
|
*/
|
|
uv__update_time(loop);
|
|
+
|
|
+#ifdef CONFIG_LIBUV_TIMER
|
|
uv__run_timers(loop);
|
|
+#endif
|
|
}
|
|
|
|
r = uv__loop_alive(loop);
|
|
@@ -423,7 +515,7 @@ int uv_is_active(const uv_handle_t* handle) {
|
|
return uv__is_active(handle);
|
|
}
|
|
|
|
-
|
|
+#ifdef CONFIG_LIBUV_NET
|
|
/* Open a socket in non-blocking close-on-exec mode, atomically if possible. */
|
|
int uv__socket(int domain, int type, int protocol) {
|
|
int sockfd;
|
|
@@ -460,6 +552,7 @@ int uv__socket(int domain, int type, int protocol) {
|
|
|
|
return sockfd;
|
|
}
|
|
+#endif
|
|
|
|
/* get a file pointer to a file in read-only and close-on-exec mode */
|
|
FILE* uv__open_file(const char* path) {
|
|
@@ -477,7 +570,7 @@ FILE* uv__open_file(const char* path) {
|
|
return fp;
|
|
}
|
|
|
|
-
|
|
+#if defined(CONFIG_LIBUV_STREAM) && defined(CONFIG_LIBUV_NET)
|
|
int uv__accept(int sockfd) {
|
|
int peerfd;
|
|
int err;
|
|
@@ -509,7 +602,7 @@ int uv__accept(int sockfd) {
|
|
|
|
return peerfd;
|
|
}
|
|
-
|
|
+#endif
|
|
|
|
/* close() on macos has the "interesting" quirk that it fails with EINTR
|
|
* without closing the file descriptor when a thread is in the cancel state.
|
|
@@ -531,6 +624,8 @@ int uv__close_nocancel(int fd) {
|
|
return close$NOCANCEL$UNIX2003(fd);
|
|
#endif
|
|
#pragma GCC diagnostic pop
|
|
+#elif defined(__NUTTX__)
|
|
+ return close(fd);
|
|
#elif defined(__linux__)
|
|
return syscall(SYS_close, fd);
|
|
#else
|
|
@@ -559,11 +654,18 @@ int uv__close_nocheckstdio(int fd) {
|
|
|
|
|
|
int uv__close(int fd) {
|
|
+#ifdef __NUTTX__
|
|
+ if (close(fd) < 0) {
|
|
+ return UV__ERR(errno);
|
|
+ }
|
|
+ return 0;
|
|
+#else
|
|
assert(fd > STDERR_FILENO); /* Catch stdio close bugs. */
|
|
#if defined(__MVS__)
|
|
SAVE_ERRNO(epoll_file_close(fd));
|
|
#endif
|
|
return uv__close_nocheckstdio(fd);
|
|
+#endif /* __NUTTX__ */
|
|
}
|
|
|
|
|
|
@@ -581,7 +683,8 @@ int uv__nonblock_ioctl(int fd, int set) {
|
|
}
|
|
|
|
|
|
-#if !defined(__CYGWIN__) && !defined(__MSYS__) && !defined(__HAIKU__)
|
|
+#if !defined(__CYGWIN__) && !defined(__MSYS__) && \
|
|
+ !defined(__HAIKU__) && !defined(__NUTTX__)
|
|
int uv__cloexec_ioctl(int fd, int set) {
|
|
int r;
|
|
|
|
@@ -658,7 +761,7 @@ int uv__cloexec_fcntl(int fd, int set) {
|
|
return 0;
|
|
}
|
|
|
|
-
|
|
+#if 0
|
|
ssize_t uv__recvmsg(int fd, struct msghdr* msg, int flags) {
|
|
struct cmsghdr* cmsg;
|
|
ssize_t rc;
|
|
@@ -695,7 +798,7 @@ ssize_t uv__recvmsg(int fd, struct msghdr* msg, int flags) {
|
|
uv__cloexec(*pfd, 1);
|
|
return rc;
|
|
}
|
|
-
|
|
+#endif
|
|
|
|
int uv_cwd(char* buffer, size_t* size) {
|
|
char scratch[1 + UV__PATH_MAX];
|
|
@@ -743,7 +846,7 @@ int uv_chdir(const char* dir) {
|
|
return 0;
|
|
}
|
|
|
|
-
|
|
+#if 0
|
|
void uv_disable_stdio_inheritance(void) {
|
|
int fd;
|
|
|
|
@@ -754,21 +857,31 @@ void uv_disable_stdio_inheritance(void) {
|
|
if (uv__cloexec(fd, 1) && fd > 15)
|
|
break;
|
|
}
|
|
-
|
|
+#endif
|
|
|
|
int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd) {
|
|
int fd_out;
|
|
|
|
switch (handle->type) {
|
|
+#ifdef CONFIG_LIBUV_TCP
|
|
case UV_TCP:
|
|
+#endif
|
|
+#ifdef CONFIG_LIBUV_PIPE
|
|
case UV_NAMED_PIPE:
|
|
+#endif
|
|
+#if 0
|
|
case UV_TTY:
|
|
+#endif
|
|
+#if defined(CONFIG_LIBUV_PIPE) || defined(CONFIG_LIBUV_TCP)
|
|
fd_out = uv__stream_fd((uv_stream_t*) handle);
|
|
break;
|
|
+#endif
|
|
|
|
+#ifdef CONFIG_LIBUV_UDP
|
|
case UV_UDP:
|
|
fd_out = ((uv_udp_t *) handle)->io_watcher.fd;
|
|
break;
|
|
+#endif
|
|
|
|
case UV_POLL:
|
|
fd_out = ((uv_poll_t *) handle)->io_watcher.fd;
|
|
@@ -785,11 +898,11 @@ int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd) {
|
|
return 0;
|
|
}
|
|
|
|
-
|
|
+#ifdef CONFIG_LIBUV_STREAM
|
|
static int uv__run_pending(uv_loop_t* loop) {
|
|
QUEUE* q;
|
|
QUEUE pq;
|
|
- uv__io_t* w;
|
|
+ uv_stream_t* handle;
|
|
|
|
if (QUEUE_EMPTY(&loop->pending_queue))
|
|
return 0;
|
|
@@ -800,14 +913,15 @@ static int uv__run_pending(uv_loop_t* loop) {
|
|
q = QUEUE_HEAD(&pq);
|
|
QUEUE_REMOVE(q);
|
|
QUEUE_INIT(q);
|
|
- w = QUEUE_DATA(q, uv__io_t, pending_queue);
|
|
- w->cb(loop, w, POLLOUT);
|
|
+ handle = QUEUE_DATA(q, uv_stream_t, pending_queue);
|
|
+ handle->io_watcher.cb(loop, &handle->io_watcher, POLLOUT);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
+#endif
|
|
|
|
-
|
|
+#ifndef CONFIG_LIBUV_LOW_FOOTPRINT
|
|
static unsigned int next_power_of_two(unsigned int val) {
|
|
val -= 1;
|
|
val |= val >> 1;
|
|
@@ -852,12 +966,14 @@ static void maybe_resize(uv_loop_t* loop, unsigned int len) {
|
|
loop->watchers = watchers;
|
|
loop->nwatchers = nwatchers;
|
|
}
|
|
-
|
|
+#endif
|
|
|
|
void uv__io_init(uv__io_t* w, uv__io_cb cb, int fd) {
|
|
assert(cb != NULL);
|
|
assert(fd >= -1);
|
|
+#if 0
|
|
QUEUE_INIT(&w->pending_queue);
|
|
+#endif
|
|
QUEUE_INIT(&w->watcher_queue);
|
|
w->cb = cb;
|
|
w->fd = fd;
|
|
@@ -878,7 +994,9 @@ void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
|
assert(w->fd < INT_MAX);
|
|
|
|
w->pevents |= events;
|
|
+#ifndef CONFIG_LIBUV_LOW_FOOTPRINT
|
|
maybe_resize(loop, w->fd + 1);
|
|
+#endif
|
|
|
|
#if !defined(__sun)
|
|
/* The event ports backend needs to rearm all file descriptors on each and
|
|
@@ -892,10 +1010,12 @@ void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
|
if (QUEUE_EMPTY(&w->watcher_queue))
|
|
QUEUE_INSERT_TAIL(&loop->watcher_queue, &w->watcher_queue);
|
|
|
|
+#ifndef CONFIG_LIBUV_LOW_FOOTPRINT
|
|
if (loop->watchers[w->fd] == NULL) {
|
|
loop->watchers[w->fd] = w;
|
|
loop->nfds++;
|
|
}
|
|
+#endif
|
|
}
|
|
|
|
|
|
@@ -909,8 +1029,10 @@ void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
|
assert(w->fd >= 0);
|
|
|
|
/* Happens when uv__io_stop() is called on a handle that was never started. */
|
|
+#ifndef CONFIG_LIBUV_LOW_FOOTPRINT
|
|
if ((unsigned) w->fd >= loop->nwatchers)
|
|
return;
|
|
+#endif
|
|
|
|
w->pevents &= ~events;
|
|
|
|
@@ -918,6 +1040,7 @@ void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
|
QUEUE_REMOVE(&w->watcher_queue);
|
|
QUEUE_INIT(&w->watcher_queue);
|
|
|
|
+#ifndef CONFIG_LIBUV_LOW_FOOTPRINT
|
|
if (loop->watchers[w->fd] != NULL) {
|
|
assert(loop->watchers[w->fd] == w);
|
|
assert(loop->nfds > 0);
|
|
@@ -925,6 +1048,9 @@ void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
|
loop->nfds--;
|
|
w->events = 0;
|
|
}
|
|
+#else
|
|
+ w->events = 0;
|
|
+#endif
|
|
}
|
|
else if (QUEUE_EMPTY(&w->watcher_queue))
|
|
QUEUE_INSERT_TAIL(&loop->watcher_queue, &w->watcher_queue);
|
|
@@ -933,19 +1059,21 @@ void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
|
|
|
void uv__io_close(uv_loop_t* loop, uv__io_t* w) {
|
|
uv__io_stop(loop, w, POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI);
|
|
+#if 0
|
|
QUEUE_REMOVE(&w->pending_queue);
|
|
+#endif
|
|
|
|
/* Remove stale events for this file descriptor */
|
|
if (w->fd != -1)
|
|
uv__platform_invalidate_fd(loop, w->fd);
|
|
}
|
|
|
|
-
|
|
-void uv__io_feed(uv_loop_t* loop, uv__io_t* w) {
|
|
- if (QUEUE_EMPTY(&w->pending_queue))
|
|
- QUEUE_INSERT_TAIL(&loop->pending_queue, &w->pending_queue);
|
|
+#ifdef CONFIG_LIBUV_STREAM
|
|
+void uv__stream_feed(uv_loop_t* loop, uv_stream_t* s) {
|
|
+ if (QUEUE_EMPTY(&s->pending_queue))
|
|
+ QUEUE_INSERT_TAIL(&loop->pending_queue, &s->pending_queue);
|
|
}
|
|
-
|
|
+#endif
|
|
|
|
int uv__io_active(const uv__io_t* w, unsigned int events) {
|
|
assert(0 == (events & ~(POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI)));
|
|
@@ -955,10 +1083,22 @@ int uv__io_active(const uv__io_t* w, unsigned int events) {
|
|
|
|
|
|
int uv__fd_exists(uv_loop_t* loop, int fd) {
|
|
+#ifndef CONFIG_LIBUV_LOW_FOOTPRINT
|
|
return (unsigned) fd < loop->nwatchers && loop->watchers[fd] != NULL;
|
|
+#else
|
|
+ QUEUE* q;
|
|
+ uv__io_t* w;
|
|
+ QUEUE_FOREACH(q, &loop->watcher_queue) {
|
|
+ w = QUEUE_DATA(q, uv__io_t, watcher_queue);
|
|
+ if (w->fd == fd) {
|
|
+ return 1;
|
|
+ }
|
|
+ }
|
|
+ return 0;
|
|
+#endif
|
|
}
|
|
|
|
-
|
|
+#if 0
|
|
int uv_getrusage(uv_rusage_t* rusage) {
|
|
struct rusage usage;
|
|
|
|
@@ -990,7 +1130,7 @@ int uv_getrusage(uv_rusage_t* rusage) {
|
|
|
|
return 0;
|
|
}
|
|
-
|
|
+#endif
|
|
|
|
int uv__open_cloexec(const char* path, int flags) {
|
|
#if defined(O_CLOEXEC)
|
|
@@ -1019,7 +1159,7 @@ int uv__open_cloexec(const char* path, int flags) {
|
|
#endif /* O_CLOEXEC */
|
|
}
|
|
|
|
-
|
|
+#if 0
|
|
int uv__dup2_cloexec(int oldfd, int newfd) {
|
|
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__linux__)
|
|
int r;
|
|
@@ -1046,7 +1186,7 @@ int uv__dup2_cloexec(int oldfd, int newfd) {
|
|
return r;
|
|
#endif
|
|
}
|
|
-
|
|
+#endif
|
|
|
|
int uv_os_homedir(char* buffer, size_t* size) {
|
|
uv_passwd_t pwd;
|
|
@@ -1390,12 +1530,13 @@ uv_pid_t uv_os_getpid(void) {
|
|
return getpid();
|
|
}
|
|
|
|
-
|
|
+#if 0
|
|
uv_pid_t uv_os_getppid(void) {
|
|
return getppid();
|
|
}
|
|
+#endif
|
|
|
|
-
|
|
+#if 0
|
|
int uv_os_getpriority(uv_pid_t pid, int* priority) {
|
|
int r;
|
|
|
|
@@ -1422,7 +1563,7 @@ int uv_os_setpriority(uv_pid_t pid, int priority) {
|
|
|
|
return 0;
|
|
}
|
|
-
|
|
+#endif
|
|
|
|
int uv_os_uname(uv_utsname_t* buffer) {
|
|
struct utsname buf;
|
|
diff --git a/src/unix/fs.c b/src/unix/fs.c
|
|
index dd08ea541..302d4f0c6 100644
|
|
--- a/src/unix/fs.c
|
|
+++ b/src/unix/fs.c
|
|
@@ -56,6 +56,12 @@
|
|
# define HAVE_PREADV 0
|
|
#endif
|
|
|
|
+#ifdef __NUTTX__
|
|
+# include <sys/sendfile.h>
|
|
+# include <sys/statfs.h>
|
|
+
|
|
+#else /* __NUTTX__ */
|
|
+
|
|
#if defined(__linux__) || defined(__sun)
|
|
# include <sys/sendfile.h>
|
|
#endif
|
|
@@ -84,6 +90,7 @@
|
|
#else
|
|
# include <sys/statfs.h>
|
|
#endif
|
|
+#endif /* __NUTTX__ */
|
|
|
|
#if defined(_AIX) && _XOPEN_SOURCE <= 600
|
|
extern char *mkdtemp(char *template); /* See issue #740 on AIX < 7 */
|
|
@@ -219,6 +226,7 @@ UV_UNUSED(static struct timeval uv__fs_to_timeval(double time)) {
|
|
return tv;
|
|
}
|
|
|
|
+#ifndef __NUTTX__
|
|
static ssize_t uv__fs_futime(uv_fs_t* req) {
|
|
#if defined(__linux__) \
|
|
|| defined(_AIX71) \
|
|
@@ -349,7 +357,7 @@ static int uv__fs_mkstemp(uv_fs_t* req) {
|
|
|
|
return r;
|
|
}
|
|
-
|
|
+#endif /* __NUTTX__ */
|
|
|
|
static ssize_t uv__fs_open(uv_fs_t* req) {
|
|
#ifdef O_CLOEXEC
|
|
@@ -431,7 +439,7 @@ static ssize_t uv__fs_preadv(uv_file fd,
|
|
|
|
|
|
static ssize_t uv__fs_read(uv_fs_t* req) {
|
|
-#if defined(__linux__)
|
|
+#if !defined(__NUTTX__) && defined(__linux__)
|
|
static int no_preadv;
|
|
#endif
|
|
unsigned int iovmax;
|
|
@@ -455,13 +463,13 @@ static ssize_t uv__fs_read(uv_fs_t* req) {
|
|
#if HAVE_PREADV
|
|
result = preadv(req->file, (struct iovec*) req->bufs, req->nbufs, req->off);
|
|
#else
|
|
-# if defined(__linux__)
|
|
+# if !defined(__NUTTX__) && defined(__linux__)
|
|
if (uv__load_relaxed(&no_preadv)) retry:
|
|
# endif
|
|
{
|
|
result = uv__fs_preadv(req->file, req->bufs, req->nbufs, req->off);
|
|
}
|
|
-# if defined(__linux__)
|
|
+# if !defined(__NUTTX__) && defined(__linux__)
|
|
else {
|
|
result = uv__preadv(req->file,
|
|
(struct iovec*)req->bufs,
|
|
@@ -668,6 +676,7 @@ static ssize_t uv__fs_pathmax_size(const char* path) {
|
|
return pathmax;
|
|
}
|
|
|
|
+#ifdef CONFIG_PSEUDOFS_SOFTLINKS
|
|
static ssize_t uv__fs_readlink(uv_fs_t* req) {
|
|
ssize_t maxlen;
|
|
ssize_t len;
|
|
@@ -726,6 +735,7 @@ static ssize_t uv__fs_readlink(uv_fs_t* req) {
|
|
|
|
return 0;
|
|
}
|
|
+#endif
|
|
|
|
static ssize_t uv__fs_realpath(uv_fs_t* req) {
|
|
char* buf;
|
|
@@ -756,6 +766,7 @@ static ssize_t uv__fs_realpath(uv_fs_t* req) {
|
|
return 0;
|
|
}
|
|
|
|
+#ifndef __NUTTX__
|
|
static ssize_t uv__fs_sendfile_emul(uv_fs_t* req) {
|
|
struct pollfd pfd;
|
|
int use_pread;
|
|
@@ -868,7 +879,7 @@ out:
|
|
|
|
return nsent;
|
|
}
|
|
-
|
|
+#endif
|
|
|
|
static ssize_t uv__fs_sendfile(uv_fs_t* req) {
|
|
int in_fd;
|
|
@@ -877,7 +888,7 @@ static ssize_t uv__fs_sendfile(uv_fs_t* req) {
|
|
in_fd = req->flags;
|
|
out_fd = req->file;
|
|
|
|
-#if defined(__linux__) || defined(__sun)
|
|
+#if defined(__NUTTX__) || defined(__linux__) || defined(__sun)
|
|
{
|
|
off_t off;
|
|
ssize_t r;
|
|
@@ -895,6 +906,7 @@ static ssize_t uv__fs_sendfile(uv_fs_t* req) {
|
|
return r;
|
|
}
|
|
|
|
+#ifndef __NUTTX__
|
|
if (errno == EINVAL ||
|
|
errno == EIO ||
|
|
errno == ENOTSOCK ||
|
|
@@ -902,7 +914,7 @@ static ssize_t uv__fs_sendfile(uv_fs_t* req) {
|
|
errno = 0;
|
|
return uv__fs_sendfile_emul(req);
|
|
}
|
|
-
|
|
+#endif
|
|
return -1;
|
|
}
|
|
#elif defined(__APPLE__) || \
|
|
@@ -968,7 +980,7 @@ static ssize_t uv__fs_sendfile(uv_fs_t* req) {
|
|
#endif
|
|
}
|
|
|
|
-
|
|
+#ifndef __NUTTX__
|
|
static ssize_t uv__fs_utime(uv_fs_t* req) {
|
|
#if defined(__linux__) \
|
|
|| defined(_AIX71) \
|
|
@@ -1035,10 +1047,10 @@ static ssize_t uv__fs_lutime(uv_fs_t* req) {
|
|
return -1;
|
|
#endif
|
|
}
|
|
-
|
|
+#endif /* !__NUTTX__ */
|
|
|
|
static ssize_t uv__fs_write(uv_fs_t* req) {
|
|
-#if defined(__linux__)
|
|
+#if !defined(__NUTTX__) && defined(__linux__)
|
|
static int no_pwritev;
|
|
#endif
|
|
ssize_t r;
|
|
@@ -1067,13 +1079,13 @@ static ssize_t uv__fs_write(uv_fs_t* req) {
|
|
#if HAVE_PREADV
|
|
r = pwritev(req->file, (struct iovec*) req->bufs, req->nbufs, req->off);
|
|
#else
|
|
-# if defined(__linux__)
|
|
+# if !defined(__NUTTX__) && defined(__linux__)
|
|
if (no_pwritev) retry:
|
|
# endif
|
|
{
|
|
r = pwrite(req->file, req->bufs[0].base, req->bufs[0].len, req->off);
|
|
}
|
|
-# if defined(__linux__)
|
|
+# if !defined(__NUTTX__) && defined(__linux__)
|
|
else {
|
|
r = uv__pwritev(req->file,
|
|
(struct iovec*) req->bufs,
|
|
@@ -1102,7 +1114,9 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) {
|
|
uv_file srcfd;
|
|
uv_file dstfd;
|
|
struct stat src_statsbuf;
|
|
+#ifndef __NUTTX__
|
|
struct stat dst_statsbuf;
|
|
+#endif
|
|
int dst_flags;
|
|
int result;
|
|
int err;
|
|
@@ -1146,6 +1160,7 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) {
|
|
goto out;
|
|
}
|
|
|
|
+#ifndef __NUTTX__
|
|
/* Get the destination file's mode. */
|
|
if (fstat(dstfd, &dst_statsbuf)) {
|
|
err = UV__ERR(errno);
|
|
@@ -1157,9 +1172,12 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) {
|
|
src_statsbuf.st_ino == dst_statsbuf.st_ino) {
|
|
goto out;
|
|
}
|
|
+#endif
|
|
|
|
+#ifndef __NUTTX__
|
|
if (fchmod(dstfd, src_statsbuf.st_mode) == -1) {
|
|
err = UV__ERR(errno);
|
|
+ goto out;
|
|
#ifdef __linux__
|
|
if (err != UV_EPERM)
|
|
goto out;
|
|
@@ -1183,6 +1201,7 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) {
|
|
goto out;
|
|
#endif /* !__linux__ */
|
|
}
|
|
+#endif /* !__NUTTX__ */
|
|
|
|
#ifdef FICLONE
|
|
if (req->flags & UV_FS_COPYFILE_FICLONE ||
|
|
@@ -1343,7 +1362,7 @@ static int uv__fs_statx(int fd,
|
|
int is_lstat,
|
|
uv_stat_t* buf) {
|
|
STATIC_ASSERT(UV_ENOSYS != -1);
|
|
-#ifdef __linux__
|
|
+#if !defined(__NUTTX__) && defined(__linux__)
|
|
static int no_statx;
|
|
struct uv__statx statxbuf;
|
|
int dirfd;
|
|
@@ -1542,40 +1561,56 @@ static void uv__fs_work(struct uv__work* w) {
|
|
|
|
switch (req->fs_type) {
|
|
X(ACCESS, access(req->path, req->flags));
|
|
+#ifndef __NUTTX__
|
|
X(CHMOD, chmod(req->path, req->mode));
|
|
X(CHOWN, chown(req->path, req->uid, req->gid));
|
|
+#endif
|
|
X(CLOSE, uv__fs_close(req->file));
|
|
X(COPYFILE, uv__fs_copyfile(req));
|
|
+#ifndef __NUTTX__
|
|
X(FCHMOD, fchmod(req->file, req->mode));
|
|
X(FCHOWN, fchown(req->file, req->uid, req->gid));
|
|
X(LCHOWN, lchown(req->path, req->uid, req->gid));
|
|
+#endif
|
|
X(FDATASYNC, uv__fs_fdatasync(req));
|
|
X(FSTAT, uv__fs_fstat(req->file, &req->statbuf));
|
|
X(FSYNC, uv__fs_fsync(req));
|
|
X(FTRUNCATE, ftruncate(req->file, req->off));
|
|
+#ifndef __NUTTX__
|
|
X(FUTIME, uv__fs_futime(req));
|
|
X(LUTIME, uv__fs_lutime(req));
|
|
+#endif
|
|
X(LSTAT, uv__fs_lstat(req->path, &req->statbuf));
|
|
+#ifdef CONFIG_PSEUDOFS_SOFTLINKS
|
|
X(LINK, link(req->path, req->new_path));
|
|
+#endif
|
|
X(MKDIR, mkdir(req->path, req->mode));
|
|
+#ifndef __NUTTX__
|
|
X(MKDTEMP, uv__fs_mkdtemp(req));
|
|
X(MKSTEMP, uv__fs_mkstemp(req));
|
|
+#endif
|
|
X(OPEN, uv__fs_open(req));
|
|
X(READ, uv__fs_read(req));
|
|
X(SCANDIR, uv__fs_scandir(req));
|
|
X(OPENDIR, uv__fs_opendir(req));
|
|
X(READDIR, uv__fs_readdir(req));
|
|
X(CLOSEDIR, uv__fs_closedir(req));
|
|
+#ifdef CONFIG_PSEUDOFS_SOFTLINKS
|
|
X(READLINK, uv__fs_readlink(req));
|
|
+#endif
|
|
X(REALPATH, uv__fs_realpath(req));
|
|
X(RENAME, rename(req->path, req->new_path));
|
|
X(RMDIR, rmdir(req->path));
|
|
X(SENDFILE, uv__fs_sendfile(req));
|
|
X(STAT, uv__fs_stat(req->path, &req->statbuf));
|
|
X(STATFS, uv__fs_statfs(req));
|
|
+#ifdef CONFIG_PSEUDOFS_SOFTLINKS
|
|
X(SYMLINK, symlink(req->path, req->new_path));
|
|
+#endif
|
|
X(UNLINK, unlink(req->path));
|
|
+#ifndef __NUTTX__
|
|
X(UTIME, uv__fs_utime(req));
|
|
+#endif
|
|
X(WRITE, uv__fs_write_all(req));
|
|
default: abort();
|
|
}
|
|
@@ -1621,7 +1656,7 @@ int uv_fs_access(uv_loop_t* loop,
|
|
POST;
|
|
}
|
|
|
|
-
|
|
+#ifndef __NUTTX__
|
|
int uv_fs_chmod(uv_loop_t* loop,
|
|
uv_fs_t* req,
|
|
const char* path,
|
|
@@ -1646,7 +1681,7 @@ int uv_fs_chown(uv_loop_t* loop,
|
|
req->gid = gid;
|
|
POST;
|
|
}
|
|
-
|
|
+#endif
|
|
|
|
int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
|
|
INIT(CLOSE);
|
|
@@ -1654,7 +1689,7 @@ int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
|
|
POST;
|
|
}
|
|
|
|
-
|
|
+#ifndef __NUTTX__
|
|
int uv_fs_fchmod(uv_loop_t* loop,
|
|
uv_fs_t* req,
|
|
uv_file file,
|
|
@@ -1693,7 +1728,7 @@ int uv_fs_lchown(uv_loop_t* loop,
|
|
req->gid = gid;
|
|
POST;
|
|
}
|
|
-
|
|
+#endif
|
|
|
|
int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
|
|
INIT(FDATASYNC);
|
|
@@ -1957,7 +1992,7 @@ int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
|
|
POST;
|
|
}
|
|
|
|
-
|
|
+#ifdef CONFIG_PSEUDOFS_SOFTLINKS
|
|
int uv_fs_symlink(uv_loop_t* loop,
|
|
uv_fs_t* req,
|
|
const char* path,
|
|
@@ -1969,7 +2004,7 @@ int uv_fs_symlink(uv_loop_t* loop,
|
|
req->flags = flags;
|
|
POST;
|
|
}
|
|
-
|
|
+#endif
|
|
|
|
int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
|
|
INIT(UNLINK);
|
|
@@ -1977,7 +2012,7 @@ int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
|
|
POST;
|
|
}
|
|
|
|
-
|
|
+#ifndef __NUTTX__
|
|
int uv_fs_utime(uv_loop_t* loop,
|
|
uv_fs_t* req,
|
|
const char* path,
|
|
@@ -1990,7 +2025,7 @@ int uv_fs_utime(uv_loop_t* loop,
|
|
req->mtime = mtime;
|
|
POST;
|
|
}
|
|
-
|
|
+#endif
|
|
|
|
int uv_fs_write(uv_loop_t* loop,
|
|
uv_fs_t* req,
|
|
diff --git a/src/unix/internal.h b/src/unix/internal.h
|
|
index 402ee877d..107565e4c 100644
|
|
--- a/src/unix/internal.h
|
|
+++ b/src/unix/internal.h
|
|
@@ -1,3 +1,23 @@
|
|
+/****************************************************************************
|
|
+ * src/unix/internal.h
|
|
+ *
|
|
+ * Licensed to the Apache Software Foundation (ASF) under one or more
|
|
+ * contributor license agreements. See the NOTICE file distributed with
|
|
+ * this work for additional information regarding copyright ownership. The
|
|
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
+ * "License"); you may not use this file except in compliance with the
|
|
+ * License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
+ * License for the specific language governing permissions and limitations
|
|
+ * under the License.
|
|
+ *
|
|
+ ****************************************************************************/
|
|
+
|
|
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
@@ -157,14 +177,15 @@ struct uv__stream_queued_fds_s {
|
|
};
|
|
|
|
|
|
-#if defined(_AIX) || \
|
|
+#if !defined(__NUTTX__) && ( \
|
|
+ defined(_AIX) || \
|
|
defined(__APPLE__) || \
|
|
defined(__DragonFly__) || \
|
|
defined(__FreeBSD__) || \
|
|
defined(__FreeBSD_kernel__) || \
|
|
defined(__linux__) || \
|
|
defined(__OpenBSD__) || \
|
|
- defined(__NetBSD__)
|
|
+ defined(__NetBSD__))
|
|
#define uv__cloexec uv__cloexec_ioctl
|
|
#define uv__nonblock uv__nonblock_ioctl
|
|
#else
|
|
@@ -201,7 +222,7 @@ void uv__io_init(uv__io_t* w, uv__io_cb cb, int fd);
|
|
void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events);
|
|
void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events);
|
|
void uv__io_close(uv_loop_t* loop, uv__io_t* w);
|
|
-void uv__io_feed(uv_loop_t* loop, uv__io_t* w);
|
|
+void uv__stream_feed(uv_loop_t* loop, uv_stream_t *s);
|
|
int uv__io_active(const uv__io_t* w, unsigned int events);
|
|
int uv__io_check_fd(uv_loop_t* loop, int fd);
|
|
void uv__io_poll(uv_loop_t* loop, int timeout); /* in milliseconds or -1 */
|
|
@@ -247,6 +268,7 @@ int uv__signal_loop_fork(uv_loop_t* loop);
|
|
|
|
/* platform specific */
|
|
uint64_t uv__hrtime(uv_clocktype_t type);
|
|
+uint32_t uv__hrtime_ms(uv_clocktype_t type);
|
|
int uv__kqueue_init(uv_loop_t* loop);
|
|
int uv__platform_loop_init(uv_loop_t* loop);
|
|
void uv__platform_loop_delete(uv_loop_t* loop);
|
|
@@ -302,7 +324,11 @@ void uv__fsevents_loop_delete(uv_loop_t* loop);
|
|
UV_UNUSED(static void uv__update_time(uv_loop_t* loop)) {
|
|
/* Use a fast time source if available. We only need millisecond precision.
|
|
*/
|
|
+#ifdef CONFIG_LIBUV_TIMER_NUTTX
|
|
+ loop->time = uv__hrtime_ms(UV_CLOCK_FAST);
|
|
+#else
|
|
loop->time = uv__hrtime(UV_CLOCK_FAST) / 1000000;
|
|
+#endif
|
|
}
|
|
|
|
UV_UNUSED(static char* uv__basename_r(const char* path)) {
|
|
diff --git a/src/unix/loop.c b/src/unix/loop.c
|
|
index e5b288956..bb100390a 100644
|
|
--- a/src/unix/loop.c
|
|
+++ b/src/unix/loop.c
|
|
@@ -1,3 +1,23 @@
|
|
+/****************************************************************************
|
|
+ * src/unix/loop.c
|
|
+ *
|
|
+ * Licensed to the Apache Software Foundation (ASF) under one or more
|
|
+ * contributor license agreements. See the NOTICE file distributed with
|
|
+ * this work for additional information regarding copyright ownership. The
|
|
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
+ * "License"); you may not use this file except in compliance with the
|
|
+ * License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
+ * License for the specific language governing permissions and limitations
|
|
+ * under the License.
|
|
+ *
|
|
+ ****************************************************************************/
|
|
+
|
|
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
@@ -27,48 +47,87 @@
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
+#ifdef CONFIG_LIBUV_CONTEXT
|
|
+int uv_loop_init(uv_loop_t* loop, uv_context_t *ctx) {
|
|
+#else
|
|
int uv_loop_init(uv_loop_t* loop) {
|
|
+#endif
|
|
void* saved_data;
|
|
int err;
|
|
|
|
-
|
|
saved_data = loop->data;
|
|
memset(loop, 0, sizeof(*loop));
|
|
loop->data = saved_data;
|
|
|
|
+#ifdef CONFIG_LIBUV_CONTEXT
|
|
+ loop->context = ctx;
|
|
+#endif
|
|
+
|
|
+#ifdef CONFIG_LIBUV_TIMER_NUTTX
|
|
+ loop->timer_head = NULL;
|
|
+#elif defined(CONFIG_LIBUV_TIMER)
|
|
heap_init((struct heap*) &loop->timer_heap);
|
|
+#endif
|
|
+#ifdef CONFIG_LIBUV_WQ
|
|
QUEUE_INIT(&loop->wq);
|
|
+#endif
|
|
+#ifdef CONFIG_LIBUV_LOOP_WATCHERS
|
|
QUEUE_INIT(&loop->idle_handles);
|
|
+#endif
|
|
+#ifdef CONFIG_LIBUV_ASYNC
|
|
QUEUE_INIT(&loop->async_handles);
|
|
+#endif
|
|
+#ifdef CONFIG_LIBUV_LOOP_WATCHERS
|
|
QUEUE_INIT(&loop->check_handles);
|
|
QUEUE_INIT(&loop->prepare_handles);
|
|
+#endif
|
|
QUEUE_INIT(&loop->handle_queue);
|
|
|
|
loop->active_handles = 0;
|
|
loop->active_reqs.count = 0;
|
|
+
|
|
+#ifndef CONFIG_LIBUV_LOW_FOOTPRINT
|
|
loop->nfds = 0;
|
|
loop->watchers = NULL;
|
|
loop->nwatchers = 0;
|
|
+#endif
|
|
+#ifdef CONFIG_LIBUV_STREAM
|
|
QUEUE_INIT(&loop->pending_queue);
|
|
+#endif
|
|
QUEUE_INIT(&loop->watcher_queue);
|
|
|
|
loop->closing_handles = NULL;
|
|
uv__update_time(loop);
|
|
+#ifdef CONFIG_LIBUV_ASYNC
|
|
loop->async_io_watcher.fd = -1;
|
|
+#ifndef CONFIG_LIBUV_LOW_FOOTPRINT
|
|
loop->async_wfd = -1;
|
|
+#endif
|
|
+#endif
|
|
+
|
|
+#ifdef CONFIG_LIBUV_SIGNAL
|
|
loop->signal_pipefd[0] = -1;
|
|
loop->signal_pipefd[1] = -1;
|
|
+#endif
|
|
+
|
|
+#ifndef CONFIG_LIBUV_LOW_FOOTPRINT
|
|
loop->backend_fd = -1;
|
|
loop->emfile_fd = -1;
|
|
+#endif
|
|
|
|
+#if defined(CONFIG_LIBUV_TIMER) && !defined(CONFIG_LIBUV_TIMER_NUTTX)
|
|
loop->timer_counter = 0;
|
|
+#endif
|
|
loop->stop_flag = 0;
|
|
|
|
err = uv__platform_loop_init(loop);
|
|
if (err)
|
|
return err;
|
|
|
|
+#ifdef CONFIG_LIBUV_SIGNAL
|
|
uv__signal_global_once_init();
|
|
+
|
|
+#ifdef CONFIG_LIBUV_PROCESS
|
|
err = uv_signal_init(loop, &loop->child_watcher);
|
|
if (err)
|
|
goto fail_signal_init;
|
|
@@ -76,11 +135,16 @@ int uv_loop_init(uv_loop_t* loop) {
|
|
uv__handle_unref(&loop->child_watcher);
|
|
loop->child_watcher.flags |= UV_HANDLE_INTERNAL;
|
|
QUEUE_INIT(&loop->process_handles);
|
|
+#endif
|
|
+#endif
|
|
|
|
+#ifndef CONFIG_LIBUV_LOW_FOOTPRINT
|
|
err = uv_rwlock_init(&loop->cloexec_lock);
|
|
if (err)
|
|
goto fail_rwlock_init;
|
|
+#endif
|
|
|
|
+#ifdef CONFIG_LIBUV_WQ
|
|
err = uv_mutex_init(&loop->wq_mutex);
|
|
if (err)
|
|
goto fail_mutex_init;
|
|
@@ -91,27 +155,38 @@ int uv_loop_init(uv_loop_t* loop) {
|
|
|
|
uv__handle_unref(&loop->wq_async);
|
|
loop->wq_async.flags |= UV_HANDLE_INTERNAL;
|
|
+#endif
|
|
|
|
return 0;
|
|
|
|
+#ifdef CONFIG_LIBUV_WQ
|
|
fail_async_init:
|
|
uv_mutex_destroy(&loop->wq_mutex);
|
|
|
|
fail_mutex_init:
|
|
+#ifndef CONFIG_LIBUV_LOW_FOOTPRINT
|
|
uv_rwlock_destroy(&loop->cloexec_lock);
|
|
+#endif
|
|
+#endif
|
|
|
|
+#ifndef CONFIG_LIBUV_LOW_FOOTPRINT
|
|
fail_rwlock_init:
|
|
+#endif
|
|
+#ifdef CONFIG_LIBUV_PROCESS
|
|
uv__signal_loop_cleanup(loop);
|
|
|
|
fail_signal_init:
|
|
+#endif
|
|
uv__platform_loop_delete(loop);
|
|
|
|
+#ifndef CONFIG_LIBUV_LOW_FOOTPRINT
|
|
uv__free(loop->watchers);
|
|
loop->nwatchers = 0;
|
|
+#endif
|
|
return err;
|
|
}
|
|
|
|
-
|
|
+#if 0
|
|
int uv_loop_fork(uv_loop_t* loop) {
|
|
int err;
|
|
unsigned int i;
|
|
@@ -143,13 +218,19 @@ int uv_loop_fork(uv_loop_t* loop) {
|
|
|
|
return 0;
|
|
}
|
|
-
|
|
+#endif
|
|
|
|
void uv__loop_close(uv_loop_t* loop) {
|
|
+#ifdef CONFIG_LIBUV_SIGNAL
|
|
uv__signal_loop_cleanup(loop);
|
|
+#endif
|
|
uv__platform_loop_delete(loop);
|
|
+
|
|
+#ifdef CONFIG_LIBUV_ASYNC
|
|
uv__async_stop(loop);
|
|
+#endif
|
|
|
|
+#ifndef CONFIG_LIBUV_LOW_FOOTPRINT
|
|
if (loop->emfile_fd != -1) {
|
|
uv__close(loop->emfile_fd);
|
|
loop->emfile_fd = -1;
|
|
@@ -159,18 +240,25 @@ void uv__loop_close(uv_loop_t* loop) {
|
|
uv__close(loop->backend_fd);
|
|
loop->backend_fd = -1;
|
|
}
|
|
+#endif
|
|
|
|
+#ifdef CONFIG_LIBUV_WQ
|
|
uv_mutex_lock(&loop->wq_mutex);
|
|
assert(QUEUE_EMPTY(&loop->wq) && "thread pool work queue not empty!");
|
|
+#ifndef CONFIG_LIBUV_LOW_FOOTPRINT
|
|
assert(!uv__has_active_reqs(loop));
|
|
+#endif
|
|
uv_mutex_unlock(&loop->wq_mutex);
|
|
uv_mutex_destroy(&loop->wq_mutex);
|
|
+#endif
|
|
|
|
+#ifndef CONFIG_LIBUV_LOW_FOOTPRINT
|
|
/*
|
|
* Note that all thread pool stuff is finished at this point and
|
|
* it is safe to just destroy rw lock
|
|
*/
|
|
uv_rwlock_destroy(&loop->cloexec_lock);
|
|
+#endif
|
|
|
|
#if 0
|
|
assert(QUEUE_EMPTY(&loop->pending_queue));
|
|
@@ -178,13 +266,16 @@ void uv__loop_close(uv_loop_t* loop) {
|
|
assert(loop->nfds == 0);
|
|
#endif
|
|
|
|
+#ifndef CONFIG_LIBUV_LOW_FOOTPRINT
|
|
uv__free(loop->watchers);
|
|
loop->watchers = NULL;
|
|
loop->nwatchers = 0;
|
|
+#endif
|
|
}
|
|
|
|
|
|
int uv__loop_configure(uv_loop_t* loop, uv_loop_option option, va_list ap) {
|
|
+#ifndef __NUTTX__
|
|
if (option != UV_LOOP_BLOCK_SIGNAL)
|
|
return UV_ENOSYS;
|
|
|
|
@@ -192,5 +283,6 @@ int uv__loop_configure(uv_loop_t* loop, uv_loop_option option, va_list ap) {
|
|
return UV_EINVAL;
|
|
|
|
loop->flags |= UV_LOOP_BLOCK_SIGPROF;
|
|
+#endif
|
|
return 0;
|
|
}
|
|
diff --git a/src/unix/no-proctitle.c b/src/unix/no-proctitle.c
|
|
index 32aa0af1f..64a785351 100644
|
|
--- a/src/unix/no-proctitle.c
|
|
+++ b/src/unix/no-proctitle.c
|
|
@@ -1,3 +1,23 @@
|
|
+/****************************************************************************
|
|
+ * src/unix/no-proctitle.c
|
|
+ *
|
|
+ * Licensed to the Apache Software Foundation (ASF) under one or more
|
|
+ * contributor license agreements. See the NOTICE file distributed with
|
|
+ * this work for additional information regarding copyright ownership. The
|
|
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
+ * "License"); you may not use this file except in compliance with the
|
|
+ * License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
+ * License for the specific language governing permissions and limitations
|
|
+ * under the License.
|
|
+ *
|
|
+ ****************************************************************************/
|
|
+
|
|
/* Copyright libuv project contributors. All rights reserved.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
@@ -29,8 +49,16 @@ char** uv_setup_args(int argc, char** argv) {
|
|
return argv;
|
|
}
|
|
|
|
+#ifdef CONFIG_LIBUV_CONTEXT
|
|
+void uv__process_title_setup(uv_context_t *ctx) {
|
|
+}
|
|
+
|
|
+void uv__process_title_cleanup(uv_context_t *ctx) {
|
|
+}
|
|
+#else
|
|
void uv__process_title_cleanup(void) {
|
|
}
|
|
+#endif
|
|
|
|
int uv_set_process_title(const char* title) {
|
|
return 0;
|
|
diff --git a/src/unix/nuttx.c b/src/unix/nuttx.c
|
|
new file mode 100644
|
|
index 000000000..4549e48eb
|
|
--- /dev/null
|
|
+++ b/src/unix/nuttx.c
|
|
@@ -0,0 +1,238 @@
|
|
+/****************************************************************************
|
|
+ * libuv/src/unix/nuttx.c
|
|
+ *
|
|
+ * Licensed to the Apache Software Foundation (ASF) under one or more
|
|
+ * contributor license agreements. See the NOTICE file distributed with
|
|
+ * this work for additional information regarding copyright ownership. The
|
|
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
+ * "License"); you may not use this file except in compliance with the
|
|
+ * License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
+ * License for the specific language governing permissions and limitations
|
|
+ * under the License.
|
|
+ *
|
|
+ ****************************************************************************/
|
|
+
|
|
+/* Copyright libuv project 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 "unix/internal.h"
|
|
+
|
|
+#include <stdint.h>
|
|
+#include <time.h>
|
|
+#include <assert.h>
|
|
+
|
|
+#undef NANOSEC
|
|
+#define NANOSEC ((uint64_t) 1e9)
|
|
+
|
|
+int uv__platform_loop_init(uv_loop_t* loop) {
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+void uv__platform_loop_delete(uv_loop_t* loop) {
|
|
+}
|
|
+
|
|
+/* From libuv/src/unix/posix-hrtime.c */
|
|
+
|
|
+uint64_t uv__hrtime(uv_clocktype_t type) {
|
|
+ struct timespec ts;
|
|
+ clock_gettime(CLOCK_MONOTONIC, &ts);
|
|
+ return (((uint64_t) ts.tv_sec) * NANOSEC + ts.tv_nsec);
|
|
+}
|
|
+
|
|
+uint32_t uv__hrtime_ms(uv_clocktype_t type) {
|
|
+ struct timespec ts;
|
|
+ clock_gettime(CLOCK_MONOTONIC, &ts);
|
|
+ return (uint32_t)(((uint64_t) ts.tv_sec) * 1000 + (ts.tv_nsec/1000/1000));
|
|
+}
|
|
+
|
|
+/* From libuv/src/unix/posix-poll.c */
|
|
+
|
|
+void uv__io_poll(uv_loop_t* loop, int timeout) {
|
|
+ uv_time_t time_base;
|
|
+ uv_time_t time_diff;
|
|
+ QUEUE* q;
|
|
+ uv__io_t* w;
|
|
+ size_t i;
|
|
+ unsigned int nevents;
|
|
+ int nfds;
|
|
+#ifdef CONFIG_LIBUV_SIGNAL
|
|
+ int have_signals;
|
|
+#endif
|
|
+ struct pollfd* pe;
|
|
+ int fd;
|
|
+
|
|
+ assert(timeout >= -1);
|
|
+ time_base = loop->time;
|
|
+
|
|
+ if (QUEUE_EMPTY(&loop->watcher_queue)) {
|
|
+ if (timeout > 0) {
|
|
+ usleep(1000*timeout);
|
|
+ }
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ /* Build pollfd array */
|
|
+
|
|
+ loop->poll_fds_used = 0;
|
|
+ QUEUE_FOREACH(q, &loop->watcher_queue) {
|
|
+ w = QUEUE_DATA(q, uv__io_t, watcher_queue);
|
|
+
|
|
+ /* Allocate new entry */
|
|
+ i = loop->poll_fds_used ++;
|
|
+ if (loop->poll_fds_used >= CONFIG_LIBUV_NPOLLWAITERS) {
|
|
+ /* Error no available pollfd for loop */
|
|
+ abort();
|
|
+ }
|
|
+
|
|
+ loop->poll_fds[i].fd = w->fd;
|
|
+ loop->poll_fds[i].events = w->pevents;
|
|
+ }
|
|
+
|
|
+ /* Loop calls to poll() and processing of results. If we get some
|
|
+ * results from poll() but they turn out not to be interesting to
|
|
+ * our caller then we need to loop around and poll() again.
|
|
+ */
|
|
+ for (;;) {
|
|
+ nfds = poll(loop->poll_fds, (nfds_t)loop->poll_fds_used, timeout);
|
|
+
|
|
+ /* 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.
|
|
+ */
|
|
+ SAVE_ERRNO(uv__update_time(loop));
|
|
+
|
|
+ if (nfds == 0) {
|
|
+ assert(timeout != -1);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (nfds == -1) {
|
|
+ if (errno != EINTR)
|
|
+ abort();
|
|
+
|
|
+ if (timeout == -1)
|
|
+ continue;
|
|
+
|
|
+ if (timeout == 0)
|
|
+ return;
|
|
+
|
|
+ /* Interrupted by a signal. Update timeout and poll again. */
|
|
+ goto update_timeout;
|
|
+ }
|
|
+
|
|
+ /* Initialize a count of events that we care about. */
|
|
+ nevents = 0;
|
|
+#ifdef CONFIG_LIBUV_SIGNAL
|
|
+ have_signals = 0;
|
|
+#endif
|
|
+
|
|
+ /* Loop over the entire poll fds array looking for returned events. */
|
|
+ for (i = 0; i < loop->poll_fds_used; i++) {
|
|
+ pe = loop->poll_fds + i;
|
|
+ fd = pe->fd;
|
|
+
|
|
+ if (fd < 0 || !pe->revents) {
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ QUEUE_FOREACH(q, &loop->watcher_queue) {
|
|
+ w = QUEUE_DATA(q, uv__io_t, watcher_queue);
|
|
+ if (w->fd == fd) {
|
|
+ goto process_event;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* File descriptor that we've stopped watching, ignore. */
|
|
+ continue;
|
|
+
|
|
+process_event:
|
|
+ /* Filter out events that user has not requested us to watch
|
|
+ * (e.g. POLLNVAL).
|
|
+ */
|
|
+ pe->revents &= w->pevents | POLLERR | POLLHUP;
|
|
+
|
|
+ if (pe->revents != 0) {
|
|
+#ifdef CONFIG_LIBUV_SIGNAL
|
|
+ /* Run signal watchers last. */
|
|
+ if (w == &loop->signal_io_watcher) {
|
|
+ have_signals = 1;
|
|
+ } else
|
|
+#endif
|
|
+ {
|
|
+ w->cb(loop, w, pe->revents);
|
|
+ }
|
|
+
|
|
+ nevents++;
|
|
+ }
|
|
+ }
|
|
+
|
|
+#ifdef CONFIG_LIBUV_SIGNAL
|
|
+ if (have_signals != 0) {
|
|
+ loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN);
|
|
+ return; /* Event loop should cycle now so don't poll again. */
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ if (nevents != 0)
|
|
+ return;
|
|
+
|
|
+ if (timeout == 0)
|
|
+ return;
|
|
+
|
|
+ if (timeout == -1)
|
|
+ continue;
|
|
+
|
|
+update_timeout:
|
|
+ assert(timeout > 0);
|
|
+
|
|
+ time_diff = (uv_time_t)(loop->time - time_base);
|
|
+ if (time_diff >= (uv_time_t) timeout)
|
|
+ return;
|
|
+
|
|
+ timeout -= time_diff;
|
|
+ }
|
|
+}
|
|
+
|
|
+/* Check whether the given fd is supported by poll(). */
|
|
+int uv__io_check_fd(uv_loop_t* loop, int fd) {
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
|
|
+ int i;
|
|
+
|
|
+ /* uv__io_stop() removes uv__io_t from watcher_queue so
|
|
+ * no need to do it here */
|
|
+
|
|
+ for (i = 0; i < loop->poll_fds_used; i++) {
|
|
+ if (loop->poll_fds[i].fd == fd) {
|
|
+ loop->poll_fds[i].fd = -1;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+}
|
|
diff --git a/src/unix/nuttx_stream.c b/src/unix/nuttx_stream.c
|
|
new file mode 100644
|
|
index 000000000..0642d057c
|
|
--- /dev/null
|
|
+++ b/src/unix/nuttx_stream.c
|
|
@@ -0,0 +1,1016 @@
|
|
+/****************************************************************************
|
|
+ * libuv/src/unix/nuttx_stream.c
|
|
+ *
|
|
+ * Licensed to the Apache Software Foundation (ASF) under one or more
|
|
+ * contributor license agreements. See the NOTICE file distributed with
|
|
+ * this work for additional information regarding copyright ownership. The
|
|
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
+ * "License"); you may not use this file except in compliance with the
|
|
+ * License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
+ * License for the specific language governing permissions and limitations
|
|
+ * under the License.
|
|
+ *
|
|
+ ****************************************************************************/
|
|
+
|
|
+/* 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 "internal.h"
|
|
+
|
|
+#include <stdio.h>
|
|
+#include <stdlib.h>
|
|
+#include <string.h>
|
|
+#include <assert.h>
|
|
+#include <errno.h>
|
|
+
|
|
+#include <sys/types.h>
|
|
+#include <sys/socket.h>
|
|
+#include <sys/uio.h>
|
|
+#include <sys/un.h>
|
|
+#include <unistd.h>
|
|
+#include <limits.h> /* IOV_MAX */
|
|
+
|
|
+#ifdef CONFIG_LIBUV_NET
|
|
+static void uv__stream_connect(uv_stream_t*);
|
|
+#endif
|
|
+
|
|
+static void uv__write(uv_stream_t* stream);
|
|
+static void uv__read(uv_stream_t* stream);
|
|
+static void uv__stream_io(uv_loop_t* loop, uv__io_t* w, unsigned int events);
|
|
+static void uv__write_callbacks(uv_stream_t* stream);
|
|
+static size_t uv__write_req_size(uv_write_t* req);
|
|
+
|
|
+
|
|
+void uv__stream_init(uv_loop_t* loop,
|
|
+ uv_stream_t* stream,
|
|
+ uv_handle_type type) {
|
|
+ uv__handle_init(loop, (uv_handle_t*)stream, type);
|
|
+ stream->read_cb = NULL;
|
|
+ stream->alloc_cb = NULL;
|
|
+ stream->close_cb = NULL;
|
|
+ stream->connection_cb = NULL;
|
|
+ stream->connect_req = NULL;
|
|
+ /* shutdown() not supported by NuttX */
|
|
+ stream->shutdown_req = NULL;
|
|
+ stream->accepted_fd = -1;
|
|
+ QUEUE_INIT(&stream->write_queue);
|
|
+ QUEUE_INIT(&stream->write_completed_queue);
|
|
+ /* FIXME move back to uv__io_t if needed */
|
|
+ QUEUE_INIT(&stream->pending_queue);
|
|
+ stream->write_queue_size = 0;
|
|
+
|
|
+ uv__io_init(&stream->io_watcher, uv__stream_io, -1);
|
|
+}
|
|
+
|
|
+
|
|
+int uv__stream_open(uv_stream_t* stream, int fd, int flags) {
|
|
+ if (!(stream->io_watcher.fd == -1 || stream->io_watcher.fd == fd))
|
|
+ return UV_EBUSY;
|
|
+
|
|
+ assert(fd >= 0);
|
|
+ stream->flags |= flags;
|
|
+
|
|
+#ifdef CONFIG_LIBUV_TCP
|
|
+ if (stream->type == UV_TCP) {
|
|
+#ifdef CONFIG_NET_TCP_KEEPALIVE
|
|
+ /* TODO Use delay the user passed in. */
|
|
+ if ((stream->flags & UV_HANDLE_TCP_KEEPALIVE) &&
|
|
+ uv__tcp_keepalive(fd, 1, 60)) {
|
|
+ return UV__ERR(errno);
|
|
+ }
|
|
+#endif
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ stream->io_watcher.fd = fd;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+void uv__stream_flush_write_queue(uv_stream_t* stream, int error) {
|
|
+ uv_write_t* req;
|
|
+ QUEUE* q;
|
|
+ while (!QUEUE_EMPTY(&stream->write_queue)) {
|
|
+ q = QUEUE_HEAD(&stream->write_queue);
|
|
+ QUEUE_REMOVE(q);
|
|
+
|
|
+ req = QUEUE_DATA(q, uv_write_t, queue);
|
|
+ req->error = error;
|
|
+
|
|
+ QUEUE_INSERT_TAIL(&stream->write_completed_queue, &req->queue);
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
+void uv__stream_destroy(uv_stream_t* stream) {
|
|
+ assert(!uv__io_active(&stream->io_watcher, POLLIN | POLLOUT));
|
|
+ assert(stream->flags & UV_HANDLE_CLOSED);
|
|
+
|
|
+ if (stream->connect_req) {
|
|
+ uv__req_unregister(stream->loop, stream->connect_req);
|
|
+ stream->connect_req->cb(stream->connect_req, UV_ECANCELED);
|
|
+ stream->connect_req = NULL;
|
|
+ }
|
|
+
|
|
+ uv__stream_flush_write_queue(stream, UV_ECANCELED);
|
|
+ uv__write_callbacks(stream);
|
|
+
|
|
+ if (stream->shutdown_req) {
|
|
+ /* The ECANCELED error code is a lie, the shutdown(2) syscall is a
|
|
+ * fait accompli at this point. Maybe we should revisit this in v0.11.
|
|
+ * A possible reason for leaving it unchanged is that it informs the
|
|
+ * callee that the handle has been destroyed.
|
|
+ */
|
|
+ uv__req_unregister(stream->loop, stream->shutdown_req);
|
|
+ stream->shutdown_req->cb(stream->shutdown_req, UV_ECANCELED);
|
|
+ stream->shutdown_req = NULL;
|
|
+ }
|
|
+
|
|
+ assert(stream->write_queue_size == 0);
|
|
+}
|
|
+
|
|
+#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) */
|
|
+
|
|
+#ifdef CONFIG_LIBUV_NET
|
|
+void uv__server_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
|
+ uv_stream_t* stream;
|
|
+ int err;
|
|
+
|
|
+ stream = container_of(w, uv_stream_t, io_watcher);
|
|
+ assert(events & POLLIN);
|
|
+ assert(stream->accepted_fd == -1);
|
|
+ assert(!(stream->flags & UV_HANDLE_CLOSING));
|
|
+
|
|
+ /* connection_cb can close the server socket while we're
|
|
+ * in the loop so check it on each iteration.
|
|
+ */
|
|
+ while (uv__stream_fd(stream) != -1) {
|
|
+ assert(stream->accepted_fd == -1);
|
|
+
|
|
+ err = uv__accept(uv__stream_fd(stream));
|
|
+ if (err < 0) {
|
|
+ if (err == UV_EAGAIN || err == UV__ERR(EWOULDBLOCK))
|
|
+ return; /* Not an error. */
|
|
+
|
|
+ if (err == UV__ERR(ENOTCONN))
|
|
+ continue; /* Ignore. Nothing we can do about that. */
|
|
+
|
|
+ stream->connection_cb(stream, err);
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ UV_DEC_BACKLOG(w)
|
|
+ stream->accepted_fd = err;
|
|
+ stream->connection_cb(stream, 0);
|
|
+
|
|
+ if (stream->accepted_fd != -1) {
|
|
+ /* The user hasn't yet accepted called uv_accept() */
|
|
+ uv__io_stop(loop, &stream->io_watcher, POLLIN);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+#if 0
|
|
+ if (stream->type == UV_TCP &&
|
|
+ (stream->flags & UV_HANDLE_TCP_SINGLE_ACCEPT)) {
|
|
+ /* Give other processes a chance to accept connections. */
|
|
+ struct timespec timeout = { 0, 1 };
|
|
+ nanosleep(&timeout, NULL);
|
|
+ }
|
|
+#endif
|
|
+ }
|
|
+}
|
|
+#endif
|
|
+
|
|
+#undef UV_DEC_BACKLOG
|
|
+
|
|
+
|
|
+int uv_accept(uv_stream_t* server, uv_stream_t* client) {
|
|
+ int err;
|
|
+
|
|
+ assert(server->loop == client->loop);
|
|
+
|
|
+ if (server->accepted_fd == -1)
|
|
+ return UV_EAGAIN;
|
|
+
|
|
+ switch (client->type) {
|
|
+#ifdef CONFIG_LIBUV_PIPE
|
|
+ case UV_NAMED_PIPE:
|
|
+#endif
|
|
+#ifdef CONFIG_LIBUV_TCP
|
|
+ case UV_TCP:
|
|
+#endif
|
|
+#if defined(CONFIG_LIBUV_PIPE) || defined(CONFIG_LIBUV_TCP)
|
|
+ err = uv__stream_open(client,
|
|
+ server->accepted_fd,
|
|
+ UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
|
|
+ if (err) {
|
|
+ /* TODO handle error */
|
|
+ uv__close(server->accepted_fd);
|
|
+ goto done;
|
|
+ }
|
|
+ break;
|
|
+#endif
|
|
+#ifdef CONFIG_LIBUV_UDP
|
|
+ case UV_UDP:
|
|
+ err = uv_udp_open((uv_udp_t*) client, server->accepted_fd);
|
|
+ if (err) {
|
|
+ uv__close(server->accepted_fd);
|
|
+ goto done;
|
|
+ }
|
|
+ break;
|
|
+#endif
|
|
+
|
|
+ default:
|
|
+ return UV_EINVAL;
|
|
+ }
|
|
+
|
|
+ client->flags |= UV_HANDLE_BOUND;
|
|
+
|
|
+done:
|
|
+
|
|
+ server->accepted_fd = -1;
|
|
+ uv__io_start(server->loop, &server->io_watcher, POLLIN);
|
|
+
|
|
+ return err;
|
|
+}
|
|
+
|
|
+#ifdef CONFIG_LIBUV_NET
|
|
+int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) {
|
|
+ int err;
|
|
+
|
|
+ switch (stream->type) {
|
|
+#ifdef CONFIG_LIBUV_TCP
|
|
+ case UV_TCP:
|
|
+ err = uv_tcp_listen((uv_tcp_t*)stream, backlog, cb);
|
|
+ break;
|
|
+#endif
|
|
+#ifndef __NUTTX__
|
|
+ /* TODO Revist uv_pipe_listen() port */
|
|
+#ifdef CONFIG_LIBUV_PIPE
|
|
+ case UV_NAMED_PIPE:
|
|
+ err = uv_pipe_listen((uv_pipe_t*)stream, backlog, cb);
|
|
+ break;
|
|
+#endif
|
|
+#endif /* !__NUTTX__ */
|
|
+
|
|
+ default:
|
|
+ err = UV_EINVAL;
|
|
+ }
|
|
+
|
|
+ if (err == 0)
|
|
+ uv__handle_start(stream);
|
|
+
|
|
+ return err;
|
|
+}
|
|
+#endif
|
|
+
|
|
+static void uv__drain(uv_stream_t* stream) {
|
|
+ uv_shutdown_t* req;
|
|
+ int err;
|
|
+
|
|
+ assert(QUEUE_EMPTY(&stream->write_queue));
|
|
+ uv__io_stop(stream->loop, &stream->io_watcher, POLLOUT);
|
|
+
|
|
+ /* Shutdown? */
|
|
+ if ((stream->flags & UV_HANDLE_SHUTTING) &&
|
|
+ !(stream->flags & UV_HANDLE_CLOSING) &&
|
|
+ !(stream->flags & UV_HANDLE_SHUT)) {
|
|
+ assert(stream->shutdown_req);
|
|
+
|
|
+ req = stream->shutdown_req;
|
|
+ stream->shutdown_req = NULL;
|
|
+ stream->flags &= ~UV_HANDLE_SHUTTING;
|
|
+ uv__req_unregister(stream->loop, req);
|
|
+
|
|
+ err = 0;
|
|
+
|
|
+#ifndef __NUTTX__
|
|
+ /* shutdown not implemented in NuttX */
|
|
+
|
|
+ if (shutdown(uv__stream_fd(stream), SHUT_WR))
|
|
+ err = UV__ERR(errno);
|
|
+#endif
|
|
+
|
|
+ if (err == 0)
|
|
+ stream->flags |= UV_HANDLE_SHUT;
|
|
+
|
|
+ if (req->cb != NULL)
|
|
+ req->cb(req, err);
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
+static ssize_t uv__writev(int fd, struct iovec* vec, size_t n) {
|
|
+ if (n == 1)
|
|
+ return write(fd, vec->iov_base, vec->iov_len);
|
|
+ else
|
|
+ return writev(fd, vec, n);
|
|
+}
|
|
+
|
|
+
|
|
+static size_t uv__write_req_size(uv_write_t* req) {
|
|
+ size_t size;
|
|
+
|
|
+ assert(req->bufs != NULL);
|
|
+ size = uv__count_bufs(req->bufs + req->write_index,
|
|
+ req->nbufs - req->write_index);
|
|
+ assert(req->handle->write_queue_size >= size);
|
|
+
|
|
+ return size;
|
|
+}
|
|
+
|
|
+
|
|
+/* Returns 1 if all write request data has been written, or 0 if there is still
|
|
+ * more data to write.
|
|
+ *
|
|
+ * Note: the return value only says something about the *current* request.
|
|
+ * There may still be other write requests sitting in the queue.
|
|
+ */
|
|
+static int uv__write_req_update(uv_stream_t* stream,
|
|
+ uv_write_t* req,
|
|
+ size_t n) {
|
|
+ uv_buf_t* buf;
|
|
+ size_t len;
|
|
+
|
|
+ assert(n <= stream->write_queue_size);
|
|
+ stream->write_queue_size -= n;
|
|
+
|
|
+ buf = req->bufs + req->write_index;
|
|
+
|
|
+ do {
|
|
+ len = n < buf->len ? n : buf->len;
|
|
+ buf->base += len;
|
|
+ buf->len -= len;
|
|
+ buf += (buf->len == 0); /* Advance to next buffer if this one is empty. */
|
|
+ n -= len;
|
|
+ } while (n > 0);
|
|
+
|
|
+ req->write_index = buf - req->bufs;
|
|
+
|
|
+ return req->write_index == req->nbufs;
|
|
+}
|
|
+
|
|
+
|
|
+static void uv__write_req_finish(uv_write_t* req) {
|
|
+ uv_stream_t* stream = req->handle;
|
|
+
|
|
+ /* Pop the req off tcp->write_queue. */
|
|
+ QUEUE_REMOVE(&req->queue);
|
|
+
|
|
+ /* Only free when there was no error. On error, we touch up write_queue_size
|
|
+ * right before making the callback. The reason we don't do that right away
|
|
+ * is that a write_queue_size > 0 is our only way to signal to the user that
|
|
+ * they should stop writing - which they should if we got an error. Something
|
|
+ * to revisit in future revisions of the libuv API.
|
|
+ */
|
|
+ if (req->error == 0) {
|
|
+ if (req->bufs != req->bufsml)
|
|
+ uv__free(req->bufs);
|
|
+ req->bufs = NULL;
|
|
+ }
|
|
+
|
|
+ /* Add it to the write_completed_queue where it will have its
|
|
+ * callback called in the near future.
|
|
+ */
|
|
+ QUEUE_INSERT_TAIL(&stream->write_completed_queue, &req->queue);
|
|
+ uv__stream_feed(stream->loop, stream);
|
|
+}
|
|
+
|
|
+#if 0
|
|
+static int uv__handle_fd(uv_handle_t* handle) {
|
|
+ switch (handle->type) {
|
|
+ case UV_NAMED_PIPE:
|
|
+ case UV_TCP:
|
|
+ return ((uv_stream_t*) handle)->io_watcher.fd;
|
|
+
|
|
+ case UV_UDP:
|
|
+ return ((uv_udp_t*) handle)->io_watcher.fd;
|
|
+
|
|
+ default:
|
|
+ return -1;
|
|
+ }
|
|
+}
|
|
+#endif
|
|
+
|
|
+static void uv__write(uv_stream_t* stream) {
|
|
+ struct iovec* iov;
|
|
+ QUEUE* q;
|
|
+ uv_write_t* req;
|
|
+ int iovmax;
|
|
+ int iovcnt;
|
|
+ ssize_t n;
|
|
+ int err;
|
|
+
|
|
+ assert(uv__stream_fd(stream) >= 0);
|
|
+
|
|
+ while (!QUEUE_EMPTY(&stream->write_queue)) {
|
|
+
|
|
+ q = QUEUE_HEAD(&stream->write_queue);
|
|
+ req = QUEUE_DATA(q, uv_write_t, queue);
|
|
+ assert(req->handle == stream);
|
|
+
|
|
+ /*
|
|
+ * Cast to iovec. We had to have our own uv_buf_t instead of iovec
|
|
+ * because Windows's WSABUF is not an iovec.
|
|
+ */
|
|
+ assert(sizeof(uv_buf_t) == sizeof(struct iovec));
|
|
+ iov = (struct iovec*) &(req->bufs[req->write_index]);
|
|
+ iovcnt = req->nbufs - req->write_index;
|
|
+
|
|
+ iovmax = uv__getiovmax();
|
|
+
|
|
+ /* Limit iov count to avoid EINVALs from writev() */
|
|
+ if (iovcnt > iovmax)
|
|
+ iovcnt = iovmax;
|
|
+
|
|
+ /*
|
|
+ * Now do the actual writev. Note that we've been updating the pointers
|
|
+ * inside the iov each time we write. So there is no need to offset it.
|
|
+ */
|
|
+
|
|
+ do {
|
|
+ n = uv__writev(uv__stream_fd(stream), iov, iovcnt);
|
|
+ } while (n == -1 && errno == EINTR);
|
|
+
|
|
+ if (n == -1 &&
|
|
+ errno != EAGAIN &&
|
|
+ errno != EWOULDBLOCK &&
|
|
+ errno != ENOBUFS) {
|
|
+ err = UV__ERR(errno);
|
|
+ goto error;
|
|
+ }
|
|
+
|
|
+ if (n >= 0 && uv__write_req_update(stream, req, n)) {
|
|
+ uv__write_req_finish(req);
|
|
+ continue; /* TODO(bnoordhuis) Start trying to write the next request. */
|
|
+ }
|
|
+
|
|
+ /* If this is a blocking stream, try again. */
|
|
+ if (stream->flags & UV_HANDLE_BLOCKING_WRITES)
|
|
+ continue;
|
|
+
|
|
+ /* Wait for next POLLOUT to continue writing.
|
|
+ * FIXME: what if user called uv_read_stop() before ?
|
|
+ * stream handle may be in invalid state.
|
|
+ */
|
|
+ uv__io_start(stream->loop, &stream->io_watcher, POLLOUT);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ return;
|
|
+
|
|
+error:
|
|
+ req->error = err;
|
|
+ uv__write_req_finish(req);
|
|
+ uv__io_stop(stream->loop, &stream->io_watcher, POLLOUT);
|
|
+ if (!uv__io_active(&stream->io_watcher, POLLIN))
|
|
+ uv__handle_stop(stream);
|
|
+}
|
|
+
|
|
+
|
|
+static void uv__write_callbacks(uv_stream_t* stream) {
|
|
+ uv_write_t* req;
|
|
+ QUEUE* q;
|
|
+ QUEUE pq;
|
|
+
|
|
+ if (QUEUE_EMPTY(&stream->write_completed_queue))
|
|
+ return;
|
|
+
|
|
+ QUEUE_MOVE(&stream->write_completed_queue, &pq);
|
|
+
|
|
+ while (!QUEUE_EMPTY(&pq)) {
|
|
+ /* Pop a req off write_completed_queue. */
|
|
+ q = QUEUE_HEAD(&pq);
|
|
+ req = QUEUE_DATA(q, uv_write_t, queue);
|
|
+ QUEUE_REMOVE(q);
|
|
+ uv__req_unregister(stream->loop, req);
|
|
+
|
|
+ if (req->bufs != NULL) {
|
|
+ stream->write_queue_size -= uv__write_req_size(req);
|
|
+ if (req->bufs != req->bufsml)
|
|
+ uv__free(req->bufs);
|
|
+ req->bufs = NULL;
|
|
+ }
|
|
+
|
|
+ /* NOTE: call callback AFTER freeing the request data. */
|
|
+ if (req->cb)
|
|
+ req->cb(req, req->error);
|
|
+ }
|
|
+}
|
|
+
|
|
+#ifdef CONFIG_LIBUV_NET
|
|
+uv_handle_type uv__handle_type(int fd) {
|
|
+ struct sockaddr_storage ss;
|
|
+ socklen_t sslen;
|
|
+ socklen_t len;
|
|
+ int type;
|
|
+
|
|
+ memset(&ss, 0, sizeof(ss));
|
|
+ sslen = sizeof(ss);
|
|
+
|
|
+ if (getsockname(fd, (struct sockaddr*)&ss, &sslen))
|
|
+ return UV_UNKNOWN_HANDLE;
|
|
+
|
|
+ len = sizeof type;
|
|
+
|
|
+ if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &type, &len))
|
|
+ return UV_UNKNOWN_HANDLE;
|
|
+
|
|
+ if (type == SOCK_STREAM) {
|
|
+#if defined(_AIX) || defined(__DragonFly__)
|
|
+ /* on AIX/DragonFly the getsockname call returns an empty sa structure
|
|
+ * for sockets of type AF_UNIX. For all other types it will
|
|
+ * return a properly filled in structure.
|
|
+ */
|
|
+ if (sslen == 0)
|
|
+ return UV_NAMED_PIPE;
|
|
+#endif
|
|
+ switch (ss.ss_family) {
|
|
+ case AF_UNIX:
|
|
+ return UV_NAMED_PIPE;
|
|
+ case AF_INET:
|
|
+ case AF_INET6:
|
|
+ return UV_TCP;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (type == SOCK_DGRAM &&
|
|
+ (ss.ss_family == AF_INET || ss.ss_family == AF_INET6))
|
|
+ return UV_UDP;
|
|
+
|
|
+ return UV_UNKNOWN_HANDLE;
|
|
+}
|
|
+#endif
|
|
+
|
|
+static void uv__stream_eof(uv_stream_t* stream, const uv_buf_t* buf) {
|
|
+ stream->flags |= UV_HANDLE_READ_EOF;
|
|
+ stream->flags &= ~UV_HANDLE_READING;
|
|
+ uv__io_stop(stream->loop, &stream->io_watcher, POLLIN);
|
|
+ if (!uv__io_active(&stream->io_watcher, POLLOUT))
|
|
+ uv__handle_stop(stream);
|
|
+ stream->read_cb(stream, UV_EOF, buf);
|
|
+}
|
|
+
|
|
+
|
|
+static void uv__read(uv_stream_t* stream) {
|
|
+ uv_buf_t buf;
|
|
+ ssize_t nread;
|
|
+ int count;
|
|
+
|
|
+ stream->flags &= ~UV_HANDLE_READ_PARTIAL;
|
|
+
|
|
+ /* Prevent loop starvation when the data comes in as fast as (or faster than)
|
|
+ * we can read it. XXX Need to rearm fd if we switch to edge-triggered I/O.
|
|
+ */
|
|
+ count = 32;
|
|
+
|
|
+ /* XXX: Maybe instead of having UV_HANDLE_READING we just test if
|
|
+ * tcp->read_cb is NULL or not?
|
|
+ */
|
|
+ while (stream->read_cb
|
|
+ && (stream->flags & UV_HANDLE_READING)
|
|
+ && (count-- > 0)) {
|
|
+ assert(stream->alloc_cb != NULL);
|
|
+
|
|
+ buf = uv_buf_init(NULL, 0);
|
|
+ stream->alloc_cb((uv_handle_t*)stream, CONFIG_LIBUV_STREAM_READ_SIZE, &buf);
|
|
+ if (buf.base == NULL || buf.len == 0) {
|
|
+ /* User indicates it can't or won't handle the read. */
|
|
+ stream->read_cb(stream, UV_ENOBUFS, &buf);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ assert(buf.base != NULL);
|
|
+ assert(uv__stream_fd(stream) >= 0);
|
|
+
|
|
+ do {
|
|
+ nread = read(uv__stream_fd(stream), buf.base, buf.len);
|
|
+ }
|
|
+ while (nread < 0 && errno == EINTR);
|
|
+
|
|
+ if (nread < 0) {
|
|
+ /* Error */
|
|
+ if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
|
+ /* Wait for the next one. */
|
|
+ if (stream->flags & UV_HANDLE_READING) {
|
|
+ uv__io_start(stream->loop, &stream->io_watcher, POLLIN);
|
|
+ }
|
|
+ stream->read_cb(stream, 0, &buf);
|
|
+ } else {
|
|
+ /* Error. User should call uv_close(). */
|
|
+ stream->read_cb(stream, UV__ERR(errno), &buf);
|
|
+ if (stream->flags & UV_HANDLE_READING) {
|
|
+ stream->flags &= ~UV_HANDLE_READING;
|
|
+ uv__io_stop(stream->loop, &stream->io_watcher, POLLIN);
|
|
+ if (!uv__io_active(&stream->io_watcher, POLLOUT))
|
|
+ uv__handle_stop(stream);
|
|
+ }
|
|
+ }
|
|
+ return;
|
|
+ } else if (nread == 0) {
|
|
+ uv__stream_eof(stream, &buf);
|
|
+ return;
|
|
+ } else {
|
|
+ /* Successful read */
|
|
+ ssize_t buflen = buf.len;
|
|
+
|
|
+ stream->read_cb(stream, nread, &buf);
|
|
+
|
|
+ /* Return if we didn't fill the buffer, there is no more data to read. */
|
|
+ if (nread < buflen) {
|
|
+ stream->flags |= UV_HANDLE_READ_PARTIAL;
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
+int uv_shutdown(uv_shutdown_t* req, uv_stream_t* stream, uv_shutdown_cb cb) {
|
|
+ assert(stream->type == UV_TCP ||
|
|
+ stream->type == UV_TTY ||
|
|
+ stream->type == UV_NAMED_PIPE);
|
|
+
|
|
+ if (!(stream->flags & UV_HANDLE_WRITABLE) ||
|
|
+ stream->flags & UV_HANDLE_SHUT ||
|
|
+ stream->flags & UV_HANDLE_SHUTTING ||
|
|
+ uv__is_closing(stream)) {
|
|
+ return UV_ENOTCONN;
|
|
+ }
|
|
+
|
|
+ assert(uv__stream_fd(stream) >= 0);
|
|
+
|
|
+ /* Initialize request */
|
|
+ uv__req_init(stream->loop, req, UV_SHUTDOWN);
|
|
+ req->handle = stream;
|
|
+ req->cb = cb;
|
|
+ stream->shutdown_req = req;
|
|
+ stream->flags |= UV_HANDLE_SHUTTING;
|
|
+
|
|
+ uv__io_start(stream->loop, &stream->io_watcher, POLLOUT);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+static void uv__stream_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
|
|
+ uv_stream_t* stream;
|
|
+
|
|
+ stream = container_of(w, uv_stream_t, io_watcher);
|
|
+
|
|
+ assert(
|
|
+#ifdef CONFIG_LIBUV_NET
|
|
+ stream->type == UV_TCP ||
|
|
+#endif
|
|
+ stream->type == UV_NAMED_PIPE
|
|
+ // || stream->type == UV_TTY
|
|
+ );
|
|
+ assert(!(stream->flags & UV_HANDLE_CLOSING));
|
|
+
|
|
+#ifdef CONFIG_LIBUV_NET
|
|
+ if (stream->connect_req) {
|
|
+ uv__stream_connect(stream);
|
|
+ return;
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ assert(uv__stream_fd(stream) >= 0);
|
|
+
|
|
+ /* Ignore POLLHUP here. Even if it's set, there may still be data to read. */
|
|
+ if (events & (POLLIN | POLLERR | POLLHUP)) {
|
|
+ uv__read(stream);
|
|
+ if (uv__stream_fd(stream) == -1)
|
|
+ return; /* read_cb closed stream. */
|
|
+ }
|
|
+
|
|
+ /* Short-circuit iff POLLHUP is set, the user is still interested in read
|
|
+ * events and uv__read() reported a partial read but not EOF. If the EOF
|
|
+ * flag is set, uv__read() called read_cb with err=UV_EOF and we don't
|
|
+ * have to do anything. If the partial read flag is not set, we can't
|
|
+ * report the EOF yet because there is still data to read.
|
|
+ */
|
|
+ if ((events & POLLHUP) &&
|
|
+ (stream->flags & UV_HANDLE_READING) &&
|
|
+ (stream->flags & UV_HANDLE_READ_PARTIAL) &&
|
|
+ !(stream->flags & UV_HANDLE_READ_EOF)) {
|
|
+ uv_buf_t buf = { NULL, 0 };
|
|
+ uv__stream_eof(stream, &buf);
|
|
+ if (uv__stream_fd(stream) == -1)
|
|
+ return; /* read_cb closed stream. */
|
|
+ }
|
|
+
|
|
+ if (events & (POLLOUT | POLLERR | POLLHUP)) {
|
|
+ /* Called by either real poll event or stream_feed */
|
|
+ uv__write(stream);
|
|
+ uv__write_callbacks(stream);
|
|
+
|
|
+ /* Write queue drained. */
|
|
+ if (QUEUE_EMPTY(&stream->write_queue))
|
|
+ uv__drain(stream);
|
|
+ }
|
|
+}
|
|
+
|
|
+#ifdef CONFIG_LIBUV_NET
|
|
+/**
|
|
+ * We get called here from directly following a call to connect(2).
|
|
+ * In order to determine if we've errored out or succeeded must call
|
|
+ * getsockopt.
|
|
+ */
|
|
+static void uv__stream_connect(uv_stream_t* stream) {
|
|
+ int error;
|
|
+ uv_connect_t* req = stream->connect_req;
|
|
+ socklen_t errorsize = sizeof(int);
|
|
+
|
|
+ assert(stream->type == UV_TCP || stream->type == UV_NAMED_PIPE);
|
|
+ assert(req);
|
|
+
|
|
+ /* Normal situation: we need to get the socket error from the kernel. */
|
|
+ assert(uv__stream_fd(stream) >= 0);
|
|
+ getsockopt(uv__stream_fd(stream),
|
|
+ SOL_SOCKET,
|
|
+ SO_ERROR,
|
|
+ &error,
|
|
+ &errorsize);
|
|
+ error = UV__ERR(error);
|
|
+
|
|
+ if (error == UV__ERR(EINPROGRESS))
|
|
+ return;
|
|
+
|
|
+ stream->connect_req = NULL;
|
|
+ uv__req_unregister(stream->loop, req);
|
|
+
|
|
+ if (error < 0 || QUEUE_EMPTY(&stream->write_queue)) {
|
|
+ uv__io_stop(stream->loop, &stream->io_watcher, POLLOUT);
|
|
+ }
|
|
+
|
|
+ if (req->cb)
|
|
+ req->cb(req, error);
|
|
+
|
|
+ if (uv__stream_fd(stream) == -1)
|
|
+ return;
|
|
+
|
|
+ if (error < 0) {
|
|
+ uv__stream_flush_write_queue(stream, UV_ECANCELED);
|
|
+ uv__write_callbacks(stream);
|
|
+ }
|
|
+}
|
|
+#endif
|
|
+
|
|
+int uv_write2(uv_write_t* req,
|
|
+ uv_stream_t* stream,
|
|
+ const uv_buf_t bufs[],
|
|
+ unsigned int nbufs,
|
|
+ uv_stream_t* send_handle,
|
|
+ uv_write_cb cb) {
|
|
+ int empty_queue;
|
|
+
|
|
+ assert(nbufs > 0);
|
|
+ assert((stream->type == UV_TCP ||
|
|
+ stream->type == UV_NAMED_PIPE ||
|
|
+ stream->type == UV_TTY) &&
|
|
+ "uv_write (unix) does not yet support other types of streams");
|
|
+
|
|
+ if (uv__stream_fd(stream) < 0)
|
|
+ return UV_EBADF;
|
|
+
|
|
+ if (!(stream->flags & UV_HANDLE_WRITABLE))
|
|
+ return UV_EPIPE;
|
|
+
|
|
+ /* It's legal for write_queue_size > 0 even when the write_queue is empty;
|
|
+ * it means there are error-state requests in the write_completed_queue that
|
|
+ * will touch up write_queue_size later, see also uv__write_req_finish().
|
|
+ * We could check that write_queue is empty instead but that implies making
|
|
+ * a write() syscall when we know that the handle is in error mode.
|
|
+ */
|
|
+ empty_queue = (stream->write_queue_size == 0);
|
|
+
|
|
+ /* Initialize the req */
|
|
+ uv__req_init(stream->loop, req, UV_WRITE);
|
|
+ req->cb = cb;
|
|
+ req->handle = stream;
|
|
+ req->error = 0;
|
|
+ // req->send_handle = send_handle;
|
|
+ QUEUE_INIT(&req->queue);
|
|
+
|
|
+ req->bufs = req->bufsml;
|
|
+ if (nbufs > ARRAY_SIZE(req->bufsml))
|
|
+ req->bufs = uv__malloc(nbufs * sizeof(bufs[0]));
|
|
+
|
|
+ if (req->bufs == NULL)
|
|
+ return UV_ENOMEM;
|
|
+
|
|
+ memcpy(req->bufs, bufs, nbufs * sizeof(bufs[0]));
|
|
+ req->nbufs = nbufs;
|
|
+ req->write_index = 0;
|
|
+ stream->write_queue_size += uv__count_bufs(bufs, nbufs);
|
|
+
|
|
+ /* Append the request to write_queue. */
|
|
+ QUEUE_INSERT_TAIL(&stream->write_queue, &req->queue);
|
|
+
|
|
+ /* If the queue was empty when this function began, we should attempt to
|
|
+ * do the write immediately. Otherwise start the write_watcher and wait
|
|
+ * for the fd to become writable.
|
|
+ */
|
|
+ if (stream->connect_req) {
|
|
+ /* Still connecting, do nothing. */
|
|
+ }
|
|
+ else if (empty_queue) {
|
|
+ uv__write(stream);
|
|
+ }
|
|
+ else {
|
|
+ /*
|
|
+ * blocking streams should never have anything in the queue.
|
|
+ * if this assert fires then somehow the blocking stream isn't being
|
|
+ * sufficiently flushed in uv__write.
|
|
+ */
|
|
+ assert(!(stream->flags & UV_HANDLE_BLOCKING_WRITES));
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+/* The buffers to be written must remain valid until the callback is called.
|
|
+ * This is not required for the uv_buf_t array.
|
|
+ */
|
|
+int uv_write(uv_write_t* req,
|
|
+ uv_stream_t* handle,
|
|
+ const uv_buf_t bufs[],
|
|
+ unsigned int nbufs,
|
|
+ uv_write_cb cb) {
|
|
+ return uv_write2(req, handle, bufs, nbufs, NULL, cb);
|
|
+}
|
|
+
|
|
+
|
|
+void uv_try_write_cb(uv_write_t* req, int status) {
|
|
+ /* Should not be called */
|
|
+ abort();
|
|
+}
|
|
+
|
|
+
|
|
+int uv_try_write(uv_stream_t* stream,
|
|
+ const uv_buf_t bufs[],
|
|
+ unsigned int nbufs) {
|
|
+ int r;
|
|
+ int has_pollout;
|
|
+ size_t written;
|
|
+ size_t req_size;
|
|
+ uv_write_t req;
|
|
+
|
|
+ /* Connecting or already writing some data */
|
|
+ if (stream->connect_req != NULL || stream->write_queue_size != 0)
|
|
+ return UV_EAGAIN;
|
|
+
|
|
+ has_pollout = uv__io_active(&stream->io_watcher, POLLOUT);
|
|
+
|
|
+ r = uv_write(&req, stream, bufs, nbufs, uv_try_write_cb);
|
|
+ if (r != 0)
|
|
+ return r;
|
|
+
|
|
+ /* Remove not written bytes from write queue size */
|
|
+ written = uv__count_bufs(bufs, nbufs);
|
|
+ if (req.bufs != NULL)
|
|
+ req_size = uv__write_req_size(&req);
|
|
+ else
|
|
+ req_size = 0;
|
|
+ written -= req_size;
|
|
+ stream->write_queue_size -= req_size;
|
|
+
|
|
+ /* Unqueue request, regardless of immediateness */
|
|
+ QUEUE_REMOVE(&req.queue);
|
|
+ uv__req_unregister(stream->loop, &req);
|
|
+ if (req.bufs != req.bufsml)
|
|
+ uv__free(req.bufs);
|
|
+ req.bufs = NULL;
|
|
+
|
|
+ /* Do not poll for writable, if we wasn't before calling this */
|
|
+ if (!has_pollout) {
|
|
+ uv__io_stop(stream->loop, &stream->io_watcher, POLLOUT);
|
|
+ }
|
|
+
|
|
+ if (written == 0 && req_size != 0)
|
|
+ return req.error < 0 ? req.error : UV_EAGAIN;
|
|
+ else
|
|
+ return written;
|
|
+}
|
|
+
|
|
+
|
|
+int uv_read_start(uv_stream_t* stream,
|
|
+ uv_alloc_cb alloc_cb,
|
|
+ uv_read_cb read_cb) {
|
|
+ assert(stream->type == UV_TCP || stream->type == UV_NAMED_PIPE ||
|
|
+ stream->type == UV_TTY);
|
|
+
|
|
+ if (stream->flags & UV_HANDLE_CLOSING)
|
|
+ return UV_EINVAL;
|
|
+
|
|
+ if (!(stream->flags & UV_HANDLE_READABLE))
|
|
+ return UV_ENOTCONN;
|
|
+
|
|
+ /* The UV_HANDLE_READING flag is irrelevant of the state of the tcp - it just
|
|
+ * expresses the desired state of the user.
|
|
+ */
|
|
+ stream->flags |= UV_HANDLE_READING;
|
|
+
|
|
+ /* TODO: try to do the read inline? */
|
|
+ /* TODO: keep track of tcp state. If we've gotten a EOF then we should
|
|
+ * not start the IO watcher.
|
|
+ */
|
|
+ assert(uv__stream_fd(stream) >= 0);
|
|
+ assert(alloc_cb);
|
|
+
|
|
+ stream->read_cb = read_cb;
|
|
+ stream->alloc_cb = alloc_cb;
|
|
+
|
|
+ uv__io_start(stream->loop, &stream->io_watcher, POLLIN);
|
|
+ uv__handle_start(stream);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+int uv_read_stop(uv_stream_t* stream) {
|
|
+ if (!(stream->flags & UV_HANDLE_READING))
|
|
+ return 0;
|
|
+
|
|
+ stream->flags &= ~UV_HANDLE_READING;
|
|
+ uv__io_stop(stream->loop, &stream->io_watcher, POLLIN);
|
|
+ if (!uv__io_active(&stream->io_watcher, POLLOUT))
|
|
+ uv__handle_stop(stream);
|
|
+
|
|
+ stream->read_cb = NULL;
|
|
+ stream->alloc_cb = NULL;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+int uv_is_readable(const uv_stream_t* stream) {
|
|
+ return !!(stream->flags & UV_HANDLE_READABLE);
|
|
+}
|
|
+
|
|
+
|
|
+int uv_is_writable(const uv_stream_t* stream) {
|
|
+ return !!(stream->flags & UV_HANDLE_WRITABLE);
|
|
+}
|
|
+
|
|
+
|
|
+void uv__stream_close(uv_stream_t* handle) {
|
|
+ QUEUE_REMOVE(&handle->pending_queue);
|
|
+
|
|
+ uv__io_close(handle->loop, &handle->io_watcher);
|
|
+ uv_read_stop(handle);
|
|
+ uv__handle_stop(handle);
|
|
+ handle->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
|
|
+
|
|
+ if (handle->io_watcher.fd != -1) {
|
|
+ /* Don't close stdio file descriptors. Nothing good comes from it. */
|
|
+ if (handle->io_watcher.fd > STDERR_FILENO)
|
|
+ uv__close(handle->io_watcher.fd);
|
|
+ handle->io_watcher.fd = -1;
|
|
+ }
|
|
+
|
|
+ if (handle->accepted_fd != -1) {
|
|
+ uv__close(handle->accepted_fd);
|
|
+ handle->accepted_fd = -1;
|
|
+ }
|
|
+
|
|
+ assert(!uv__io_active(&handle->io_watcher, POLLIN | POLLOUT));
|
|
+}
|
|
+
|
|
+
|
|
+int uv_stream_set_blocking(uv_stream_t* handle, int blocking) {
|
|
+ /* Don't need to check the file descriptor, uv__nonblock()
|
|
+ * will fail with EBADF if it's not valid.
|
|
+ */
|
|
+ return uv__nonblock(uv__stream_fd(handle), !blocking);
|
|
+}
|
|
diff --git a/src/unix/nuttx_tcp.c b/src/unix/nuttx_tcp.c
|
|
new file mode 100644
|
|
index 000000000..ddf4216f7
|
|
--- /dev/null
|
|
+++ b/src/unix/nuttx_tcp.c
|
|
@@ -0,0 +1,311 @@
|
|
+/****************************************************************************
|
|
+ * libuv/src/unix/nuttx_tcp.c
|
|
+ *
|
|
+ * Licensed to the Apache Software Foundation (ASF) under one or more
|
|
+ * contributor license agreements. See the NOTICE file distributed with
|
|
+ * this work for additional information regarding copyright ownership. The
|
|
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
+ * "License"); you may not use this file except in compliance with the
|
|
+ * License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
+ * License for the specific language governing permissions and limitations
|
|
+ * under the License.
|
|
+ *
|
|
+ ****************************************************************************/
|
|
+
|
|
+/* 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 "internal.h"
|
|
+
|
|
+#include <stdlib.h>
|
|
+#include <unistd.h>
|
|
+#include <assert.h>
|
|
+#include <errno.h>
|
|
+
|
|
+static int new_socket(uv_tcp_t* handle, int domain, unsigned long flags) {
|
|
+ int sockfd;
|
|
+ int err;
|
|
+
|
|
+ err = uv__socket(domain, SOCK_STREAM, 0);
|
|
+ if (err < 0)
|
|
+ return err;
|
|
+ sockfd = err;
|
|
+
|
|
+ err = uv__stream_open((uv_stream_t*) handle, sockfd, flags);
|
|
+ if (err) {
|
|
+ uv__close(sockfd);
|
|
+ return err;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int uv_tcp_init(uv_loop_t* loop, uv_tcp_t* tcp) {
|
|
+ uv__stream_init(loop, (uv_stream_t*)tcp, UV_TCP);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+static int maybe_new_socket(uv_tcp_t* handle, int domain, unsigned long flags) {
|
|
+ if (uv__stream_fd(handle) != -1) {
|
|
+ handle->flags |= flags;
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ return new_socket(handle, domain, flags);
|
|
+}
|
|
+
|
|
+int uv__tcp_bind(uv_tcp_t* tcp,
|
|
+ const struct sockaddr* addr,
|
|
+ unsigned int addrlen,
|
|
+ unsigned int flags) {
|
|
+ int err;
|
|
+
|
|
+ err = maybe_new_socket(tcp, addr->sa_family, 0);
|
|
+ if (err)
|
|
+ return err;
|
|
+
|
|
+ errno = 0;
|
|
+ if (bind(tcp->io_watcher.fd, addr, addrlen)) {
|
|
+ return UV__ERR(errno);
|
|
+ }
|
|
+
|
|
+ tcp->flags |= UV_HANDLE_BOUND;
|
|
+
|
|
+#ifdef CONFIG_NET_IPv6
|
|
+ if (addr->sa_family == AF_INET6)
|
|
+ tcp->flags |= UV_HANDLE_IPV6;
|
|
+#endif
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+int uv__tcp_connect(uv_connect_t* req,
|
|
+ uv_tcp_t* handle,
|
|
+ const struct sockaddr* addr,
|
|
+ unsigned int addrlen,
|
|
+ uv_connect_cb cb) {
|
|
+ int err;
|
|
+ int r;
|
|
+
|
|
+ assert(handle->type == UV_TCP);
|
|
+
|
|
+ if (handle->connect_req != NULL)
|
|
+ return UV_EBUSY;
|
|
+
|
|
+ err = maybe_new_socket(handle,
|
|
+ addr->sa_family,
|
|
+ UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
|
|
+ if (err)
|
|
+ return err;
|
|
+
|
|
+ do {
|
|
+ errno = 0;
|
|
+ r = connect(uv__stream_fd(handle), addr, addrlen);
|
|
+ } while (r < 0 && errno == EINTR);
|
|
+
|
|
+ if (r < 0) {
|
|
+ /* FIXME NuttX does not support NONBLOCKING connect,
|
|
+ * no need to check for EINPROGRESS.
|
|
+ *
|
|
+ * if (errno == EINPROGRESS) {
|
|
+ * // This is not an error
|
|
+ * }
|
|
+ */
|
|
+ return UV__ERR(errno);
|
|
+ }
|
|
+
|
|
+ uv__req_init(handle->loop, req, UV_CONNECT);
|
|
+ req->cb = cb;
|
|
+ req->handle = (uv_stream_t*) handle;
|
|
+ QUEUE_INIT(&req->queue);
|
|
+ handle->connect_req = req;
|
|
+
|
|
+ uv__io_start(handle->loop, &handle->io_watcher, POLLOUT);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+#if 0
|
|
+int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock) {
|
|
+ int err;
|
|
+
|
|
+ if (uv__fd_exists(handle->loop, sock))
|
|
+ return UV_EEXIST;
|
|
+
|
|
+ err = uv__nonblock(sock, 1);
|
|
+ if (err)
|
|
+ return err;
|
|
+
|
|
+ return uv__stream_open((uv_stream_t*)handle,
|
|
+ sock,
|
|
+ UV_HANDLE_READABLE | UV_HANDLE_WRITABLE);
|
|
+}
|
|
+#endif
|
|
+
|
|
+int uv_tcp_getsockname(const uv_tcp_t* handle,
|
|
+ struct sockaddr* name,
|
|
+ int* namelen) {
|
|
+ return uv__getsockpeername((const uv_handle_t*) handle,
|
|
+ getsockname,
|
|
+ name,
|
|
+ namelen);
|
|
+}
|
|
+
|
|
+
|
|
+int uv_tcp_getpeername(const uv_tcp_t* handle,
|
|
+ struct sockaddr* name,
|
|
+ int* namelen) {
|
|
+ return uv__getsockpeername((const uv_handle_t*) handle,
|
|
+ getpeername,
|
|
+ name,
|
|
+ namelen);
|
|
+}
|
|
+
|
|
+#if 0
|
|
+int uv_tcp_close_reset(uv_tcp_t* handle, uv_close_cb close_cb) {
|
|
+ int fd;
|
|
+ struct linger l = { 1, 0 };
|
|
+
|
|
+ /* Disallow setting SO_LINGER to zero due to some platform inconsistencies */
|
|
+ if (handle->flags & UV_HANDLE_SHUTTING)
|
|
+ return UV_EINVAL;
|
|
+
|
|
+ fd = uv__stream_fd(handle);
|
|
+ if (0 != setsockopt(fd, SOL_SOCKET, SO_LINGER, &l, sizeof(l)))
|
|
+ return UV__ERR(errno);
|
|
+
|
|
+ uv_close((uv_handle_t*) handle, close_cb);
|
|
+ return 0;
|
|
+}
|
|
+#endif
|
|
+
|
|
+int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) {
|
|
+ unsigned long flags;
|
|
+ int err;
|
|
+
|
|
+ flags = 0;
|
|
+
|
|
+ err = maybe_new_socket(tcp, AF_INET, flags);
|
|
+ if (err)
|
|
+ return err;
|
|
+
|
|
+ if (listen(tcp->io_watcher.fd, backlog))
|
|
+ return UV__ERR(errno);
|
|
+
|
|
+ tcp->connection_cb = cb;
|
|
+ tcp->flags |= UV_HANDLE_BOUND;
|
|
+
|
|
+ /* Start listening for connections. */
|
|
+ tcp->io_watcher.cb = uv__server_io;
|
|
+ uv__io_start(tcp->loop, &tcp->io_watcher, POLLIN);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+#if 0
|
|
+int uv__tcp_nodelay(int fd, int on) {
|
|
+ if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)))
|
|
+ return UV__ERR(errno);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int uv_tcp_nodelay(uv_tcp_t* handle, int on) {
|
|
+ int err;
|
|
+
|
|
+ if (uv__stream_fd(handle) != -1) {
|
|
+ err = uv__tcp_nodelay(uv__stream_fd(handle), on);
|
|
+ if (err)
|
|
+ return err;
|
|
+ }
|
|
+
|
|
+ if (on)
|
|
+ handle->flags |= UV_HANDLE_TCP_NODELAY;
|
|
+ else
|
|
+ handle->flags &= ~UV_HANDLE_TCP_NODELAY;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+#endif
|
|
+
|
|
+#ifdef CONFIG_NET_TCP_KEEPALIVE
|
|
+int uv__tcp_keepalive(int fd, int on, unsigned int delay) {
|
|
+ if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)))
|
|
+ return UV__ERR(errno);
|
|
+
|
|
+#ifdef TCP_KEEPIDLE
|
|
+ if (on) {
|
|
+ int intvl = 1; /* 1 second; same as default on Win32 */
|
|
+ int cnt = 10; /* 10 retries; same as hardcoded on Win32 */
|
|
+ if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &delay, sizeof(delay)))
|
|
+ return UV__ERR(errno);
|
|
+ if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &intvl, sizeof(intvl)))
|
|
+ return UV__ERR(errno);
|
|
+ if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &cnt, sizeof(cnt)))
|
|
+ return UV__ERR(errno);
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ /* Solaris/SmartOS, if you don't support keep-alive,
|
|
+ * then don't advertise it in your system headers...
|
|
+ */
|
|
+ /* FIXME(bnoordhuis) That's possibly because sizeof(delay) should be 1. */
|
|
+#if defined(TCP_KEEPALIVE) && !defined(__sun)
|
|
+ if (on && setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &delay, sizeof(delay)))
|
|
+ return UV__ERR(errno);
|
|
+#endif
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int uv_tcp_keepalive(uv_tcp_t* handle, int on, unsigned int delay) {
|
|
+ int err;
|
|
+
|
|
+ if (uv__stream_fd(handle) != -1) {
|
|
+ err =uv__tcp_keepalive(uv__stream_fd(handle), on, delay);
|
|
+ if (err)
|
|
+ return err;
|
|
+ }
|
|
+
|
|
+ if (on)
|
|
+ handle->flags |= UV_HANDLE_TCP_KEEPALIVE;
|
|
+ else
|
|
+ handle->flags &= ~UV_HANDLE_TCP_KEEPALIVE;
|
|
+
|
|
+ /* TODO Store delay if uv__stream_fd(handle) == -1 but don't want to enlarge
|
|
+ * uv_tcp_t with an int that's almost never used...
|
|
+ */
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+#endif /* CONFIG_NET_TCP_KEEPALIVE */
|
|
+
|
|
+void uv__tcp_close(uv_tcp_t* handle) {
|
|
+ uv__stream_close((uv_stream_t*)handle);
|
|
+}
|
|
diff --git a/src/unix/nuttx_threadpool.c b/src/unix/nuttx_threadpool.c
|
|
new file mode 100644
|
|
index 000000000..ae509db11
|
|
--- /dev/null
|
|
+++ b/src/unix/nuttx_threadpool.c
|
|
@@ -0,0 +1,361 @@
|
|
+/****************************************************************************
|
|
+ * libuv/src/unix/nuttx_threadpool.c
|
|
+ *
|
|
+ * Licensed to the Apache Software Foundation (ASF) under one or more
|
|
+ * contributor license agreements. See the NOTICE file distributed with
|
|
+ * this work for additional information regarding copyright ownership. The
|
|
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
+ * "License"); you may not use this file except in compliance with the
|
|
+ * License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
+ * License for the specific language governing permissions and limitations
|
|
+ * under the License.
|
|
+ *
|
|
+ ****************************************************************************/
|
|
+
|
|
+/* 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-common.h"
|
|
+# include "unix/internal.h"
|
|
+
|
|
+#include <stdlib.h>
|
|
+
|
|
+#ifdef CONFIG_LIBUV_CONTEXT
|
|
+typedef struct worker_priv_s {
|
|
+ uv_sem_t sem;
|
|
+ uv_wq_context_t *ctx;
|
|
+} worker_priv_t;
|
|
+#else
|
|
+static uv_wq_context_t wq_ctx = {
|
|
+ .once = UV_ONCE_INIT;
|
|
+};
|
|
+#endif
|
|
+
|
|
+static void uv__cancelled(struct uv__work* w) {
|
|
+ abort();
|
|
+}
|
|
+
|
|
+
|
|
+/* To avoid deadlock with uv_cancel() it's crucial that the worker
|
|
+ * never holds the global mutex and the loop-local mutex at the same time.
|
|
+ */
|
|
+static void worker(void* arg) {
|
|
+ struct uv__work* w;
|
|
+ QUEUE* q;
|
|
+
|
|
+#ifdef CONFIG_LIBUV_CONTEXT
|
|
+ uv_wq_context_t *ctx = ((volatile worker_priv_t*)arg)->ctx;
|
|
+ uv_sem_post(&((worker_priv_t*) arg)->sem);
|
|
+#else
|
|
+ uv_wq_context_t *ctx = &wq_ctx;
|
|
+ uv_sem_post((uv_sem_t*) arg);
|
|
+#endif
|
|
+
|
|
+ arg = NULL;
|
|
+
|
|
+ uv_mutex_lock(&ctx->mutex);
|
|
+ for (;;) {
|
|
+ /* `mutex` should always be locked at this point. */
|
|
+
|
|
+ /* Keep waiting while either no work is present or only slow I/O
|
|
+ and we're at the threshold for that. */
|
|
+ while (QUEUE_EMPTY(&ctx->wq)) {
|
|
+ ctx->idle_threads += 1;
|
|
+ uv_cond_wait(&ctx->cond, &ctx->mutex);
|
|
+ ctx->idle_threads -= 1;
|
|
+ }
|
|
+
|
|
+ q = QUEUE_HEAD(&ctx->wq);
|
|
+ if (q == &ctx->exit_message) {
|
|
+ uv_cond_signal(&ctx->cond);
|
|
+ uv_mutex_unlock(&ctx->mutex);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ QUEUE_REMOVE(q);
|
|
+ QUEUE_INIT(q); /* Signal uv_cancel() that the work req is executing. */
|
|
+
|
|
+ uv_mutex_unlock(&ctx->mutex);
|
|
+
|
|
+ w = QUEUE_DATA(q, struct uv__work, wq);
|
|
+ w->work(w);
|
|
+
|
|
+ uv_mutex_lock(&w->loop->wq_mutex);
|
|
+ w->work = NULL; /* Signal uv_cancel() that the work req is done
|
|
+ executing. */
|
|
+ QUEUE_INSERT_TAIL(&w->loop->wq, &w->wq);
|
|
+ uv_async_send(&w->loop->wq_async);
|
|
+ uv_mutex_unlock(&w->loop->wq_mutex);
|
|
+
|
|
+ /* Lock `mutex` since that is expected at the start of the next
|
|
+ * iteration. */
|
|
+ uv_mutex_lock(&ctx->mutex);
|
|
+ }
|
|
+}
|
|
+
|
|
+#ifdef CONFIG_LIBUV_CONTEXT
|
|
+static void post(QUEUE* q, enum uv__work_kind kind,
|
|
+ uv_wq_context_t *ctx) {
|
|
+#else
|
|
+static void post(QUEUE* q, enum uv__work_kind kind) {
|
|
+ uv_wq_context_t *ctx = &wq_ctx;
|
|
+#endif
|
|
+ uv_mutex_lock(&ctx->mutex);
|
|
+ QUEUE_INSERT_TAIL(&ctx->wq, q);
|
|
+ if (ctx->idle_threads > 0)
|
|
+ uv_cond_signal(&ctx->cond);
|
|
+ uv_mutex_unlock(&ctx->mutex);
|
|
+}
|
|
+
|
|
+
|
|
+#ifdef CONFIG_LIBUV_CONTEXT
|
|
+static void init_threads(uv_wq_context_t *ctx) {
|
|
+ worker_priv_t worker_priv;
|
|
+ uv_sem_t *psem = &worker_priv.sem;
|
|
+#else
|
|
+static void init_threads(void) {
|
|
+ uv_wq_context_t *ctx = &wq_ctx;
|
|
+ uv_sem_t sem;
|
|
+ uv_sem_t *psem = &sem;
|
|
+#endif
|
|
+ unsigned int i;
|
|
+
|
|
+ if (uv_cond_init(&ctx->cond))
|
|
+ abort();
|
|
+
|
|
+ if (uv_mutex_init(&ctx->mutex))
|
|
+ abort();
|
|
+
|
|
+ QUEUE_INIT(&ctx->wq);
|
|
+
|
|
+#ifdef CONFIG_LIBUV_CONTEXT
|
|
+ worker_priv.ctx = ctx;
|
|
+#endif
|
|
+
|
|
+ if (uv_sem_init(psem, 0))
|
|
+ abort();
|
|
+
|
|
+ for (i = 0; i < ARRAY_SIZE(ctx->default_threads); i++)
|
|
+#ifdef CONFIG_LIBUV_CONTEXT
|
|
+ if (uv_thread_create(ctx->default_threads + i, worker, &worker_priv))
|
|
+#else
|
|
+ if (uv_thread_create(ctx->default_threads + i, worker, &sem))
|
|
+#endif
|
|
+ abort();
|
|
+
|
|
+ for (i = 0; i < ARRAY_SIZE(ctx->default_threads); i++)
|
|
+ uv_sem_wait(psem);
|
|
+
|
|
+ uv_sem_destroy(psem);
|
|
+}
|
|
+
|
|
+#ifndef CONFIG_LIBUV_CONTEXT
|
|
+static void init_once(void) {
|
|
+ init_threads();
|
|
+}
|
|
+#endif
|
|
+
|
|
+
|
|
+#ifdef CONFIG_LIBUV_CONTEXT
|
|
+void uv__threadpool_setup(uv_context_t *context) {
|
|
+ init_threads(&context->wq);
|
|
+}
|
|
+
|
|
+void uv__threadpool_cleanup(uv_context_t *context) {
|
|
+ unsigned int i;
|
|
+ uv_wq_context_t *ctx = &context->wq;
|
|
+#else
|
|
+void uv__threadpool_cleanup(void) {
|
|
+ uv_wq_context_t *ctx = &wq_ctx;
|
|
+ unsigned int i;
|
|
+
|
|
+ if (!ctx->once) {
|
|
+ /* Threads not initialized */
|
|
+ return;
|
|
+ }
|
|
+#endif
|
|
+
|
|
+ post(&ctx->exit_message, UV__WORK_CPU
|
|
+#ifdef CONFIG_LIBUV_CONTEXT
|
|
+ , ctx
|
|
+#endif
|
|
+ );
|
|
+
|
|
+ for (i = 0; i < ARRAY_SIZE(ctx->default_threads); i++)
|
|
+ if (uv_thread_join(ctx->default_threads + i))
|
|
+ abort();
|
|
+
|
|
+ uv_mutex_destroy(&ctx->mutex);
|
|
+ uv_cond_destroy(&ctx->cond);
|
|
+}
|
|
+
|
|
+
|
|
+void uv__work_submit(uv_loop_t* loop,
|
|
+ struct uv__work* w,
|
|
+ enum uv__work_kind kind,
|
|
+ void (*work)(struct uv__work* w),
|
|
+ void (*done)(struct uv__work* w, int status)) {
|
|
+#ifndef CONFIG_LIBUV_CONTEXT
|
|
+ uv_once(&once, init_once);
|
|
+#endif
|
|
+ w->loop = loop;
|
|
+ w->work = work;
|
|
+ w->done = done;
|
|
+ post(&w->wq, kind
|
|
+#ifdef CONFIG_LIBUV_CONTEXT
|
|
+ , &loop->context->wq
|
|
+#endif
|
|
+ );
|
|
+}
|
|
+
|
|
+
|
|
+static int uv__work_cancel(uv_loop_t* loop, uv_req_t* req, struct uv__work* w) {
|
|
+ int cancelled;
|
|
+
|
|
+#ifdef CONFIG_LIBUV_CONTEXT
|
|
+ uv_wq_context_t *ctx = &loop->context->wq;
|
|
+#else
|
|
+ uv_wq_context_t *ctx = &wq_ctx;
|
|
+#endif
|
|
+
|
|
+ uv_mutex_lock(&ctx->mutex);
|
|
+ uv_mutex_lock(&w->loop->wq_mutex);
|
|
+
|
|
+ cancelled = !QUEUE_EMPTY(&w->wq) && w->work != NULL;
|
|
+ if (cancelled)
|
|
+ QUEUE_REMOVE(&w->wq);
|
|
+
|
|
+ uv_mutex_unlock(&w->loop->wq_mutex);
|
|
+ uv_mutex_unlock(&ctx->mutex);
|
|
+
|
|
+ if (!cancelled)
|
|
+ return UV_EBUSY;
|
|
+
|
|
+ w->work = uv__cancelled;
|
|
+ uv_mutex_lock(&loop->wq_mutex);
|
|
+ QUEUE_INSERT_TAIL(&loop->wq, &w->wq);
|
|
+ uv_async_send(&loop->wq_async);
|
|
+ uv_mutex_unlock(&loop->wq_mutex);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+void uv__work_done(uv_async_t* handle) {
|
|
+ struct uv__work* w;
|
|
+ uv_loop_t* loop;
|
|
+ QUEUE* q;
|
|
+ QUEUE wql;
|
|
+ int err;
|
|
+
|
|
+ loop = container_of(handle, uv_loop_t, wq_async);
|
|
+ uv_mutex_lock(&loop->wq_mutex);
|
|
+ QUEUE_MOVE(&loop->wq, &wql);
|
|
+ uv_mutex_unlock(&loop->wq_mutex);
|
|
+
|
|
+ while (!QUEUE_EMPTY(&wql)) {
|
|
+ q = QUEUE_HEAD(&wql);
|
|
+ QUEUE_REMOVE(q);
|
|
+
|
|
+ w = container_of(q, struct uv__work, wq);
|
|
+ err = (w->work == uv__cancelled) ? UV_ECANCELED : 0;
|
|
+ w->done(w, err);
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
+static void uv__queue_work(struct uv__work* w) {
|
|
+ uv_work_t* req = container_of(w, uv_work_t, work_req);
|
|
+
|
|
+ req->work_cb(req);
|
|
+}
|
|
+
|
|
+
|
|
+static void uv__queue_done(struct uv__work* w, int err) {
|
|
+ uv_work_t* req;
|
|
+
|
|
+ req = container_of(w, uv_work_t, work_req);
|
|
+ uv__req_unregister(req->loop, req);
|
|
+
|
|
+ if (req->after_work_cb == NULL)
|
|
+ return;
|
|
+
|
|
+ req->after_work_cb(req, err);
|
|
+}
|
|
+
|
|
+
|
|
+int uv_queue_work(uv_loop_t* loop,
|
|
+ uv_work_t* req,
|
|
+ uv_work_cb work_cb,
|
|
+ uv_after_work_cb after_work_cb) {
|
|
+ if (work_cb == NULL)
|
|
+ return UV_EINVAL;
|
|
+
|
|
+ uv__req_init(loop, req, UV_WORK);
|
|
+ req->loop = loop;
|
|
+ req->work_cb = work_cb;
|
|
+ req->after_work_cb = after_work_cb;
|
|
+ uv__work_submit(loop,
|
|
+ &req->work_req,
|
|
+ UV__WORK_CPU,
|
|
+ uv__queue_work,
|
|
+ uv__queue_done);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+int uv_cancel(uv_req_t* req) {
|
|
+ struct uv__work* wreq;
|
|
+ uv_loop_t* loop;
|
|
+
|
|
+ switch (req->type) {
|
|
+ case UV_FS:
|
|
+ loop = ((uv_fs_t*) req)->loop;
|
|
+ wreq = &((uv_fs_t*) req)->work_req;
|
|
+ break;
|
|
+ case UV_GETADDRINFO:
|
|
+ loop = ((uv_getaddrinfo_t*) req)->loop;
|
|
+ wreq = &((uv_getaddrinfo_t*) req)->work_req;
|
|
+ break;
|
|
+ case UV_GETNAMEINFO:
|
|
+ loop = ((uv_getnameinfo_t*) req)->loop;
|
|
+ wreq = &((uv_getnameinfo_t*) req)->work_req;
|
|
+ break;
|
|
+ case UV_RANDOM:
|
|
+ loop = ((uv_random_t*) req)->loop;
|
|
+ wreq = &((uv_random_t*) req)->work_req;
|
|
+ break;
|
|
+ case UV_WORK:
|
|
+ loop = ((uv_work_t*) req)->loop;
|
|
+ wreq = &((uv_work_t*) req)->work_req;
|
|
+ break;
|
|
+ default:
|
|
+ return UV_EINVAL;
|
|
+ }
|
|
+
|
|
+ return uv__work_cancel(loop, req, wreq);
|
|
+}
|
|
diff --git a/src/unix/nuttx_timer.c b/src/unix/nuttx_timer.c
|
|
new file mode 100644
|
|
index 000000000..d56fdc287
|
|
--- /dev/null
|
|
+++ b/src/unix/nuttx_timer.c
|
|
@@ -0,0 +1,199 @@
|
|
+/****************************************************************************
|
|
+ * libuv/src/unix/nuttx_timer.c
|
|
+ *
|
|
+ * Licensed to the Apache Software Foundation (ASF) under one or more
|
|
+ * contributor license agreements. See the NOTICE file distributed with
|
|
+ * this work for additional information regarding copyright ownership. The
|
|
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
+ * "License"); you may not use this file except in compliance with the
|
|
+ * License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
+ * License for the specific language governing permissions and limitations
|
|
+ * under the License.
|
|
+ *
|
|
+ ****************************************************************************/
|
|
+
|
|
+#include "uv.h"
|
|
+#include "uv-common.h"
|
|
+
|
|
+#include <assert.h>
|
|
+#include <stdlib.h>
|
|
+
|
|
+int uv_timer_init(uv_loop_t* loop, uv_timer_t* handle) {
|
|
+ uv__handle_init(loop, (uv_handle_t*)handle, UV_TIMER);
|
|
+ handle->timer_cb = NULL;
|
|
+ handle->repeat = 0;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+int uv_timer_start(uv_timer_t* handle,
|
|
+ uv_timer_cb cb,
|
|
+ int32_t timeout,
|
|
+ int32_t repeat) {
|
|
+ if (uv__is_closing(handle) || cb == NULL)
|
|
+ return UV_EINVAL;
|
|
+
|
|
+ if (timeout < 0 || repeat < 0) {
|
|
+ return UV_EINVAL;
|
|
+ }
|
|
+
|
|
+ if (uv__is_active(handle))
|
|
+ uv_timer_stop(handle);
|
|
+
|
|
+ handle->timer_cb = cb;
|
|
+ handle->timeout = (uint32_t)handle->loop->time + (uint32_t)timeout;
|
|
+ handle->repeat = repeat;
|
|
+
|
|
+ uv_timer_t *cur_timer = handle->loop->timer_head;
|
|
+
|
|
+ /* If a timer has the same timeout, insert after to preserve timer order */
|
|
+
|
|
+ if (cur_timer == NULL ||
|
|
+ timeout < (int32_t)(cur_timer->timeout-(uint32_t)handle->loop->time)) {
|
|
+ handle->next = cur_timer;
|
|
+ handle->loop->timer_head = handle;
|
|
+ goto exit_start_handle;
|
|
+ }
|
|
+
|
|
+ /* Insert anywhere in timer list */
|
|
+ for (;; cur_timer = cur_timer->next) {
|
|
+ if (cur_timer->next == NULL) {
|
|
+ handle->next = NULL;
|
|
+ cur_timer->next = handle;
|
|
+ goto exit_start_handle;
|
|
+ }
|
|
+
|
|
+ int32_t expiration =
|
|
+ (int32_t)(cur_timer->next->timeout-(uint32_t)handle->loop->time);
|
|
+
|
|
+ if (timeout < expiration) {
|
|
+ handle->next = cur_timer->next;
|
|
+ cur_timer->next = handle;
|
|
+ goto exit_start_handle;
|
|
+ }
|
|
+ }
|
|
+
|
|
+exit_start_handle:
|
|
+ uv__handle_start(handle);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+int uv_timer_stop(uv_timer_t* handle) {
|
|
+ if (!uv__is_active(handle))
|
|
+ return 0;
|
|
+
|
|
+ uv_timer_t *cur_timer = handle->loop->timer_head;
|
|
+
|
|
+ /* Remove if handle is in timer list head */
|
|
+ if (cur_timer == handle) {
|
|
+ handle->loop->timer_head = cur_timer->next;
|
|
+ goto exit_stop_handle;
|
|
+ }
|
|
+
|
|
+ /* Remove anywhere in timer list */
|
|
+ for (;; cur_timer = cur_timer->next) {
|
|
+ if (cur_timer->next == NULL) {
|
|
+ abort();
|
|
+ }
|
|
+
|
|
+ if (cur_timer->next == handle) {
|
|
+ cur_timer->next = handle->next;
|
|
+ goto exit_stop_handle;
|
|
+ }
|
|
+ }
|
|
+
|
|
+exit_stop_handle:
|
|
+ uv__handle_stop(handle);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+int uv_timer_again(uv_timer_t* handle) {
|
|
+ if (handle->timer_cb == NULL)
|
|
+ return UV_EINVAL;
|
|
+
|
|
+ if (handle->repeat) {
|
|
+ uv_timer_stop(handle);
|
|
+ uv_timer_start(handle, handle->timer_cb, handle->repeat, handle->repeat);
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+void uv_timer_set_repeat(uv_timer_t* handle, int32_t repeat) {
|
|
+ handle->repeat = repeat;
|
|
+}
|
|
+
|
|
+
|
|
+int32_t uv_timer_get_repeat(const uv_timer_t* handle) {
|
|
+ return handle->repeat;
|
|
+}
|
|
+
|
|
+
|
|
+int uv__next_timeout(const uv_loop_t* loop) {
|
|
+ if (loop->timer_head == NULL) {
|
|
+ return -1; /* block indefinitely */
|
|
+ }
|
|
+
|
|
+ int32_t expiration =
|
|
+ (int32_t)(loop->timer_head->timeout-(uint32_t)loop->time);
|
|
+
|
|
+ if (expiration <= 0) {
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ return expiration;
|
|
+}
|
|
+
|
|
+
|
|
+void uv__run_timers(uv_loop_t* loop) {
|
|
+ uv_timer_t* handle;
|
|
+
|
|
+ for (;;) {
|
|
+ handle = loop->timer_head;
|
|
+
|
|
+ if (handle == NULL) {
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ int32_t expiration =
|
|
+ (int32_t)(handle->timeout-(uint32_t)loop->time);
|
|
+
|
|
+ if (expiration > 0) {
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ uv_timer_stop(handle);
|
|
+
|
|
+ if (handle->repeat) {
|
|
+ uv_interval_t new_timeout;
|
|
+ if (handle->repeat+expiration <= 0) {
|
|
+ new_timeout = 0;
|
|
+ }
|
|
+ else {
|
|
+ new_timeout = handle->repeat+expiration;
|
|
+ }
|
|
+ uv_timer_start(handle,
|
|
+ handle->timer_cb,
|
|
+ new_timeout,
|
|
+ handle->repeat);
|
|
+ }
|
|
+
|
|
+ handle->timer_cb(handle);
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
+void uv__timer_close(uv_timer_t* handle) {
|
|
+ uv_timer_stop(handle);
|
|
+}
|
|
diff --git a/src/unix/pipe.c b/src/unix/pipe.c
|
|
index 040d57817..7d6105083 100644
|
|
--- a/src/unix/pipe.c
|
|
+++ b/src/unix/pipe.c
|
|
@@ -39,7 +39,8 @@ int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) {
|
|
return 0;
|
|
}
|
|
|
|
-
|
|
+// #ifdef CONFIG_LIBUV_NET
|
|
+#if 0
|
|
int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
|
|
struct sockaddr_un saddr;
|
|
const char* pipe_fname;
|
|
@@ -115,7 +116,7 @@ int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) {
|
|
uv__io_start(handle->loop, &handle->io_watcher, POLLIN);
|
|
return 0;
|
|
}
|
|
-
|
|
+#endif
|
|
|
|
void uv__pipe_close(uv_pipe_t* handle) {
|
|
if (handle->pipe_fname) {
|
|
@@ -169,7 +170,8 @@ int uv_pipe_open(uv_pipe_t* handle, uv_file fd) {
|
|
return uv__stream_open((uv_stream_t*)handle, fd, flags);
|
|
}
|
|
|
|
-
|
|
+// #ifdef CONFIG_LIBUV_NET
|
|
+#if 0
|
|
void uv_pipe_connect(uv_connect_t* req,
|
|
uv_pipe_t* handle,
|
|
const char* name,
|
|
@@ -198,6 +200,10 @@ void uv_pipe_connect(uv_connect_t* req,
|
|
}
|
|
while (r == -1 && errno == EINTR);
|
|
|
|
+ /* FIXME NuttX does not support NONBLOCKING connect,
|
|
+ * no need to check for EINPROGRESS.
|
|
+ */
|
|
+
|
|
if (r == -1 && errno != EINPROGRESS) {
|
|
err = UV__ERR(errno);
|
|
#if defined(__CYGWIN__) || defined(__MSYS__)
|
|
@@ -230,10 +236,13 @@ out:
|
|
req->cb = cb;
|
|
QUEUE_INIT(&req->queue);
|
|
|
|
+#ifdef __NUTTX__
|
|
+ return 0;
|
|
+#else
|
|
/* Force callback to run on next tick in case of error. */
|
|
if (err)
|
|
- uv__io_feed(handle->loop, &handle->io_watcher);
|
|
-
|
|
+ uv__stream_feed(handle->loop, (uv_stream_t*)handle);
|
|
+#endif
|
|
}
|
|
|
|
|
|
@@ -280,7 +289,6 @@ static int uv__pipe_getsockpeername(const uv_pipe_t* handle,
|
|
return 0;
|
|
}
|
|
|
|
-
|
|
int uv_pipe_getsockname(const uv_pipe_t* handle, char* buffer, size_t* size) {
|
|
return uv__pipe_getsockpeername(handle, getsockname, buffer, size);
|
|
}
|
|
@@ -289,8 +297,9 @@ int uv_pipe_getsockname(const uv_pipe_t* handle, char* buffer, size_t* size) {
|
|
int uv_pipe_getpeername(const uv_pipe_t* handle, char* buffer, size_t* size) {
|
|
return uv__pipe_getsockpeername(handle, getpeername, buffer, size);
|
|
}
|
|
+#endif
|
|
|
|
-
|
|
+#if 0
|
|
void uv_pipe_pending_instances(uv_pipe_t* handle, int count) {
|
|
}
|
|
|
|
@@ -379,3 +388,4 @@ int uv_pipe_chmod(uv_pipe_t* handle, int mode) {
|
|
|
|
return r != -1 ? 0 : UV__ERR(errno);
|
|
}
|
|
+#endif
|
|
diff --git a/src/unix/poll.c b/src/unix/poll.c
|
|
index 3d5022b22..d2f442132 100644
|
|
--- a/src/unix/poll.c
|
|
+++ b/src/unix/poll.c
|
|
@@ -1,3 +1,23 @@
|
|
+/****************************************************************************
|
|
+ * src/unix/poll.c
|
|
+ *
|
|
+ * Licensed to the Apache Software Foundation (ASF) under one or more
|
|
+ * contributor license agreements. See the NOTICE file distributed with
|
|
+ * this work for additional information regarding copyright ownership. The
|
|
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
+ * "License"); you may not use this file except in compliance with the
|
|
+ * License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
+ * License for the specific language governing permissions and limitations
|
|
+ * under the License.
|
|
+ *
|
|
+ ****************************************************************************/
|
|
+
|
|
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
@@ -75,6 +95,11 @@ int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) {
|
|
if (err)
|
|
return err;
|
|
|
|
+#ifdef __NUTTX__
|
|
+ err = uv__nonblock(fd, 1);
|
|
+ if (err)
|
|
+ return err;
|
|
+#else
|
|
/* If ioctl(FIONBIO) reports ENOTTY, try fcntl(F_GETFL) + fcntl(F_SETFL).
|
|
* Workaround for e.g. kqueue fds not supporting ioctls.
|
|
*/
|
|
@@ -85,6 +110,7 @@ int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) {
|
|
|
|
if (err)
|
|
return err;
|
|
+#endif
|
|
|
|
uv__handle_init(loop, (uv_handle_t*) handle, UV_POLL);
|
|
uv__io_init(&handle->io_watcher, uv__poll_io, fd);
|
|
diff --git a/src/unix/process.c b/src/unix/process.c
|
|
index b021aaeba..7abed9f0f 100644
|
|
--- a/src/unix/process.c
|
|
+++ b/src/unix/process.c
|
|
@@ -1,3 +1,23 @@
|
|
+/****************************************************************************
|
|
+ * src/unix/process.c
|
|
+ *
|
|
+ * Licensed to the Apache Software Foundation (ASF) under one or more
|
|
+ * contributor license agreements. See the NOTICE file distributed with
|
|
+ * this work for additional information regarding copyright ownership. The
|
|
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
+ * "License"); you may not use this file except in compliance with the
|
|
+ * License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
+ * License for the specific language governing permissions and limitations
|
|
+ * under the License.
|
|
+ *
|
|
+ ****************************************************************************/
|
|
+
|
|
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
@@ -111,7 +131,7 @@ static void uv__chld(uv_signal_t* handle, int signum) {
|
|
assert(QUEUE_EMPTY(&pending));
|
|
}
|
|
|
|
-
|
|
+#if 0
|
|
static int uv__make_socketpair(int fds[2]) {
|
|
#if defined(__FreeBSD__) || defined(__linux__)
|
|
if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, fds))
|
|
@@ -137,7 +157,7 @@ static int uv__make_socketpair(int fds[2]) {
|
|
return 0;
|
|
#endif
|
|
}
|
|
-
|
|
+#endif
|
|
|
|
int uv__make_pipe(int fds[2], int flags) {
|
|
#if defined(__FreeBSD__) || defined(__linux__)
|
|
@@ -172,7 +192,7 @@ fail:
|
|
#endif
|
|
}
|
|
|
|
-
|
|
+#if 0
|
|
/*
|
|
* Used for initializing stdio streams like options.stdin_stream. Returns
|
|
* zero on success. See also the cleanup section in uv_spawn().
|
|
@@ -243,7 +263,7 @@ static void uv__process_close_stream(uv_stdio_container_t* container) {
|
|
if (!(container->flags & UV_CREATE_PIPE)) return;
|
|
uv__stream_close(container->data.stream);
|
|
}
|
|
-
|
|
+#endif
|
|
|
|
static void uv__write_int(int fd, int val) {
|
|
ssize_t n;
|
|
@@ -259,7 +279,8 @@ static void uv__write_int(int fd, int val) {
|
|
}
|
|
|
|
|
|
-#if !(defined(__APPLE__) && (TARGET_OS_TV || TARGET_OS_WATCH))
|
|
+#if !(defined(__APPLE__) && (TARGET_OS_TV || TARGET_OS_WATCH)) \
|
|
+ && !defined(__NUTTX__)
|
|
/* execvp is marked __WATCHOS_PROHIBITED __TVOS_PROHIBITED, so must be
|
|
* avoided. Since this isn't called on those targets, the function
|
|
* doesn't even need to be defined for them.
|
|
@@ -404,7 +425,7 @@ static void uv__process_child_init(const uv_process_options_t* options,
|
|
}
|
|
#endif
|
|
|
|
-
|
|
+#if 0
|
|
int uv_spawn(uv_loop_t* loop,
|
|
uv_process_t* process,
|
|
const uv_process_options_t* options) {
|
|
@@ -572,7 +593,7 @@ error:
|
|
return err;
|
|
#endif
|
|
}
|
|
-
|
|
+#endif
|
|
|
|
int uv_process_kill(uv_process_t* process, int signum) {
|
|
return uv_kill(process->pid, signum);
|
|
diff --git a/src/unix/random-devurandom.c b/src/unix/random-devurandom.c
|
|
index 05e52a56a..dd6f5c438 100644
|
|
--- a/src/unix/random-devurandom.c
|
|
+++ b/src/unix/random-devurandom.c
|
|
@@ -25,16 +25,23 @@
|
|
#include <sys/stat.h>
|
|
#include <unistd.h>
|
|
|
|
+#ifndef __NUTTX__
|
|
static uv_once_t once = UV_ONCE_INIT;
|
|
static int status;
|
|
-
|
|
+#endif
|
|
|
|
int uv__random_readpath(const char* path, void* buf, size_t buflen) {
|
|
- struct stat s;
|
|
size_t pos;
|
|
ssize_t n;
|
|
int fd;
|
|
|
|
+#ifdef __NUTTX__
|
|
+ fd = open(path, O_RDONLY);
|
|
+ if (fd < 0)
|
|
+ return fd;
|
|
+#else
|
|
+ struct stat s;
|
|
+
|
|
fd = uv__open_cloexec(path, O_RDONLY);
|
|
|
|
if (fd < 0)
|
|
@@ -49,6 +56,7 @@ int uv__random_readpath(const char* path, void* buf, size_t buflen) {
|
|
uv__close(fd);
|
|
return UV_EIO;
|
|
}
|
|
+#endif
|
|
|
|
for (pos = 0; pos != buflen; pos += n) {
|
|
do
|
|
@@ -70,7 +78,7 @@ int uv__random_readpath(const char* path, void* buf, size_t buflen) {
|
|
return 0;
|
|
}
|
|
|
|
-
|
|
+#ifndef __NUTTX__
|
|
static void uv__random_devurandom_init(void) {
|
|
char c;
|
|
|
|
@@ -81,13 +89,14 @@ static void uv__random_devurandom_init(void) {
|
|
*/
|
|
status = uv__random_readpath("/dev/random", &c, 1);
|
|
}
|
|
-
|
|
+#endif
|
|
|
|
int uv__random_devurandom(void* buf, size_t buflen) {
|
|
+#ifndef __NUTTX__
|
|
uv_once(&once, uv__random_devurandom_init);
|
|
|
|
if (status != 0)
|
|
return status;
|
|
-
|
|
+#endif
|
|
return uv__random_readpath("/dev/urandom", buf, buflen);
|
|
}
|
|
diff --git a/src/unix/thread.c b/src/unix/thread.c
|
|
index 1a85d1d4f..479a20b90 100644
|
|
--- a/src/unix/thread.c
|
|
+++ b/src/unix/thread.c
|
|
@@ -1,3 +1,23 @@
|
|
+/****************************************************************************
|
|
+ * src/unix/thread.c
|
|
+ *
|
|
+ * Licensed to the Apache Software Foundation (ASF) under one or more
|
|
+ * contributor license agreements. See the NOTICE file distributed with
|
|
+ * this work for additional information regarding copyright ownership. The
|
|
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
+ * "License"); you may not use this file except in compliance with the
|
|
+ * License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
+ * License for the specific language governing permissions and limitations
|
|
+ * under the License.
|
|
+ *
|
|
+ ****************************************************************************/
|
|
+
|
|
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
@@ -161,7 +181,7 @@ void uv_barrier_destroy(uv_barrier_t* barrier) {
|
|
|
|
#endif
|
|
|
|
-
|
|
+#if 0
|
|
/* On MacOS, threads other than the main thread are created with a reduced
|
|
* stack size by default. Adjust to RLIMIT_STACK aligned to the page size.
|
|
*
|
|
@@ -205,14 +225,19 @@ static size_t thread_stack_size(void) {
|
|
return 2 << 20; /* glibc default. */
|
|
#endif
|
|
}
|
|
-
|
|
+#endif
|
|
|
|
int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) {
|
|
+#ifdef __NUTTX__
|
|
+ return pthread_create(tid, NULL, (pthread_startroutine_t)entry, arg);
|
|
+#else
|
|
uv_thread_options_t params;
|
|
params.flags = UV_THREAD_NO_FLAGS;
|
|
return uv_thread_create_ex(tid, ¶ms, entry, arg);
|
|
+#endif
|
|
}
|
|
|
|
+#if 0
|
|
int uv_thread_create_ex(uv_thread_t* tid,
|
|
const uv_thread_options_t* params,
|
|
void (*entry)(void *arg),
|
|
@@ -263,7 +288,7 @@ int uv_thread_create_ex(uv_thread_t* tid,
|
|
|
|
return UV__ERR(err);
|
|
}
|
|
-
|
|
+#endif
|
|
|
|
uv_thread_t uv_thread_self(void) {
|
|
return pthread_self();
|
|
@@ -280,7 +305,7 @@ int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2) {
|
|
|
|
|
|
int uv_mutex_init(uv_mutex_t* mutex) {
|
|
-#if defined(NDEBUG) || !defined(PTHREAD_MUTEX_ERRORCHECK)
|
|
+#if defined(NDEBUG) || !defined(PTHREAD_MUTEX_ERRORCHECK) || defined(__NUTTX__)
|
|
return UV__ERR(pthread_mutex_init(mutex, NULL));
|
|
#else
|
|
pthread_mutexattr_t attr;
|
|
@@ -709,9 +734,11 @@ int uv_cond_init(uv_cond_t* cond) {
|
|
if (err)
|
|
return UV__ERR(err);
|
|
|
|
+#ifndef __NUTTX__
|
|
err = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
|
|
if (err)
|
|
goto error2;
|
|
+#endif
|
|
|
|
err = pthread_cond_init(cond, &attr);
|
|
if (err)
|
|
diff --git a/src/uv-common.c b/src/uv-common.c
|
|
index 0cfb921e6..6eaee4902 100644
|
|
--- a/src/uv-common.c
|
|
+++ b/src/uv-common.c
|
|
@@ -1,3 +1,23 @@
|
|
+/****************************************************************************
|
|
+ * src/uv-common.c
|
|
+ *
|
|
+ * Licensed to the Apache Software Foundation (ASF) under one or more
|
|
+ * contributor license agreements. See the NOTICE file distributed with
|
|
+ * this work for additional information regarding copyright ownership. The
|
|
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
+ * "License"); you may not use this file except in compliance with the
|
|
+ * License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
+ * License for the specific language governing permissions and limitations
|
|
+ * under the License.
|
|
+ *
|
|
+ ****************************************************************************/
|
|
+
|
|
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
@@ -217,7 +237,8 @@ const char* uv_strerror(int err) {
|
|
}
|
|
#undef UV_STRERROR_GEN
|
|
|
|
-
|
|
+#ifdef CONFIG_LIBUV_TCP
|
|
+#ifdef CONFIG_NET_IPv4
|
|
int uv_ip4_addr(const char* ip, int port, struct sockaddr_in* addr) {
|
|
memset(addr, 0, sizeof(*addr));
|
|
addr->sin_family = AF_INET;
|
|
@@ -228,7 +249,12 @@ int uv_ip4_addr(const char* ip, int port, struct sockaddr_in* addr) {
|
|
return uv_inet_pton(AF_INET, ip, &(addr->sin_addr.s_addr));
|
|
}
|
|
|
|
+int uv_ip4_name(const struct sockaddr_in* src, char* dst, size_t size) {
|
|
+ return uv_inet_ntop(AF_INET, &src->sin_addr, dst, size);
|
|
+}
|
|
+#endif
|
|
|
|
+#ifdef CONFIG_NET_IPv6
|
|
int uv_ip6_addr(const char* ip, int port, struct sockaddr_in6* addr) {
|
|
char address_part[40];
|
|
size_t address_part_size;
|
|
@@ -263,16 +289,10 @@ int uv_ip6_addr(const char* ip, int port, struct sockaddr_in6* addr) {
|
|
return uv_inet_pton(AF_INET6, ip, &addr->sin6_addr);
|
|
}
|
|
|
|
-
|
|
-int uv_ip4_name(const struct sockaddr_in* src, char* dst, size_t size) {
|
|
- return uv_inet_ntop(AF_INET, &src->sin_addr, dst, size);
|
|
-}
|
|
-
|
|
-
|
|
int uv_ip6_name(const struct sockaddr_in6* src, char* dst, size_t size) {
|
|
return uv_inet_ntop(AF_INET6, &src->sin6_addr, dst, size);
|
|
}
|
|
-
|
|
+#endif
|
|
|
|
int uv_tcp_bind(uv_tcp_t* handle,
|
|
const struct sockaddr* addr,
|
|
@@ -282,17 +302,48 @@ int uv_tcp_bind(uv_tcp_t* handle,
|
|
if (handle->type != UV_TCP)
|
|
return UV_EINVAL;
|
|
|
|
+#ifdef CONFIG_NET_IPv4
|
|
if (addr->sa_family == AF_INET)
|
|
addrlen = sizeof(struct sockaddr_in);
|
|
- else if (addr->sa_family == AF_INET6)
|
|
+ else
|
|
+#endif
|
|
+#ifdef CONFIG_NET_IPv6
|
|
+ if (addr->sa_family == AF_INET6)
|
|
addrlen = sizeof(struct sockaddr_in6);
|
|
else
|
|
+#endif
|
|
return UV_EINVAL;
|
|
|
|
return uv__tcp_bind(handle, addr, addrlen, flags);
|
|
}
|
|
|
|
|
|
+int uv_tcp_connect(uv_connect_t* req,
|
|
+ uv_tcp_t* handle,
|
|
+ const struct sockaddr* addr,
|
|
+ uv_connect_cb cb) {
|
|
+ unsigned int addrlen;
|
|
+
|
|
+ if (handle->type != UV_TCP)
|
|
+ return UV_EINVAL;
|
|
+
|
|
+#ifdef CONFIG_NET_IPv4
|
|
+ if (addr->sa_family == AF_INET)
|
|
+ addrlen = sizeof(struct sockaddr_in);
|
|
+ else
|
|
+#endif
|
|
+#ifdef CONFIG_NET_IPv6
|
|
+ if (addr->sa_family == AF_INET6)
|
|
+ addrlen = sizeof(struct sockaddr_in6);
|
|
+ else
|
|
+#endif
|
|
+ return UV_EINVAL;
|
|
+
|
|
+ return uv__tcp_connect(req, handle, addr, addrlen, cb);
|
|
+}
|
|
+#endif /* CONFIG_LIBUV_TCP */
|
|
+
|
|
+#ifdef CONFIG_LIBUV_UDP
|
|
int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned flags) {
|
|
unsigned extra_flags;
|
|
int domain;
|
|
@@ -342,26 +393,6 @@ int uv_udp_bind(uv_udp_t* handle,
|
|
}
|
|
|
|
|
|
-int uv_tcp_connect(uv_connect_t* req,
|
|
- uv_tcp_t* handle,
|
|
- const struct sockaddr* addr,
|
|
- uv_connect_cb cb) {
|
|
- unsigned int addrlen;
|
|
-
|
|
- if (handle->type != UV_TCP)
|
|
- return UV_EINVAL;
|
|
-
|
|
- if (addr->sa_family == AF_INET)
|
|
- addrlen = sizeof(struct sockaddr_in);
|
|
- else if (addr->sa_family == AF_INET6)
|
|
- addrlen = sizeof(struct sockaddr_in6);
|
|
- else
|
|
- return UV_EINVAL;
|
|
-
|
|
- return uv__tcp_connect(req, handle, addr, addrlen, cb);
|
|
-}
|
|
-
|
|
-
|
|
int uv_udp_connect(uv_udp_t* handle, const struct sockaddr* addr) {
|
|
unsigned int addrlen;
|
|
|
|
@@ -481,7 +512,7 @@ int uv_udp_recv_stop(uv_udp_t* handle) {
|
|
else
|
|
return uv__udp_recv_stop(handle);
|
|
}
|
|
-
|
|
+#endif
|
|
|
|
void uv_walk(uv_loop_t* loop, uv_walk_cb walk_cb, void* arg) {
|
|
QUEUE queue;
|
|
@@ -507,8 +538,12 @@ static void uv__print_handles(uv_loop_t* loop, int only_active, FILE* stream) {
|
|
QUEUE* q;
|
|
uv_handle_t* h;
|
|
|
|
+#ifdef CONFIG_LIBUV_CONTEXT
|
|
+ assert(loop != NULL);
|
|
+#else
|
|
if (loop == NULL)
|
|
loop = uv_default_loop();
|
|
+#endif
|
|
|
|
QUEUE_FOREACH(q, &loop->handle_queue) {
|
|
h = QUEUE_DATA(q, uv_handle_t, handle_queue);
|
|
@@ -564,7 +599,7 @@ void uv_stop(uv_loop_t* loop) {
|
|
}
|
|
|
|
|
|
-uint64_t uv_now(const uv_loop_t* loop) {
|
|
+uv_time_t uv_now(const uv_loop_t* loop) {
|
|
return loop->time;
|
|
}
|
|
|
|
@@ -581,6 +616,7 @@ size_t uv__count_bufs(const uv_buf_t bufs[], unsigned int nbufs) {
|
|
return bytes;
|
|
}
|
|
|
|
+#if 0
|
|
int uv_recv_buffer_size(uv_handle_t* handle, int* value) {
|
|
return uv__socket_sockopt(handle, SO_RCVBUF, value);
|
|
}
|
|
@@ -588,6 +624,7 @@ int uv_recv_buffer_size(uv_handle_t* handle, int* value) {
|
|
int uv_send_buffer_size(uv_handle_t* handle, int *value) {
|
|
return uv__socket_sockopt(handle, SO_SNDBUF, value);
|
|
}
|
|
+#endif
|
|
|
|
int uv_fs_event_getpath(uv_fs_event_t* handle, char* buffer, size_t* size) {
|
|
size_t required_len;
|
|
@@ -742,7 +779,7 @@ void uv__fs_readdir_cleanup(uv_fs_t* req) {
|
|
}
|
|
}
|
|
|
|
-
|
|
+#if 0
|
|
int uv_loop_configure(uv_loop_t* loop, uv_loop_option option, ...) {
|
|
va_list ap;
|
|
int err;
|
|
@@ -754,7 +791,22 @@ int uv_loop_configure(uv_loop_t* loop, uv_loop_option option, ...) {
|
|
|
|
return err;
|
|
}
|
|
+#endif
|
|
+
|
|
+#ifdef CONFIG_LIBUV_CONTEXT
|
|
+
|
|
+uv_loop_t* uv_default_loop(uv_context_t *ctx) {
|
|
+ if (ctx->default_loop_ptr != NULL)
|
|
+ return ctx->default_loop_ptr;
|
|
|
|
+ if (uv_loop_init(&ctx->default_loop, ctx))
|
|
+ return NULL;
|
|
+
|
|
+ ctx->default_loop_ptr = &ctx->default_loop;
|
|
+ return ctx->default_loop_ptr;
|
|
+}
|
|
+
|
|
+#else /* CONFIG_LIBUV_CONTEXT */
|
|
|
|
static uv_loop_t default_loop_struct;
|
|
static uv_loop_t* default_loop_ptr;
|
|
@@ -770,16 +822,24 @@ uv_loop_t* uv_default_loop(void) {
|
|
default_loop_ptr = &default_loop_struct;
|
|
return default_loop_ptr;
|
|
}
|
|
+#endif /* CONFIG_LIBUV_CONTEXT */
|
|
|
|
-
|
|
+#ifdef CONFIG_LIBUV_CONTEXT
|
|
+uv_loop_t* uv_loop_new(uv_context_t *ctx) {
|
|
+#else
|
|
uv_loop_t* uv_loop_new(void) {
|
|
+#endif
|
|
uv_loop_t* loop;
|
|
|
|
loop = uv__malloc(sizeof(*loop));
|
|
if (loop == NULL)
|
|
return NULL;
|
|
|
|
+#ifdef CONFIG_LIBUV_CONTEXT
|
|
+ if (uv_loop_init(loop, ctx)) {
|
|
+#else
|
|
if (uv_loop_init(loop)) {
|
|
+#endif
|
|
uv__free(loop);
|
|
return NULL;
|
|
}
|
|
@@ -806,13 +866,19 @@ int uv_loop_close(uv_loop_t* loop) {
|
|
|
|
uv__loop_close(loop);
|
|
|
|
+#ifdef CONFIG_LIBUV_CONTEXT
|
|
+ if (loop == loop->context->default_loop_ptr)
|
|
+ loop->context->default_loop_ptr = NULL;
|
|
+#else
|
|
+ if (loop == default_loop_ptr)
|
|
+ default_loop_ptr = NULL;
|
|
+#endif
|
|
+
|
|
#ifndef NDEBUG
|
|
saved_data = loop->data;
|
|
memset(loop, -1, sizeof(*loop));
|
|
loop->data = saved_data;
|
|
#endif
|
|
- if (loop == default_loop_ptr)
|
|
- default_loop_ptr = NULL;
|
|
|
|
return 0;
|
|
}
|
|
@@ -822,7 +888,11 @@ void uv_loop_delete(uv_loop_t* loop) {
|
|
uv_loop_t* default_loop;
|
|
int err;
|
|
|
|
+#ifdef CONFIG_LIBUV_CONTEXT
|
|
+ default_loop = loop->context->default_loop_ptr;
|
|
+#else
|
|
default_loop = default_loop_ptr;
|
|
+#endif
|
|
|
|
err = uv_loop_close(loop);
|
|
(void) err; /* Squelch compiler warnings. */
|
|
@@ -852,18 +922,51 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) {
|
|
uv__free(cpu_infos);
|
|
}
|
|
|
|
+#ifdef CONFIG_LIBUV_CONTEXT
|
|
+void uv_library_init(uv_context_t *ctx) {
|
|
+ memset(ctx, 0, sizeof(*ctx));
|
|
+ uv__process_title_setup(ctx);
|
|
+
|
|
+#ifdef CONFIG_LIBUV_SIGNAL
|
|
+ uv__signal_setup(ctx);
|
|
+#endif
|
|
+
|
|
+#ifdef CONFIG_LIBUV_WQ
|
|
+ uv__threadpool_setup(ctx);
|
|
+#endif
|
|
+}
|
|
+
|
|
+void uv_library_shutdown(uv_context_t *ctx) {
|
|
+ uv__process_title_cleanup(ctx);
|
|
+
|
|
+#ifdef CONFIG_LIBUV_SIGNAL
|
|
+ uv__signal_cleanup(ctx);
|
|
+#endif
|
|
+
|
|
+#ifdef CONFIG_LIBUV_WQ
|
|
+ uv__threadpool_cleanup(ctx);
|
|
+#endif
|
|
+}
|
|
+
|
|
+#else /* CONFIG_LIBUV_CONTEXT */
|
|
|
|
#ifdef __GNUC__ /* Also covers __clang__ and __INTEL_COMPILER. */
|
|
__attribute__((destructor))
|
|
#endif
|
|
void uv_library_shutdown(void) {
|
|
static int was_shutdown;
|
|
-
|
|
if (uv__load_relaxed(&was_shutdown))
|
|
return;
|
|
|
|
uv__process_title_cleanup();
|
|
+#ifdef CONFIG_LIBUV_SIGNAL
|
|
uv__signal_cleanup();
|
|
+#endif
|
|
+
|
|
+#ifdef CONFIG_LIBUV_WQ
|
|
uv__threadpool_cleanup();
|
|
+#endif
|
|
+
|
|
uv__store_relaxed(&was_shutdown, 1);
|
|
}
|
|
+#endif /* CONFIG_LIBUV_CONTEXT */
|
|
\ No newline at end of file
|
|
diff --git a/src/uv-common.h b/src/uv-common.h
|
|
index 063588eac..9a436c0fd 100644
|
|
--- a/src/uv-common.h
|
|
+++ b/src/uv-common.h
|
|
@@ -1,3 +1,23 @@
|
|
+/****************************************************************************
|
|
+ * src/uv-common.h
|
|
+ *
|
|
+ * Licensed to the Apache Software Foundation (ASF) under one or more
|
|
+ * contributor license agreements. See the NOTICE file distributed with
|
|
+ * this work for additional information regarding copyright ownership. The
|
|
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
+ * "License"); you may not use this file except in compliance with the
|
|
+ * License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
+ * License for the specific language governing permissions and limitations
|
|
+ * under the License.
|
|
+ *
|
|
+ ****************************************************************************/
|
|
+
|
|
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
@@ -214,9 +234,20 @@ int uv__next_timeout(const uv_loop_t* loop);
|
|
void uv__run_timers(uv_loop_t* loop);
|
|
void uv__timer_close(uv_timer_t* handle);
|
|
|
|
+#ifdef CONFIG_LIBUV_CONTEXT
|
|
+void uv__process_title_setup(uv_context_t *ctx);
|
|
+void uv__signal_setup(uv_context_t *ctx);
|
|
+void uv__threadpool_setup(uv_context_t *ctx);
|
|
+
|
|
+void uv__process_title_cleanup(uv_context_t *ctx);
|
|
+void uv__signal_cleanup(uv_context_t *ctx);
|
|
+void uv__threadpool_cleanup(uv_context_t *ctx);
|
|
+
|
|
+#else
|
|
void uv__process_title_cleanup(void);
|
|
void uv__signal_cleanup(void);
|
|
void uv__threadpool_cleanup(void);
|
|
+#endif
|
|
|
|
#define uv__has_active_reqs(loop) \
|
|
((loop)->active_reqs.count > 0)
|
|
diff --git a/test/echo-server.c b/test/echo-server.c
|
|
index c65142ff9..ca7270cdb 100644
|
|
--- a/test/echo-server.c
|
|
+++ b/test/echo-server.c
|
|
@@ -34,10 +34,10 @@ static uv_loop_t* loop;
|
|
static int server_closed;
|
|
static stream_type serverType;
|
|
static uv_tcp_t tcpServer;
|
|
-static uv_udp_t udpServer;
|
|
-static uv_pipe_t pipeServer;
|
|
-static uv_handle_t* server;
|
|
-static uv_udp_send_t* send_freelist;
|
|
+// static uv_udp_t udpServer;
|
|
+// static uv_pipe_t pipeServer;
|
|
+static uv_handle_t* server_handle;
|
|
+// static uv_udp_send_t* send_freelist;
|
|
|
|
static void after_write(uv_write_t* req, int status);
|
|
static void after_read(uv_stream_t*, ssize_t nread, const uv_buf_t* buf);
|
|
@@ -61,6 +61,15 @@ static void after_write(uv_write_t* req, int status) {
|
|
"uv_write error: %s - %s\n",
|
|
uv_err_name(status),
|
|
uv_strerror(status));
|
|
+
|
|
+#ifdef __NUTTX__
|
|
+ /* FIXME server needs to stop properly on NuttX */
|
|
+ if (status == -ENOTCONN) {
|
|
+ _err("client disconnected, stop server\n");
|
|
+ uv_close(server_handle, on_server_close);
|
|
+ server_closed = 1;
|
|
+ }
|
|
+#endif
|
|
}
|
|
|
|
|
|
@@ -105,7 +114,7 @@ static void after_read(uv_stream_t* handle,
|
|
uv_close((uv_handle_t*)handle, on_close);
|
|
return;
|
|
} else {
|
|
- uv_close(server, on_server_close);
|
|
+ uv_close(server_handle, on_server_close);
|
|
server_closed = 1;
|
|
}
|
|
}
|
|
@@ -134,6 +143,7 @@ static void echo_alloc(uv_handle_t* handle,
|
|
buf->len = suggested_size;
|
|
}
|
|
|
|
+#if 0
|
|
static void slab_alloc(uv_handle_t* handle,
|
|
size_t suggested_size,
|
|
uv_buf_t* buf) {
|
|
@@ -142,6 +152,7 @@ static void slab_alloc(uv_handle_t* handle,
|
|
buf->base = slab;
|
|
buf->len = sizeof(slab);
|
|
}
|
|
+#endif
|
|
|
|
static void on_connection(uv_stream_t* server, int status) {
|
|
uv_stream_t* stream;
|
|
@@ -160,12 +171,14 @@ static void on_connection(uv_stream_t* server, int status) {
|
|
ASSERT(r == 0);
|
|
break;
|
|
|
|
+#if 0
|
|
case PIPE:
|
|
stream = malloc(sizeof(uv_pipe_t));
|
|
ASSERT(stream != NULL);
|
|
r = uv_pipe_init(loop, (uv_pipe_t*)stream, 0);
|
|
ASSERT(r == 0);
|
|
break;
|
|
+#endif
|
|
|
|
default:
|
|
ASSERT(0 && "Bad serverType");
|
|
@@ -184,9 +197,10 @@ static void on_connection(uv_stream_t* server, int status) {
|
|
|
|
|
|
static void on_server_close(uv_handle_t* handle) {
|
|
- ASSERT(handle == server);
|
|
+ ASSERT(handle == server_handle);
|
|
}
|
|
|
|
+#if 0
|
|
static uv_udp_send_t* send_alloc(void) {
|
|
uv_udp_send_t* req = send_freelist;
|
|
if (req != NULL)
|
|
@@ -223,6 +237,7 @@ static void on_recv(uv_udp_t* handle,
|
|
sndbuf = uv_buf_init(rcvbuf->base, nread);
|
|
ASSERT(0 <= uv_udp_send(req, handle, &sndbuf, 1, addr, on_send));
|
|
}
|
|
+#endif
|
|
|
|
static int tcp4_echo_start(int port) {
|
|
struct sockaddr_in addr;
|
|
@@ -230,7 +245,7 @@ static int tcp4_echo_start(int port) {
|
|
|
|
ASSERT(0 == uv_ip4_addr("0.0.0.0", port, &addr));
|
|
|
|
- server = (uv_handle_t*)&tcpServer;
|
|
+ server_handle = (uv_handle_t*)&tcpServer;
|
|
serverType = TCP;
|
|
|
|
r = uv_tcp_init(loop, &tcpServer);
|
|
@@ -257,14 +272,14 @@ static int tcp4_echo_start(int port) {
|
|
return 0;
|
|
}
|
|
|
|
-
|
|
+#if 0
|
|
static int tcp6_echo_start(int port) {
|
|
struct sockaddr_in6 addr6;
|
|
int r;
|
|
|
|
ASSERT(0 == uv_ip6_addr("::1", port, &addr6));
|
|
|
|
- server = (uv_handle_t*)&tcpServer;
|
|
+ server_handle = (uv_handle_t*)&tcpServer;
|
|
serverType = TCP;
|
|
|
|
r = uv_tcp_init(loop, &tcpServer);
|
|
@@ -298,7 +313,7 @@ static int udp4_echo_start(int port) {
|
|
int r;
|
|
|
|
ASSERT(0 == uv_ip4_addr("127.0.0.1", port, &addr));
|
|
- server = (uv_handle_t*)&udpServer;
|
|
+ server_handle = (uv_handle_t*)&udpServer;
|
|
serverType = UDP;
|
|
|
|
r = uv_udp_init(loop, &udpServer);
|
|
@@ -334,7 +349,7 @@ static int pipe_echo_start(char* pipeName) {
|
|
}
|
|
#endif
|
|
|
|
- server = (uv_handle_t*)&pipeServer;
|
|
+ server_handle = (uv_handle_t*)&pipeServer;
|
|
serverType = PIPE;
|
|
|
|
r = uv_pipe_init(loop, &pipeServer, 0);
|
|
@@ -357,20 +372,32 @@ static int pipe_echo_start(char* pipeName) {
|
|
|
|
return 0;
|
|
}
|
|
-
|
|
+#endif
|
|
|
|
HELPER_IMPL(tcp4_echo_server) {
|
|
- loop = uv_default_loop();
|
|
+ uv_context_t context;
|
|
+ uv_library_init(&context);
|
|
+ loop = uv_default_loop(&context);
|
|
|
|
- if (tcp4_echo_start(TEST_PORT))
|
|
- return 1;
|
|
+ int ret;
|
|
+
|
|
+ server_closed = 0;
|
|
+
|
|
+ if (tcp4_echo_start(TEST_PORT)) {
|
|
+ ret = 1;
|
|
+ goto exit;
|
|
+ }
|
|
|
|
notify_parent_process();
|
|
uv_run(loop, UV_RUN_DEFAULT);
|
|
- return 0;
|
|
-}
|
|
+ ret = 0;
|
|
|
|
+exit:
|
|
+ MAKE_VALGRIND_HAPPY(loop);
|
|
+ return ret;
|
|
+}
|
|
|
|
+#if 0
|
|
HELPER_IMPL(tcp6_echo_server) {
|
|
loop = uv_default_loop();
|
|
|
|
@@ -405,3 +432,4 @@ HELPER_IMPL(udp4_echo_server) {
|
|
uv_run(loop, UV_RUN_DEFAULT);
|
|
return 0;
|
|
}
|
|
+#endif
|
|
\ No newline at end of file
|
|
diff --git a/test/runner.c b/test/runner.c
|
|
index bb50b43b3..697dc729c 100644
|
|
--- a/test/runner.c
|
|
+++ b/test/runner.c
|
|
@@ -1,3 +1,23 @@
|
|
+/****************************************************************************
|
|
+ * test/runner.c
|
|
+ *
|
|
+ * Licensed to the Apache Software Foundation (ASF) under one or more
|
|
+ * contributor license agreements. See the NOTICE file distributed with
|
|
+ * this work for additional information regarding copyright ownership. The
|
|
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
+ * "License"); you may not use this file except in compliance with the
|
|
+ * License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
+ * License for the specific language governing permissions and limitations
|
|
+ * under the License.
|
|
+ *
|
|
+ ****************************************************************************/
|
|
+
|
|
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
@@ -27,7 +47,7 @@
|
|
#include "task.h"
|
|
#include "uv.h"
|
|
|
|
-char executable_path[sizeof(executable_path)];
|
|
+// char executable_path[sizeof(executable_path)];
|
|
|
|
|
|
static int compare_task(const void* va, const void* vb) {
|
|
@@ -123,7 +143,7 @@ int run_tests(int benchmark_output) {
|
|
return failed;
|
|
}
|
|
|
|
-
|
|
+#if 0
|
|
void log_tap_result(int test_count,
|
|
const char* test,
|
|
int status,
|
|
@@ -159,13 +179,18 @@ void log_tap_result(int test_count,
|
|
fprintf(stderr, "%s %d - %s%s%s\n", result, test_count, test, directive, reason);
|
|
fflush(stderr);
|
|
}
|
|
-
|
|
+#endif
|
|
|
|
int run_test(const char* test,
|
|
int benchmark_output,
|
|
int test_count) {
|
|
+#ifdef __NUTTX__
|
|
+ char errmsg[64] = "";
|
|
+ process_info_t processes[4];
|
|
+#else
|
|
char errmsg[1024] = "";
|
|
process_info_t processes[1024];
|
|
+#endif
|
|
process_info_t *main_proc;
|
|
task_entry_t* task;
|
|
int timeout_multiplier;
|
|
@@ -178,7 +203,7 @@ int run_test(const char* test,
|
|
main_proc = NULL;
|
|
process_count = 0;
|
|
|
|
-#ifndef _WIN32
|
|
+#if !defined(_WIN32) && !defined(__NUTTX__)
|
|
/* Clean up stale socket from previous run. */
|
|
remove(TEST_PIPENAME);
|
|
remove(TEST_PIPENAME_2);
|
|
@@ -203,8 +228,12 @@ int run_test(const char* test,
|
|
continue;
|
|
}
|
|
|
|
+#ifdef __NUTTX__
|
|
+ if (process_start(task,
|
|
+#else
|
|
if (process_start(task->task_name,
|
|
task->process_name,
|
|
+#endif
|
|
&processes[process_count],
|
|
1 /* is_helper */) == -1) {
|
|
snprintf(errmsg,
|
|
@@ -217,6 +246,13 @@ int run_test(const char* test,
|
|
process_count++;
|
|
}
|
|
|
|
+#ifdef __NUTTX__
|
|
+ if (process_count > 0) {
|
|
+ /* Give some time to helpers to start */
|
|
+ sleep(1);
|
|
+ }
|
|
+#endif
|
|
+
|
|
/* Now start the test itself. */
|
|
for (task = TASKS; task->main; task++) {
|
|
if (strcmp(test, task->task_name) != 0) {
|
|
@@ -227,8 +263,12 @@ int run_test(const char* test,
|
|
continue;
|
|
}
|
|
|
|
+#ifdef __NUTTX__
|
|
+ if (process_start(task,
|
|
+#else
|
|
if (process_start(task->task_name,
|
|
task->process_name,
|
|
+#endif
|
|
&processes[process_count],
|
|
0 /* !is_helper */) == -1) {
|
|
snprintf(errmsg,
|
|
@@ -252,7 +292,7 @@ int run_test(const char* test,
|
|
}
|
|
|
|
timeout_multiplier = 1;
|
|
-#ifndef _WIN32
|
|
+#if !defined(_WIN32) && !defined(__NUTTX__)
|
|
do {
|
|
const char* var;
|
|
|
|
@@ -266,6 +306,12 @@ int run_test(const char* test,
|
|
} while (0);
|
|
#endif
|
|
|
|
+#ifdef __NUTTX__
|
|
+ result = process_wait(processes, process_count, task->timeout * timeout_multiplier);
|
|
+ if (result) {
|
|
+ FATAL("process_wait failed");
|
|
+ }
|
|
+#else
|
|
result = process_wait(main_proc, 1, task->timeout * timeout_multiplier);
|
|
if (result == -1) {
|
|
FATAL("process_wait failed");
|
|
@@ -276,7 +322,9 @@ int run_test(const char* test,
|
|
"timeout");
|
|
goto out;
|
|
}
|
|
+#endif
|
|
|
|
+#if 0
|
|
status = process_reap(main_proc);
|
|
if (status != TEST_OK) {
|
|
snprintf(errmsg,
|
|
@@ -290,8 +338,10 @@ int run_test(const char* test,
|
|
/* Give the helpers time to clean up their act. */
|
|
uv_sleep(1000);
|
|
}
|
|
+#endif
|
|
|
|
out:
|
|
+#ifndef __NUTTX__
|
|
/* Reap running processes except the main process, it's already dead. */
|
|
for (i = 0; i < process_count - 1; i++) {
|
|
process_terminate(&processes[i]);
|
|
@@ -301,7 +351,9 @@ out:
|
|
process_wait(processes, process_count - 1, -1) < 0) {
|
|
FATAL("process_wait failed");
|
|
}
|
|
+#endif
|
|
|
|
+#if 0
|
|
log_tap_result(test_count, test, status, &processes[i]);
|
|
|
|
/* Show error and output from processes if the test failed. */
|
|
@@ -353,6 +405,7 @@ out:
|
|
break;
|
|
}
|
|
}
|
|
+#endif
|
|
|
|
/* Clean up all process handles. */
|
|
for (i = 0; i < process_count; i++) {
|
|
diff --git a/test/runner.h b/test/runner.h
|
|
index 6801564f9..15619088d 100644
|
|
--- a/test/runner.h
|
|
+++ b/test/runner.h
|
|
@@ -1,3 +1,23 @@
|
|
+/****************************************************************************
|
|
+ * test/runner.h
|
|
+ *
|
|
+ * Licensed to the Apache Software Foundation (ASF) under one or more
|
|
+ * contributor license agreements. See the NOTICE file distributed with
|
|
+ * this work for additional information regarding copyright ownership. The
|
|
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
+ * "License"); you may not use this file except in compliance with the
|
|
+ * License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
+ * License for the specific language governing permissions and limitations
|
|
+ * under the License.
|
|
+ *
|
|
+ ****************************************************************************/
|
|
+
|
|
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
@@ -36,7 +56,7 @@
|
|
/*
|
|
* Struct to store both tests and to define helper processes for tasks.
|
|
*/
|
|
-typedef struct {
|
|
+typedef struct task_entry_s {
|
|
char *task_name;
|
|
char *process_name;
|
|
int (*main)(void);
|
|
@@ -91,6 +111,8 @@ extern char executable_path[4096];
|
|
*/
|
|
#ifdef _WIN32
|
|
# include "runner-win.h"
|
|
+#elif defined(__NUTTX__)
|
|
+# include "runner-nuttx.h"
|
|
#else
|
|
# include "runner-unix.h"
|
|
#endif
|
|
@@ -136,7 +158,11 @@ void platform_init(int argc, char** argv);
|
|
|
|
/* Invoke "argv[0] test-name [test-part]". Store process info in *p. Make sure
|
|
* that all stdio output of the processes is buffered up. */
|
|
+#ifdef __NUTTX__
|
|
+int process_start(task_entry_t *task, process_info_t *p, int is_helper);
|
|
+#else
|
|
int process_start(char *name, char* part, process_info_t *p, int is_helper);
|
|
+#endif
|
|
|
|
/* Wait for all `n` processes in `vec` to terminate. Time out after `timeout`
|
|
* msec, or never if timeout == -1. Return 0 if all processes are terminated,
|
|
diff --git a/test/task.h b/test/task.h
|
|
index e95e3bde5..3b4556d86 100644
|
|
--- a/test/task.h
|
|
+++ b/test/task.h
|
|
@@ -1,3 +1,23 @@
|
|
+/****************************************************************************
|
|
+ * test/task.h
|
|
+ *
|
|
+ * Licensed to the Apache Software Foundation (ASF) under one or more
|
|
+ * contributor license agreements. See the NOTICE file distributed with
|
|
+ * this work for additional information regarding copyright ownership. The
|
|
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
+ * "License"); you may not use this file except in compliance with the
|
|
+ * License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
+ * License for the specific language governing permissions and limitations
|
|
+ * under the License.
|
|
+ *
|
|
+ ****************************************************************************/
|
|
+
|
|
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
@@ -84,6 +104,15 @@ typedef enum {
|
|
PIPE
|
|
} stream_type;
|
|
|
|
+#define ASSERT_WARN(msg) \
|
|
+ do { \
|
|
+ fprintf(stderr, \
|
|
+ "Warning in %s on line %d: %s\n", \
|
|
+ __FILE__, \
|
|
+ __LINE__, \
|
|
+ msg); \
|
|
+ } while (0)
|
|
+
|
|
/* Die with fatal error. */
|
|
#define FATAL(msg) \
|
|
do { \
|
|
@@ -99,6 +128,9 @@ typedef enum {
|
|
/* Have our own assert, so we are sure it does not get optimized away in
|
|
* a release build.
|
|
*/
|
|
+#ifdef ASSERT
|
|
+# undef ASSERT
|
|
+#endif
|
|
#define ASSERT(expr) \
|
|
do { \
|
|
if (!(expr)) { \
|
|
@@ -226,12 +258,25 @@ typedef enum {
|
|
/* This macro cleans up the main loop. This is used to avoid valgrind
|
|
* warnings about memory being "leaked" by the main event loop.
|
|
*/
|
|
-#define MAKE_VALGRIND_HAPPY() \
|
|
+#ifdef CONFIG_LIBUV_CONTEXT
|
|
+#define MAKE_VALGRIND_HAPPY(loop) \
|
|
do { \
|
|
- close_loop(uv_default_loop()); \
|
|
- ASSERT(0 == uv_loop_close(uv_default_loop())); \
|
|
+ if ((uv_loop_t*)(loop) != NULL) { \
|
|
+ uv_context_t *tmp_ctx = \
|
|
+ ((uv_loop_t*)(loop))->context; \
|
|
+ close_loop(loop); \
|
|
+ ASSERT(0 == uv_loop_close(loop)); \
|
|
+ uv_library_shutdown(tmp_ctx); \
|
|
+ } \
|
|
+ } while (0)
|
|
+#else
|
|
+#define MAKE_VALGRIND_HAPPY(loop) \
|
|
+ do { \
|
|
+ close_loop(loop); \
|
|
+ ASSERT(0 == uv_loop_close(loop)); \
|
|
uv_library_shutdown(); \
|
|
} while (0)
|
|
+#endif
|
|
|
|
/* Just sugar for wrapping the main() for a task or helper. */
|
|
#define TEST_IMPL(name) \
|
|
@@ -288,6 +333,9 @@ enum test_status {
|
|
extern int snprintf(char*, size_t, const char*, ...);
|
|
#endif
|
|
|
|
+#ifdef UNUSED
|
|
+# undef UNUSED
|
|
+#endif
|
|
#if defined(__clang__) || \
|
|
defined(__GNUC__) || \
|
|
defined(__INTEL_COMPILER)
|
|
@@ -296,7 +344,7 @@ extern int snprintf(char*, size_t, const char*, ...);
|
|
# define UNUSED
|
|
#endif
|
|
|
|
-#if defined(_WIN32)
|
|
+#if defined(_WIN32) || defined(__NUTTX__)
|
|
#define notify_parent_process() ((void) 0)
|
|
#else
|
|
extern void notify_parent_process(void);
|
|
@@ -313,6 +361,7 @@ UNUSED static void close_loop(uv_loop_t* loop) {
|
|
uv_run(loop, UV_RUN_DEFAULT);
|
|
}
|
|
|
|
+#if 0
|
|
UNUSED static int can_ipv6(void) {
|
|
uv_interface_address_t* addr;
|
|
int supported;
|
|
@@ -329,6 +378,7 @@ UNUSED static int can_ipv6(void) {
|
|
uv_free_interface_addresses(addr, count);
|
|
return supported;
|
|
}
|
|
+#endif
|
|
|
|
#if defined(__CYGWIN__) || defined(__MSYS__) || defined(__PASE__)
|
|
# define NO_FS_EVENTS "Filesystem watching not supported on this platform."
|
|
diff --git a/test/test-active.c b/test/test-active.c
|
|
index b17bd1760..8c5f00254 100644
|
|
--- a/test/test-active.c
|
|
+++ b/test/test-active.c
|
|
@@ -41,10 +41,16 @@ static void timer_cb(uv_timer_t* handle) {
|
|
|
|
|
|
TEST_IMPL(active) {
|
|
+ uv_context_t context;
|
|
+ uv_loop_t *loop;
|
|
+ uv_library_init(&context);
|
|
+ loop = uv_default_loop(&context);
|
|
int r;
|
|
uv_timer_t timer;
|
|
|
|
- r = uv_timer_init(uv_default_loop(), &timer);
|
|
+ close_cb_called = 0;
|
|
+
|
|
+ r = uv_timer_init(loop, &timer);
|
|
ASSERT(r == 0);
|
|
|
|
/* uv_is_active() and uv_is_closing() should always return either 0 or 1. */
|
|
@@ -74,11 +80,11 @@ TEST_IMPL(active) {
|
|
ASSERT(0 == uv_is_active((uv_handle_t*) &timer));
|
|
ASSERT(1 == uv_is_closing((uv_handle_t*) &timer));
|
|
|
|
- r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
|
+ r = uv_run(loop, UV_RUN_DEFAULT);
|
|
ASSERT(r == 0);
|
|
|
|
ASSERT(close_cb_called == 1);
|
|
|
|
- MAKE_VALGRIND_HAPPY();
|
|
+ MAKE_VALGRIND_HAPPY(loop);
|
|
return 0;
|
|
}
|
|
diff --git a/test/test-async.c b/test/test-async.c
|
|
index 6f5351bf1..fb29059e2 100644
|
|
--- a/test/test-async.c
|
|
+++ b/test/test-async.c
|
|
@@ -1,3 +1,23 @@
|
|
+/****************************************************************************
|
|
+ * test/test-async.c
|
|
+ *
|
|
+ * Licensed to the Apache Software Foundation (ASF) under one or more
|
|
+ * contributor license agreements. See the NOTICE file distributed with
|
|
+ * this work for additional information regarding copyright ownership. The
|
|
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
+ * "License"); you may not use this file except in compliance with the
|
|
+ * License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
+ * License for the specific language governing permissions and limitations
|
|
+ * under the License.
|
|
+ *
|
|
+ ****************************************************************************/
|
|
+
|
|
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
@@ -107,20 +127,28 @@ static void prepare_cb(uv_prepare_t* handle) {
|
|
|
|
TEST_IMPL(async) {
|
|
int r;
|
|
+ uv_context_t context;
|
|
+ uv_loop_t *loop;
|
|
+ uv_library_init(&context);
|
|
+ loop = uv_default_loop(&context);
|
|
+
|
|
+ async_cb_called = 0;
|
|
+ prepare_cb_called = 0;
|
|
+ close_cb_called = 0;
|
|
|
|
r = uv_mutex_init(&mutex);
|
|
ASSERT(r == 0);
|
|
uv_mutex_lock(&mutex);
|
|
|
|
- r = uv_prepare_init(uv_default_loop(), &prepare);
|
|
+ r = uv_prepare_init(loop, &prepare);
|
|
ASSERT(r == 0);
|
|
r = uv_prepare_start(&prepare, prepare_cb);
|
|
ASSERT(r == 0);
|
|
|
|
- r = uv_async_init(uv_default_loop(), &async, async_cb);
|
|
+ r = uv_async_init(loop, &async, async_cb);
|
|
ASSERT(r == 0);
|
|
|
|
- r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
|
+ r = uv_run(loop, UV_RUN_DEFAULT);
|
|
ASSERT(r == 0);
|
|
|
|
ASSERT(prepare_cb_called > 0);
|
|
@@ -129,6 +157,6 @@ TEST_IMPL(async) {
|
|
|
|
ASSERT(0 == uv_thread_join(&thread));
|
|
|
|
- MAKE_VALGRIND_HAPPY();
|
|
+ MAKE_VALGRIND_HAPPY(loop);
|
|
return 0;
|
|
}
|
|
diff --git a/test/test-fs-copyfile.c b/test/test-fs-copyfile.c
|
|
index 3335c8810..51d0b26b8 100644
|
|
--- a/test/test-fs-copyfile.c
|
|
+++ b/test/test-fs-copyfile.c
|
|
@@ -22,7 +22,8 @@
|
|
#include "uv.h"
|
|
#include "task.h"
|
|
|
|
-#if defined(__unix__) || defined(__POSIX__) || \
|
|
+#if defined(__NUTTX__) || \
|
|
+ defined(__unix__) || defined(__POSIX__) || \
|
|
defined(__APPLE__) || defined(__sun) || \
|
|
defined(_AIX) || defined(__MVS__) || \
|
|
defined(__HAIKU__)
|
|
@@ -33,8 +34,8 @@
|
|
# define unlink _unlink
|
|
#endif
|
|
|
|
-static const char fixture[] = "test/fixtures/load_error.node";
|
|
-static const char dst[] = "test_file_dst";
|
|
+static const char fixture[] = "/tmp/load_error.node";
|
|
+static const char dst[] = "/tmp/test_file_dst";
|
|
static int result_check_count;
|
|
|
|
|
|
@@ -96,12 +97,19 @@ static void touch_file(const char* name, unsigned int size) {
|
|
|
|
|
|
TEST_IMPL(fs_copyfile) {
|
|
- const char src[] = "test_file_src";
|
|
+ const char src[] = "/tmp/test_file_src";
|
|
uv_loop_t* loop;
|
|
uv_fs_t req;
|
|
int r;
|
|
|
|
- loop = uv_default_loop();
|
|
+ uv_context_t context;
|
|
+ uv_library_init(&context);
|
|
+ loop = uv_default_loop(&context);
|
|
+
|
|
+ result_check_count = 0;
|
|
+
|
|
+ /* FIXME prepare test files */
|
|
+ touch_file(fixture, 8);
|
|
|
|
/* Fails with EINVAL if bad flags are passed. */
|
|
r = uv_fs_copyfile(NULL, &req, src, dst, -1, NULL);
|
|
@@ -121,10 +129,14 @@ TEST_IMPL(fs_copyfile) {
|
|
uv_fs_req_cleanup(&req);
|
|
|
|
/* Succeeds if src and dst files are identical. */
|
|
+#ifdef __NUTTX__
|
|
+ ASSERT_WARN("FIXME copy same file not supported on NuttX");
|
|
+#else
|
|
touch_file(src, 12);
|
|
r = uv_fs_copyfile(NULL, &req, src, src, 0, NULL);
|
|
ASSERT(r == 0);
|
|
uv_fs_req_cleanup(&req);
|
|
+#endif
|
|
unlink(src);
|
|
|
|
/* Copies file synchronously. Creates new file. */
|
|
@@ -193,10 +205,9 @@ TEST_IMPL(fs_copyfile) {
|
|
if (r == 0)
|
|
handle_result(&req);
|
|
|
|
-#ifndef _WIN32
|
|
+#if !defined(__NUTTX__) && !defined(_WIN32)
|
|
/* Copying respects permissions/mode. */
|
|
unlink(dst);
|
|
- touch_file(dst, 0);
|
|
chmod(dst, S_IRUSR|S_IRGRP|S_IROTH); /* Sets file mode to 444 (read-only). */
|
|
r = uv_fs_copyfile(NULL, &req, fixture, dst, 0, NULL);
|
|
/* On IBMi PASE, qsecofr users can overwrite read-only files */
|
|
@@ -207,6 +218,9 @@ TEST_IMPL(fs_copyfile) {
|
|
uv_fs_req_cleanup(&req);
|
|
#endif
|
|
|
|
- unlink(dst); /* Cleanup */
|
|
+ /* Cleanup */
|
|
+ unlink(dst);
|
|
+ unlink(fixture);
|
|
+ MAKE_VALGRIND_HAPPY(loop);
|
|
return 0;
|
|
}
|
|
diff --git a/test/test-fs-poll.c b/test/test-fs-poll.c
|
|
index 9dfd5fdd6..35e32d42c 100644
|
|
--- a/test/test-fs-poll.c
|
|
+++ b/test/test-fs-poll.c
|
|
@@ -24,7 +24,7 @@
|
|
|
|
#include <string.h>
|
|
|
|
-#define FIXTURE "testfile"
|
|
+#define FIXTURE "/tmp/testfile"
|
|
|
|
static void timer_cb(uv_timer_t* handle);
|
|
static void close_cb(uv_handle_t* handle);
|
|
@@ -50,9 +50,9 @@ static int poll_cb_called;
|
|
static int timer_cb_called;
|
|
static int close_cb_called;
|
|
|
|
+static int touch_file_count;
|
|
|
|
static void touch_file(const char* path) {
|
|
- static int count;
|
|
FILE* fp;
|
|
int i;
|
|
|
|
@@ -61,7 +61,7 @@ static void touch_file(const char* path) {
|
|
/* Need to change the file size because the poller may not pick up
|
|
* sub-second mtime changes.
|
|
*/
|
|
- i = ++count;
|
|
+ i = ++touch_file_count;
|
|
|
|
while (i--)
|
|
fputc('*', fp);
|
|
@@ -151,7 +151,14 @@ static void poll_cb(uv_fs_poll_t* handle,
|
|
|
|
|
|
TEST_IMPL(fs_poll) {
|
|
- loop = uv_default_loop();
|
|
+ uv_context_t context;
|
|
+ uv_library_init(&context);
|
|
+ loop = uv_default_loop(&context);
|
|
+
|
|
+ poll_cb_called = 0;
|
|
+ timer_cb_called = 0;
|
|
+ close_cb_called = 0;
|
|
+ touch_file_count = 0;
|
|
|
|
remove(FIXTURE);
|
|
|
|
@@ -164,15 +171,26 @@ TEST_IMPL(fs_poll) {
|
|
ASSERT(timer_cb_called == 2);
|
|
ASSERT(close_cb_called == 1);
|
|
|
|
- MAKE_VALGRIND_HAPPY();
|
|
+ MAKE_VALGRIND_HAPPY(loop);
|
|
return 0;
|
|
}
|
|
|
|
|
|
TEST_IMPL(fs_poll_getpath) {
|
|
+#ifdef __NUTTX__
|
|
+ char buf[64];
|
|
+#else
|
|
char buf[1024];
|
|
+#endif
|
|
size_t len;
|
|
- loop = uv_default_loop();
|
|
+ uv_context_t context;
|
|
+ uv_library_init(&context);
|
|
+ loop = uv_default_loop(&context);
|
|
+
|
|
+ poll_cb_called = 0;
|
|
+ timer_cb_called = 0;
|
|
+ close_cb_called = 0;
|
|
+ touch_file_count = 0;
|
|
|
|
remove(FIXTURE);
|
|
|
|
@@ -192,109 +210,149 @@ TEST_IMPL(fs_poll_getpath) {
|
|
|
|
ASSERT(close_cb_called == 1);
|
|
|
|
- MAKE_VALGRIND_HAPPY();
|
|
+ MAKE_VALGRIND_HAPPY(loop);
|
|
return 0;
|
|
}
|
|
|
|
|
|
TEST_IMPL(fs_poll_close_request) {
|
|
- uv_loop_t loop;
|
|
- uv_fs_poll_t poll_handle;
|
|
+ uv_loop_t sloop;
|
|
+ uv_fs_poll_t spoll_handle;
|
|
+
|
|
+ uv_context_t context;
|
|
+ uv_library_init(&context);
|
|
+
|
|
+ poll_cb_called = 0;
|
|
+ timer_cb_called = 0;
|
|
+ close_cb_called = 0;
|
|
+ touch_file_count = 0;
|
|
|
|
remove(FIXTURE);
|
|
|
|
- ASSERT(0 == uv_loop_init(&loop));
|
|
+ ASSERT(0 == uv_loop_init(&sloop, &context));
|
|
|
|
- ASSERT(0 == uv_fs_poll_init(&loop, &poll_handle));
|
|
- ASSERT(0 == uv_fs_poll_start(&poll_handle, poll_cb_fail, FIXTURE, 100));
|
|
- uv_close((uv_handle_t*) &poll_handle, close_cb);
|
|
+ ASSERT(0 == uv_fs_poll_init(&sloop, &spoll_handle));
|
|
+ ASSERT(0 == uv_fs_poll_start(&spoll_handle, poll_cb_fail, FIXTURE, 100));
|
|
+ uv_close((uv_handle_t*) &spoll_handle, close_cb);
|
|
while (close_cb_called == 0)
|
|
- uv_run(&loop, UV_RUN_ONCE);
|
|
+ uv_run(&sloop, UV_RUN_ONCE);
|
|
ASSERT(close_cb_called == 1);
|
|
|
|
- ASSERT(0 == uv_loop_close(&loop));
|
|
-
|
|
- MAKE_VALGRIND_HAPPY();
|
|
+#ifndef __NUTTX__
|
|
+ ASSERT(0 == uv_loop_close(&sloop));
|
|
+#else
|
|
+ MAKE_VALGRIND_HAPPY(&sloop);
|
|
+#endif
|
|
return 0;
|
|
}
|
|
|
|
TEST_IMPL(fs_poll_close_request_multi_start_stop) {
|
|
- uv_loop_t loop;
|
|
- uv_fs_poll_t poll_handle;
|
|
+ uv_loop_t sloop;
|
|
+ uv_fs_poll_t spoll_handle;
|
|
int i;
|
|
|
|
+ uv_context_t context;
|
|
+ uv_library_init(&context);
|
|
+
|
|
+ poll_cb_called = 0;
|
|
+ timer_cb_called = 0;
|
|
+ close_cb_called = 0;
|
|
+ touch_file_count = 0;
|
|
+
|
|
remove(FIXTURE);
|
|
|
|
- ASSERT(0 == uv_loop_init(&loop));
|
|
+ ASSERT(0 == uv_loop_init(&sloop, &context));
|
|
|
|
- ASSERT(0 == uv_fs_poll_init(&loop, &poll_handle));
|
|
+ ASSERT(0 == uv_fs_poll_init(&sloop, &spoll_handle));
|
|
|
|
for (i = 0; i < 10; ++i) {
|
|
- ASSERT(0 == uv_fs_poll_start(&poll_handle, poll_cb_fail, FIXTURE, 100));
|
|
- ASSERT(0 == uv_fs_poll_stop(&poll_handle));
|
|
+ ASSERT(0 == uv_fs_poll_start(&spoll_handle, poll_cb_fail, FIXTURE, 100));
|
|
+ ASSERT(0 == uv_fs_poll_stop(&spoll_handle));
|
|
}
|
|
- uv_close((uv_handle_t*) &poll_handle, close_cb);
|
|
+ uv_close((uv_handle_t*) &spoll_handle, close_cb);
|
|
while (close_cb_called == 0)
|
|
- uv_run(&loop, UV_RUN_ONCE);
|
|
+ uv_run(&sloop, UV_RUN_ONCE);
|
|
ASSERT(close_cb_called == 1);
|
|
|
|
- ASSERT(0 == uv_loop_close(&loop));
|
|
-
|
|
- MAKE_VALGRIND_HAPPY();
|
|
+#ifndef __NUTTX__
|
|
+ ASSERT(0 == uv_loop_close(&sloop));
|
|
+#else
|
|
+ MAKE_VALGRIND_HAPPY(&sloop);
|
|
+#endif
|
|
return 0;
|
|
}
|
|
|
|
TEST_IMPL(fs_poll_close_request_multi_stop_start) {
|
|
- uv_loop_t loop;
|
|
- uv_fs_poll_t poll_handle;
|
|
+ uv_loop_t sloop;
|
|
+ uv_fs_poll_t spoll_handle;
|
|
int i;
|
|
|
|
+ uv_context_t context;
|
|
+ uv_library_init(&context);
|
|
+
|
|
+ poll_cb_called = 0;
|
|
+ timer_cb_called = 0;
|
|
+ close_cb_called = 0;
|
|
+ touch_file_count = 0;
|
|
+
|
|
remove(FIXTURE);
|
|
|
|
- ASSERT(0 == uv_loop_init(&loop));
|
|
+ ASSERT(0 == uv_loop_init(&sloop, &context));
|
|
|
|
- ASSERT(0 == uv_fs_poll_init(&loop, &poll_handle));
|
|
+ ASSERT(0 == uv_fs_poll_init(&sloop, &spoll_handle));
|
|
|
|
for (i = 0; i < 10; ++i) {
|
|
- ASSERT(0 == uv_fs_poll_stop(&poll_handle));
|
|
- ASSERT(0 == uv_fs_poll_start(&poll_handle, poll_cb_fail, FIXTURE, 100));
|
|
+ ASSERT(0 == uv_fs_poll_stop(&spoll_handle));
|
|
+ ASSERT(0 == uv_fs_poll_start(&spoll_handle, poll_cb_fail, FIXTURE, 100));
|
|
}
|
|
- uv_close((uv_handle_t*) &poll_handle, close_cb);
|
|
+ uv_close((uv_handle_t*) &spoll_handle, close_cb);
|
|
while (close_cb_called == 0)
|
|
- uv_run(&loop, UV_RUN_ONCE);
|
|
+ uv_run(&sloop, UV_RUN_ONCE);
|
|
ASSERT(close_cb_called == 1);
|
|
|
|
- ASSERT(0 == uv_loop_close(&loop));
|
|
-
|
|
- MAKE_VALGRIND_HAPPY();
|
|
+#ifndef __NUTTX__
|
|
+ ASSERT(0 == uv_loop_close(&sloop));
|
|
+#else
|
|
+ MAKE_VALGRIND_HAPPY(&sloop);
|
|
+#endif
|
|
return 0;
|
|
}
|
|
|
|
TEST_IMPL(fs_poll_close_request_stop_when_active) {
|
|
/* Regression test for https://github.com/libuv/libuv/issues/2287. */
|
|
- uv_loop_t loop;
|
|
- uv_fs_poll_t poll_handle;
|
|
+ uv_loop_t sloop;
|
|
+ uv_fs_poll_t spoll_handle;
|
|
+
|
|
+ uv_context_t context;
|
|
+ uv_library_init(&context);
|
|
+
|
|
+ poll_cb_called = 0;
|
|
+ timer_cb_called = 0;
|
|
+ close_cb_called = 0;
|
|
+ touch_file_count = 0;
|
|
|
|
remove(FIXTURE);
|
|
|
|
- ASSERT(0 == uv_loop_init(&loop));
|
|
+ ASSERT(0 == uv_loop_init(&sloop, &context));
|
|
|
|
/* Set up all handles. */
|
|
- ASSERT(0 == uv_fs_poll_init(&loop, &poll_handle));
|
|
- ASSERT(0 == uv_fs_poll_start(&poll_handle, poll_cb_noop, FIXTURE, 100));
|
|
- uv_run(&loop, UV_RUN_ONCE);
|
|
+ ASSERT(0 == uv_fs_poll_init(&sloop, &spoll_handle));
|
|
+ ASSERT(0 == uv_fs_poll_start(&spoll_handle, poll_cb_noop, FIXTURE, 100));
|
|
+ uv_run(&sloop, UV_RUN_ONCE);
|
|
|
|
/* Close the timer handle, and do not crash. */
|
|
- ASSERT(0 == uv_fs_poll_stop(&poll_handle));
|
|
- uv_run(&loop, UV_RUN_ONCE);
|
|
+ ASSERT(0 == uv_fs_poll_stop(&spoll_handle));
|
|
+ uv_run(&sloop, UV_RUN_ONCE);
|
|
|
|
/* Clean up after the test. */
|
|
- uv_close((uv_handle_t*) &poll_handle, close_cb);
|
|
- uv_run(&loop, UV_RUN_ONCE);
|
|
+ uv_close((uv_handle_t*) &spoll_handle, close_cb);
|
|
+ uv_run(&sloop, UV_RUN_ONCE);
|
|
ASSERT(close_cb_called == 1);
|
|
|
|
- ASSERT(0 == uv_loop_close(&loop));
|
|
-
|
|
- MAKE_VALGRIND_HAPPY();
|
|
+#ifndef __NUTTX__
|
|
+ ASSERT(0 == uv_loop_close(&sloop));
|
|
+#else
|
|
+ MAKE_VALGRIND_HAPPY(&sloop);
|
|
+#endif
|
|
return 0;
|
|
}
|
|
diff --git a/test/test-idle.c b/test/test-idle.c
|
|
index f49d19648..51bd1747a 100644
|
|
--- a/test/test-idle.c
|
|
+++ b/test/test-idle.c
|
|
@@ -57,6 +57,7 @@ static void idle_cb(uv_idle_t* handle) {
|
|
idle_cb_called++;
|
|
fprintf(stderr, "idle_cb %d\n", idle_cb_called);
|
|
fflush(stderr);
|
|
+ usleep(50*1000);
|
|
}
|
|
|
|
|
|
@@ -70,30 +71,39 @@ static void check_cb(uv_check_t* handle) {
|
|
|
|
|
|
TEST_IMPL(idle_starvation) {
|
|
+ uv_context_t context;
|
|
+ uv_loop_t *loop;
|
|
+ uv_library_init(&context);
|
|
+ loop = uv_default_loop(&context);
|
|
int r;
|
|
|
|
- r = uv_idle_init(uv_default_loop(), &idle_handle);
|
|
+ idle_cb_called = 0;
|
|
+ check_cb_called = 0;
|
|
+ timer_cb_called = 0;
|
|
+ close_cb_called = 0;
|
|
+
|
|
+ r = uv_idle_init(loop, &idle_handle);
|
|
ASSERT(r == 0);
|
|
r = uv_idle_start(&idle_handle, idle_cb);
|
|
ASSERT(r == 0);
|
|
|
|
- r = uv_check_init(uv_default_loop(), &check_handle);
|
|
+ r = uv_check_init(loop, &check_handle);
|
|
ASSERT(r == 0);
|
|
r = uv_check_start(&check_handle, check_cb);
|
|
ASSERT(r == 0);
|
|
|
|
- r = uv_timer_init(uv_default_loop(), &timer_handle);
|
|
+ r = uv_timer_init(loop, &timer_handle);
|
|
ASSERT(r == 0);
|
|
r = uv_timer_start(&timer_handle, timer_cb, 50, 0);
|
|
ASSERT(r == 0);
|
|
|
|
- r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
|
+ r = uv_run(loop, UV_RUN_DEFAULT);
|
|
ASSERT(r == 0);
|
|
|
|
ASSERT(idle_cb_called > 0);
|
|
ASSERT(timer_cb_called == 1);
|
|
ASSERT(close_cb_called == 3);
|
|
|
|
- MAKE_VALGRIND_HAPPY();
|
|
+ MAKE_VALGRIND_HAPPY(loop);
|
|
return 0;
|
|
}
|
|
diff --git a/test/test-ip4-addr.c b/test/test-ip4-addr.c
|
|
index dfefb0f91..1cd9cd33f 100644
|
|
--- a/test/test-ip4-addr.c
|
|
+++ b/test/test-ip4-addr.c
|
|
@@ -50,6 +50,6 @@ TEST_IMPL(ip4_addr) {
|
|
ASSERT(UV_EAFNOSUPPORT == uv_inet_pton(42, "127.0.0.1",
|
|
&addr.sin_addr.s_addr));
|
|
|
|
- MAKE_VALGRIND_HAPPY();
|
|
+ MAKE_VALGRIND_HAPPY(NULL);
|
|
return 0;
|
|
}
|
|
diff --git a/test/test-list.h b/test/test-list.h
|
|
index 58e174d1d..edf5077cd 100644
|
|
--- a/test/test-list.h
|
|
+++ b/test/test-list.h
|
|
@@ -21,17 +21,20 @@
|
|
|
|
#include "uv.h"
|
|
|
|
+#if 0
|
|
TEST_DECLARE (platform_output)
|
|
TEST_DECLARE (callback_order)
|
|
TEST_DECLARE (close_order)
|
|
TEST_DECLARE (run_once)
|
|
TEST_DECLARE (run_nowait)
|
|
TEST_DECLARE (loop_alive)
|
|
+#endif
|
|
TEST_DECLARE (loop_close)
|
|
TEST_DECLARE (loop_instant_close)
|
|
TEST_DECLARE (loop_stop)
|
|
TEST_DECLARE (loop_update_time)
|
|
TEST_DECLARE (loop_backend_timeout)
|
|
+#if 0
|
|
TEST_DECLARE (loop_configure)
|
|
TEST_DECLARE (default_loop_close)
|
|
TEST_DECLARE (barrier_1)
|
|
@@ -94,17 +97,21 @@ TEST_DECLARE (ipc_send_zero)
|
|
TEST_DECLARE (ipc_closed_handle)
|
|
#endif
|
|
TEST_DECLARE (tcp_alloc_cb_fail)
|
|
+#endif
|
|
TEST_DECLARE (tcp_ping_pong)
|
|
TEST_DECLARE (tcp_ping_pong_vec)
|
|
+#if 0
|
|
TEST_DECLARE (tcp6_ping_pong)
|
|
TEST_DECLARE (tcp6_ping_pong_vec)
|
|
TEST_DECLARE (pipe_ping_pong)
|
|
TEST_DECLARE (pipe_ping_pong_vec)
|
|
TEST_DECLARE (delayed_accept)
|
|
TEST_DECLARE (multiple_listen)
|
|
+#endif
|
|
#ifndef _WIN32
|
|
TEST_DECLARE (tcp_write_after_connect)
|
|
#endif
|
|
+#if 0
|
|
TEST_DECLARE (tcp_writealot)
|
|
TEST_DECLARE (tcp_write_fail)
|
|
TEST_DECLARE (tcp_try_write)
|
|
@@ -144,7 +151,9 @@ TEST_DECLARE (tcp_oob)
|
|
TEST_DECLARE (tcp_flags)
|
|
TEST_DECLARE (tcp_write_to_half_open_connection)
|
|
TEST_DECLARE (tcp_unexpected_read)
|
|
+#endif
|
|
TEST_DECLARE (tcp_read_stop)
|
|
+#if 0
|
|
TEST_DECLARE (tcp_bind6_error_addrinuse)
|
|
TEST_DECLARE (tcp_bind6_error_addrnotavail)
|
|
TEST_DECLARE (tcp_bind6_error_fault)
|
|
@@ -206,6 +215,7 @@ TEST_DECLARE (callback_stack)
|
|
TEST_DECLARE (env_vars)
|
|
TEST_DECLARE (error_message)
|
|
TEST_DECLARE (sys_error)
|
|
+#endif
|
|
TEST_DECLARE (timer)
|
|
TEST_DECLARE (timer_init)
|
|
TEST_DECLARE (timer_again)
|
|
@@ -218,10 +228,14 @@ TEST_DECLARE (timer_from_check)
|
|
TEST_DECLARE (timer_is_closing)
|
|
TEST_DECLARE (timer_null_callback)
|
|
TEST_DECLARE (timer_early_check)
|
|
+
|
|
TEST_DECLARE (idle_starvation)
|
|
+#if 0
|
|
TEST_DECLARE (loop_handles)
|
|
TEST_DECLARE (get_loadavg)
|
|
+#endif
|
|
TEST_DECLARE (walk_handles)
|
|
+#if 0
|
|
TEST_DECLARE (watcher_cross_stop)
|
|
TEST_DECLARE (ref)
|
|
TEST_DECLARE (idle_ref)
|
|
@@ -253,9 +267,13 @@ TEST_DECLARE (pipe_set_chmod)
|
|
TEST_DECLARE (process_ref)
|
|
TEST_DECLARE (process_priority)
|
|
TEST_DECLARE (has_ref)
|
|
+#endif
|
|
TEST_DECLARE (active)
|
|
+#if 0
|
|
TEST_DECLARE (embed)
|
|
+#endif
|
|
TEST_DECLARE (async)
|
|
+#if 0
|
|
TEST_DECLARE (async_null_cb)
|
|
TEST_DECLARE (eintr_handling)
|
|
TEST_DECLARE (get_currentexe)
|
|
@@ -311,12 +329,14 @@ TEST_DECLARE (spawn_reads_child_path)
|
|
TEST_DECLARE (spawn_inherit_streams)
|
|
TEST_DECLARE (spawn_quoted_path)
|
|
TEST_DECLARE (spawn_tcp_server)
|
|
+#endif
|
|
TEST_DECLARE (fs_poll)
|
|
TEST_DECLARE (fs_poll_getpath)
|
|
TEST_DECLARE (fs_poll_close_request)
|
|
TEST_DECLARE (fs_poll_close_request_multi_start_stop)
|
|
TEST_DECLARE (fs_poll_close_request_multi_stop_start)
|
|
TEST_DECLARE (fs_poll_close_request_stop_when_active)
|
|
+#if 0
|
|
TEST_DECLARE (kill)
|
|
TEST_DECLARE (kill_invalid_signum)
|
|
TEST_DECLARE (fs_file_noent)
|
|
@@ -333,7 +353,9 @@ TEST_DECLARE (fs_mkstemp)
|
|
TEST_DECLARE (fs_fstat)
|
|
TEST_DECLARE (fs_access)
|
|
TEST_DECLARE (fs_chmod)
|
|
+#endif
|
|
TEST_DECLARE (fs_copyfile)
|
|
+#if 0
|
|
TEST_DECLARE (fs_unlink_readonly)
|
|
#ifdef _WIN32
|
|
TEST_DECLARE (fs_unlink_archive_readonly)
|
|
@@ -413,8 +435,10 @@ TEST_DECLARE (fs_invalid_mkdir_name)
|
|
#endif
|
|
TEST_DECLARE (fs_get_system_error)
|
|
TEST_DECLARE (strscpy)
|
|
+#endif
|
|
TEST_DECLARE (threadpool_queue_work_simple)
|
|
TEST_DECLARE (threadpool_queue_work_einval)
|
|
+#if 0
|
|
TEST_DECLARE (threadpool_multiple_event_loops)
|
|
TEST_DECLARE (threadpool_cancel_getaddrinfo)
|
|
TEST_DECLARE (threadpool_cancel_getnameinfo)
|
|
@@ -438,7 +462,9 @@ TEST_DECLARE (poll_oob)
|
|
#endif
|
|
TEST_DECLARE (poll_duplex)
|
|
TEST_DECLARE (poll_unidirectional)
|
|
+#endif
|
|
TEST_DECLARE (poll_close)
|
|
+#if 0
|
|
TEST_DECLARE (poll_bad_fdtype)
|
|
#ifdef __linux__
|
|
TEST_DECLARE (poll_nested_epoll)
|
|
@@ -447,7 +473,9 @@ TEST_DECLARE (poll_nested_epoll)
|
|
TEST_DECLARE (poll_nested_kqueue)
|
|
#endif
|
|
|
|
+#endif
|
|
TEST_DECLARE (ip4_addr)
|
|
+#if 0
|
|
TEST_DECLARE (ip6_addr_link_local)
|
|
|
|
TEST_DECLARE (poll_close_doesnt_corrupt_stack)
|
|
@@ -482,16 +510,20 @@ TEST_DECLARE (closed_fd_events)
|
|
TEST_DECLARE (osx_select)
|
|
TEST_DECLARE (osx_select_many_fds)
|
|
#endif
|
|
+#endif
|
|
HELPER_DECLARE (tcp4_echo_server)
|
|
+#if 0
|
|
HELPER_DECLARE (tcp6_echo_server)
|
|
HELPER_DECLARE (udp4_echo_server)
|
|
HELPER_DECLARE (pipe_echo_server)
|
|
|
|
TEST_DECLARE (queue_foreach_delete)
|
|
-
|
|
+#endif
|
|
+#ifdef CONFIG_DEV_URANDOM
|
|
TEST_DECLARE (random_async)
|
|
TEST_DECLARE (random_sync)
|
|
-
|
|
+#endif
|
|
+#if 0
|
|
TEST_DECLARE (handle_type_name)
|
|
TEST_DECLARE (req_type_name)
|
|
TEST_DECLARE (getters_setters)
|
|
@@ -517,22 +549,27 @@ TEST_DECLARE (fork_threadpool_queue_work_simple)
|
|
TEST_DECLARE (idna_toascii)
|
|
TEST_DECLARE (utf8_decode1)
|
|
TEST_DECLARE (uname)
|
|
+#endif
|
|
|
|
TASK_LIST_START
|
|
+#if 0
|
|
TEST_ENTRY_CUSTOM (platform_output, 0, 1, 5000)
|
|
-
|
|
+#endif
|
|
#if 0
|
|
TEST_ENTRY (callback_order)
|
|
#endif
|
|
+#if 0
|
|
TEST_ENTRY (close_order)
|
|
TEST_ENTRY (run_once)
|
|
TEST_ENTRY (run_nowait)
|
|
TEST_ENTRY (loop_alive)
|
|
+#endif
|
|
TEST_ENTRY (loop_close)
|
|
TEST_ENTRY (loop_instant_close)
|
|
TEST_ENTRY (loop_stop)
|
|
TEST_ENTRY (loop_update_time)
|
|
TEST_ENTRY (loop_backend_timeout)
|
|
+#if 0
|
|
TEST_ENTRY (loop_configure)
|
|
TEST_ENTRY (default_loop_close)
|
|
TEST_ENTRY (barrier_1)
|
|
@@ -607,13 +644,13 @@ TASK_LIST_START
|
|
#endif
|
|
|
|
TEST_ENTRY (tcp_alloc_cb_fail)
|
|
-
|
|
+#endif
|
|
TEST_ENTRY (tcp_ping_pong)
|
|
TEST_HELPER (tcp_ping_pong, tcp4_echo_server)
|
|
|
|
TEST_ENTRY (tcp_ping_pong_vec)
|
|
TEST_HELPER (tcp_ping_pong_vec, tcp4_echo_server)
|
|
-
|
|
+#if 0
|
|
TEST_ENTRY (tcp6_ping_pong)
|
|
TEST_HELPER (tcp6_ping_pong, tcp6_echo_server)
|
|
|
|
@@ -628,11 +665,11 @@ TASK_LIST_START
|
|
|
|
TEST_ENTRY (delayed_accept)
|
|
TEST_ENTRY (multiple_listen)
|
|
-
|
|
+#endif
|
|
#ifndef _WIN32
|
|
TEST_ENTRY (tcp_write_after_connect)
|
|
#endif
|
|
-
|
|
+#if 0
|
|
#ifdef __MVS__
|
|
TEST_ENTRY_CUSTOM (tcp_writealot, 0, 0, 20000)
|
|
#else
|
|
@@ -689,10 +726,10 @@ TASK_LIST_START
|
|
TEST_ENTRY (tcp_flags)
|
|
TEST_ENTRY (tcp_write_to_half_open_connection)
|
|
TEST_ENTRY (tcp_unexpected_read)
|
|
-
|
|
+#endif
|
|
TEST_ENTRY (tcp_read_stop)
|
|
TEST_HELPER (tcp_read_stop, tcp4_echo_server)
|
|
-
|
|
+#if 0
|
|
TEST_ENTRY (tcp_bind6_error_addrinuse)
|
|
TEST_ENTRY (tcp_bind6_error_addrnotavail)
|
|
TEST_ENTRY (tcp_bind6_error_fault)
|
|
@@ -764,7 +801,7 @@ TASK_LIST_START
|
|
|
|
TEST_ENTRY (error_message)
|
|
TEST_ENTRY (sys_error)
|
|
-
|
|
+#endif
|
|
TEST_ENTRY (timer)
|
|
TEST_ENTRY (timer_init)
|
|
TEST_ENTRY (timer_again)
|
|
@@ -779,7 +816,7 @@ TASK_LIST_START
|
|
TEST_ENTRY (timer_early_check)
|
|
|
|
TEST_ENTRY (idle_starvation)
|
|
-
|
|
+#if 0
|
|
TEST_ENTRY (ref)
|
|
TEST_ENTRY (idle_ref)
|
|
TEST_ENTRY (fs_poll_ref)
|
|
@@ -812,15 +849,18 @@ TASK_LIST_START
|
|
TEST_ENTRY (has_ref)
|
|
|
|
TEST_ENTRY (loop_handles)
|
|
+#endif
|
|
TEST_ENTRY (walk_handles)
|
|
-
|
|
+#if 0
|
|
TEST_ENTRY (watcher_cross_stop)
|
|
-
|
|
+#endif
|
|
TEST_ENTRY (active)
|
|
+#if 0
|
|
|
|
TEST_ENTRY (embed)
|
|
-
|
|
+#endif
|
|
TEST_ENTRY (async)
|
|
+#if 0
|
|
TEST_ENTRY (async_null_cb)
|
|
TEST_ENTRY (eintr_handling)
|
|
|
|
@@ -866,7 +906,9 @@ TASK_LIST_START
|
|
|
|
TEST_ENTRY (poll_duplex)
|
|
TEST_ENTRY (poll_unidirectional)
|
|
+#endif
|
|
TEST_ENTRY (poll_close)
|
|
+#if 0
|
|
TEST_ENTRY (poll_bad_fdtype)
|
|
#if (defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))) && \
|
|
!defined(__sun)
|
|
@@ -909,12 +951,14 @@ TASK_LIST_START
|
|
TEST_ENTRY (spawn_inherit_streams)
|
|
TEST_ENTRY (spawn_quoted_path)
|
|
TEST_ENTRY (spawn_tcp_server)
|
|
+#endif
|
|
TEST_ENTRY (fs_poll)
|
|
TEST_ENTRY (fs_poll_getpath)
|
|
TEST_ENTRY (fs_poll_close_request)
|
|
TEST_ENTRY (fs_poll_close_request_multi_start_stop)
|
|
TEST_ENTRY (fs_poll_close_request_multi_stop_start)
|
|
TEST_ENTRY (fs_poll_close_request_stop_when_active)
|
|
+#if 0
|
|
TEST_ENTRY (kill)
|
|
TEST_ENTRY (kill_invalid_signum)
|
|
|
|
@@ -966,7 +1010,9 @@ TASK_LIST_START
|
|
TEST_ENTRY (fs_fstat)
|
|
TEST_ENTRY (fs_access)
|
|
TEST_ENTRY (fs_chmod)
|
|
+#endif
|
|
TEST_ENTRY (fs_copyfile)
|
|
+#if 0
|
|
TEST_ENTRY (fs_unlink_readonly)
|
|
#ifdef _WIN32
|
|
TEST_ENTRY (fs_unlink_archive_readonly)
|
|
@@ -1045,8 +1091,10 @@ TASK_LIST_START
|
|
TEST_ENTRY (get_osfhandle_valid_handle)
|
|
TEST_ENTRY (open_osfhandle_valid_handle)
|
|
TEST_ENTRY (strscpy)
|
|
+#endif
|
|
TEST_ENTRY (threadpool_queue_work_simple)
|
|
TEST_ENTRY (threadpool_queue_work_einval)
|
|
+#if 0
|
|
TEST_ENTRY_CUSTOM (threadpool_multiple_event_loops, 0, 0, 60000)
|
|
TEST_ENTRY (threadpool_cancel_getaddrinfo)
|
|
TEST_ENTRY (threadpool_cancel_getnameinfo)
|
|
@@ -1064,14 +1112,18 @@ TASK_LIST_START
|
|
TEST_ENTRY (thread_create)
|
|
TEST_ENTRY (thread_equal)
|
|
TEST_ENTRY (dlerror)
|
|
+#endif
|
|
TEST_ENTRY (ip4_addr)
|
|
+#if 0
|
|
TEST_ENTRY (ip6_addr_link_local)
|
|
|
|
TEST_ENTRY (queue_foreach_delete)
|
|
-
|
|
+#endif
|
|
+#ifdef CONFIG_DEV_URANDOM
|
|
TEST_ENTRY (random_async)
|
|
TEST_ENTRY (random_sync)
|
|
-
|
|
+#endif
|
|
+#if 0
|
|
TEST_ENTRY (handle_type_name)
|
|
TEST_ENTRY (req_type_name)
|
|
TEST_ENTRY (getters_setters)
|
|
@@ -1105,4 +1157,5 @@ TASK_LIST_START
|
|
TEST_ENTRY (fail_always)
|
|
TEST_ENTRY (pass_always)
|
|
#endif
|
|
+#endif
|
|
TASK_LIST_END
|
|
diff --git a/test/test-loop-close.c b/test/test-loop-close.c
|
|
index f0f3e627f..9e10c2b22 100644
|
|
--- a/test/test-loop-close.c
|
|
+++ b/test/test-loop-close.c
|
|
@@ -33,9 +33,11 @@ static void timer_cb(uv_timer_t* handle) {
|
|
TEST_IMPL(loop_close) {
|
|
int r;
|
|
uv_loop_t loop;
|
|
+ uv_context_t context;
|
|
+ uv_library_init(&context);
|
|
|
|
loop.data = &loop;
|
|
- ASSERT(0 == uv_loop_init(&loop));
|
|
+ ASSERT(0 == uv_loop_init(&loop, &context));
|
|
ASSERT(loop.data == (void*) &loop);
|
|
|
|
uv_timer_init(&loop, &timer_handle);
|
|
@@ -53,6 +55,7 @@ TEST_IMPL(loop_close) {
|
|
ASSERT(0 == uv_loop_close(&loop));
|
|
ASSERT(loop.data == (void*) &loop);
|
|
|
|
+ uv_library_shutdown(&context);
|
|
return 0;
|
|
}
|
|
|
|
@@ -65,11 +68,15 @@ static void loop_instant_close_after_work_cb(uv_work_t* req, int status) {
|
|
TEST_IMPL(loop_instant_close) {
|
|
static uv_loop_t loop;
|
|
static uv_work_t req;
|
|
- ASSERT(0 == uv_loop_init(&loop));
|
|
+
|
|
+ uv_context_t context;
|
|
+ uv_library_init(&context);
|
|
+
|
|
+ ASSERT(0 == uv_loop_init(&loop, &context));
|
|
ASSERT(0 == uv_queue_work(&loop,
|
|
&req,
|
|
loop_instant_close_work_cb,
|
|
loop_instant_close_after_work_cb));
|
|
- MAKE_VALGRIND_HAPPY();
|
|
+ MAKE_VALGRIND_HAPPY(&loop);
|
|
return 0;
|
|
}
|
|
diff --git a/test/test-loop-stop.c b/test/test-loop-stop.c
|
|
index 14b8c1118..b40d3ad9b 100644
|
|
--- a/test/test-loop-stop.c
|
|
+++ b/test/test-loop-stop.c
|
|
@@ -41,31 +41,43 @@ static void timer_cb(uv_timer_t* handle) {
|
|
ASSERT(handle == &timer_handle);
|
|
timer_called++;
|
|
if (timer_called == 1)
|
|
- uv_stop(uv_default_loop());
|
|
+ uv_stop(handle->loop);
|
|
else if (timer_called == num_ticks)
|
|
uv_timer_stop(handle);
|
|
}
|
|
|
|
|
|
TEST_IMPL(loop_stop) {
|
|
+ uv_context_t context;
|
|
+ uv_loop_t *loop;
|
|
+ uv_library_init(&context);
|
|
+ loop = uv_default_loop(&context);
|
|
+
|
|
int r;
|
|
- uv_prepare_init(uv_default_loop(), &prepare_handle);
|
|
+
|
|
+ prepare_called = 0;
|
|
+ timer_called = 0;
|
|
+ num_ticks = 10;
|
|
+
|
|
+ uv_prepare_init(loop, &prepare_handle);
|
|
uv_prepare_start(&prepare_handle, prepare_cb);
|
|
- uv_timer_init(uv_default_loop(), &timer_handle);
|
|
+ uv_timer_init(loop, &timer_handle);
|
|
uv_timer_start(&timer_handle, timer_cb, 100, 100);
|
|
|
|
- r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
|
+ r = uv_run(loop, UV_RUN_DEFAULT);
|
|
ASSERT(r != 0);
|
|
ASSERT(timer_called == 1);
|
|
|
|
- r = uv_run(uv_default_loop(), UV_RUN_NOWAIT);
|
|
+ r = uv_run(loop, UV_RUN_NOWAIT);
|
|
ASSERT(r != 0);
|
|
ASSERT(prepare_called > 1);
|
|
|
|
- r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
|
+ r = uv_run(loop, UV_RUN_DEFAULT);
|
|
ASSERT(r == 0);
|
|
ASSERT(timer_called == 10);
|
|
ASSERT(prepare_called == 10);
|
|
|
|
+ MAKE_VALGRIND_HAPPY(loop);
|
|
+
|
|
return 0;
|
|
}
|
|
diff --git a/test/test-loop-time.c b/test/test-loop-time.c
|
|
index a2db42cce..581f31b9e 100644
|
|
--- a/test/test-loop-time.c
|
|
+++ b/test/test-loop-time.c
|
|
@@ -1,3 +1,23 @@
|
|
+/****************************************************************************
|
|
+ * test-loop-time.c
|
|
+ *
|
|
+ * Licensed to the Apache Software Foundation (ASF) under one or more
|
|
+ * contributor license agreements. See the NOTICE file distributed with
|
|
+ * this work for additional information regarding copyright ownership. The
|
|
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
+ * "License"); you may not use this file except in compliance with the
|
|
+ * License. You may obtain a copy of the License at
|
|
+ *
|
|
+ * http://www.apache.org/licenses/LICENSE-2.0
|
|
+ *
|
|
+ * Unless required by applicable law or agreed to in writing, software
|
|
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
+ * License for the specific language governing permissions and limitations
|
|
+ * under the License.
|
|
+ *
|
|
+ ****************************************************************************/
|
|
+
|
|
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
@@ -24,13 +44,20 @@
|
|
|
|
|
|
TEST_IMPL(loop_update_time) {
|
|
- uint64_t start;
|
|
+ uv_time_t start;
|
|
+ uv_context_t context;
|
|
+ uv_loop_t *loop;
|
|
+ uv_library_init(&context);
|
|
+ loop = uv_default_loop(&context);
|
|
|
|
- start = uv_now(uv_default_loop());
|
|
- while (uv_now(uv_default_loop()) - start < 1000)
|
|
- ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_NOWAIT));
|
|
+ start = uv_now(loop);
|
|
+ while (uv_now(loop) - start < 1000) {
|
|
+ /* Let NuttX update time */
|
|
+ usleep(100*1000);
|
|
+ ASSERT(0 == uv_run(loop, UV_RUN_NOWAIT));
|
|
+ }
|
|
|
|
- MAKE_VALGRIND_HAPPY();
|
|
+ MAKE_VALGRIND_HAPPY(loop);
|
|
return 0;
|
|
}
|
|
|
|
@@ -39,9 +66,12 @@ static void cb(uv_timer_t* timer) {
|
|
}
|
|
|
|
TEST_IMPL(loop_backend_timeout) {
|
|
- uv_loop_t *loop = uv_default_loop();
|
|
uv_timer_t timer;
|
|
int r;
|
|
+ uv_context_t context;
|
|
+ uv_loop_t *loop;
|
|
+ uv_library_init(&context);
|
|
+ loop = uv_default_loop(&context);
|
|
|
|
r = uv_timer_init(loop, &timer);
|
|
ASSERT(r == 0);
|
|
@@ -58,6 +88,6 @@ TEST_IMPL(loop_backend_timeout) {
|
|
ASSERT(r == 0);
|
|
ASSERT(uv_backend_timeout(loop) == 0);
|
|
|
|
- MAKE_VALGRIND_HAPPY();
|
|
+ MAKE_VALGRIND_HAPPY(loop);
|
|
return 0;
|
|
}
|
|
diff --git a/test/test-ping-pong.c b/test/test-ping-pong.c
|
|
index c86a3f4a6..50e47d6a3 100644
|
|
--- a/test/test-ping-pong.c
|
|
+++ b/test/test-ping-pong.c
|
|
@@ -49,7 +49,7 @@ typedef struct {
|
|
uv_pipe_t pipe;
|
|
} stream;
|
|
uv_connect_t connect_req;
|
|
- char read_buffer[BUFSIZE];
|
|
+ // char read_buffer[BUFSIZE];
|
|
} pinger_t;
|
|
|
|
|
|
@@ -102,7 +102,34 @@ static void pinger_write_ping(pinger_t* pinger) {
|
|
FATAL("uv_write failed");
|
|
}
|
|
|
|
- puts("PING");
|
|
+ // puts("PING");
|
|
+}
|
|
+
|
|
+
|
|
+static void pinger_after_stop_write(uv_write_t *req, int status) {
|
|
+ ASSERT(status == 0);
|
|
+ pinger_t* pinger = (pinger_t*)req->data;
|
|
+ uv_close((uv_handle_t*)(&pinger->stream.tcp), pinger_on_close);
|
|
+ free(req);
|
|
+}
|
|
+
|
|
+
|
|
+static void pinger_write_stop(pinger_t* pinger) {
|
|
+ uv_write_t *req;
|
|
+ uv_buf_t bufs;
|
|
+
|
|
+ bufs.base = "QQS";
|
|
+ bufs.len = 3;
|
|
+
|
|
+ req = malloc(sizeof(*req));
|
|
+ req->data = pinger;
|
|
+ if (uv_write(req,
|
|
+ (uv_stream_t*) &pinger->stream.tcp,
|
|
+ &bufs,
|
|
+ 1,
|
|
+ pinger_after_stop_write)) {
|
|
+ FATAL("uv_write failed");
|
|
+ }
|
|
}
|
|
|
|
|
|
@@ -133,13 +160,13 @@ static void pinger_read_cb(uv_stream_t* stream,
|
|
if (pinger->state != 0)
|
|
continue;
|
|
|
|
- printf("PONG %d\n", pinger->pongs);
|
|
+ // printf("PONG %d\n", pinger->pongs);
|
|
pinger->pongs++;
|
|
|
|
if (pinger->pongs < NUM_PINGS) {
|
|
pinger_write_ping(pinger);
|
|
} else {
|
|
- uv_close((uv_handle_t*)(&pinger->stream.tcp), pinger_on_close);
|
|
+ pinger_write_stop(pinger);
|
|
break;
|
|
}
|
|
}
|
|
@@ -164,7 +191,7 @@ static void pinger_on_connect(uv_connect_t *req, int status) {
|
|
uv_read_start((uv_stream_t*)(req->handle), alloc_cb, pinger_read_cb);
|
|
}
|
|
|
|
-
|
|
+#if 0
|
|
/* same ping-pong test, but using IPv6 connection */
|
|
static void tcp_pinger_v6_new(int vectored_writes) {
|
|
int r;
|
|
@@ -195,13 +222,16 @@ static void tcp_pinger_v6_new(int vectored_writes) {
|
|
/* Synchronous connect callbacks are not allowed. */
|
|
ASSERT(pinger_on_connect_count == 0);
|
|
}
|
|
+#endif
|
|
|
|
-
|
|
-static void tcp_pinger_new(int vectored_writes) {
|
|
+static void tcp_pinger_new(uv_context_t *ctx, int vectored_writes) {
|
|
int r;
|
|
struct sockaddr_in server_addr;
|
|
pinger_t *pinger;
|
|
|
|
+ pinger_on_connect_count = 0;
|
|
+ completed_pingers = 0;
|
|
+
|
|
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &server_addr));
|
|
pinger = malloc(sizeof(*pinger));
|
|
ASSERT(pinger != NULL);
|
|
@@ -210,7 +240,7 @@ static void tcp_pinger_new(int vectored_writes) {
|
|
pinger->pongs = 0;
|
|
|
|
/* Try to connect to the server and do NUM_PINGS ping-pongs. */
|
|
- r = uv_tcp_init(uv_default_loop(), &pinger->stream.tcp);
|
|
+ r = uv_tcp_init(uv_default_loop(ctx), &pinger->stream.tcp);
|
|
pinger->stream.tcp.data = pinger;
|
|
ASSERT(!r);
|
|
|
|
@@ -226,11 +256,14 @@ static void tcp_pinger_new(int vectored_writes) {
|
|
ASSERT(pinger_on_connect_count == 0);
|
|
}
|
|
|
|
-
|
|
-static void pipe_pinger_new(int vectored_writes) {
|
|
+#if 0
|
|
+static void pipe_pinger_new(uv_context_t *ctx, int vectored_writes) {
|
|
int r;
|
|
pinger_t *pinger;
|
|
|
|
+ pinger_on_connect_count = 0;
|
|
+ completed_pingers = 0;
|
|
+
|
|
pinger = (pinger_t*)malloc(sizeof(*pinger));
|
|
ASSERT(pinger != NULL);
|
|
pinger->vectored_writes = vectored_writes;
|
|
@@ -238,7 +271,7 @@ static void pipe_pinger_new(int vectored_writes) {
|
|
pinger->pongs = 0;
|
|
|
|
/* Try to connect to the server and do NUM_PINGS ping-pongs. */
|
|
- r = uv_pipe_init(uv_default_loop(), &pinger->stream.pipe, 0);
|
|
+ r = uv_pipe_init(uv_default_loop(ctx), &pinger->stream.pipe, 0);
|
|
pinger->stream.pipe.data = pinger;
|
|
ASSERT(!r);
|
|
|
|
@@ -250,29 +283,34 @@ static void pipe_pinger_new(int vectored_writes) {
|
|
/* Synchronous connect callbacks are not allowed. */
|
|
ASSERT(pinger_on_connect_count == 0);
|
|
}
|
|
+#endif
|
|
|
|
-
|
|
-static int run_ping_pong_test(void) {
|
|
- uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
|
+static int run_ping_pong_test(uv_context_t *ctx) {
|
|
+ uv_loop_t *loop = uv_default_loop(ctx);
|
|
+ uv_run(loop, UV_RUN_DEFAULT);
|
|
ASSERT(completed_pingers == 1);
|
|
|
|
- MAKE_VALGRIND_HAPPY();
|
|
+ MAKE_VALGRIND_HAPPY(loop);
|
|
return 0;
|
|
}
|
|
|
|
|
|
TEST_IMPL(tcp_ping_pong) {
|
|
- tcp_pinger_new(0);
|
|
- return run_ping_pong_test();
|
|
+ uv_context_t context;
|
|
+ uv_library_init(&context);
|
|
+ tcp_pinger_new(&context, 0);
|
|
+ return run_ping_pong_test(&context);
|
|
}
|
|
|
|
|
|
TEST_IMPL(tcp_ping_pong_vec) {
|
|
- tcp_pinger_new(1);
|
|
- return run_ping_pong_test();
|
|
+ uv_context_t context;
|
|
+ uv_library_init(&context);
|
|
+ tcp_pinger_new(&context, 1);
|
|
+ return run_ping_pong_test(&context);
|
|
}
|
|
|
|
-
|
|
+#if 0
|
|
TEST_IMPL(tcp6_ping_pong) {
|
|
if (!can_ipv6())
|
|
RETURN_SKIP("IPv6 not supported");
|
|
@@ -288,14 +326,18 @@ TEST_IMPL(tcp6_ping_pong_vec) {
|
|
return run_ping_pong_test();
|
|
}
|
|
|
|
-
|
|
TEST_IMPL(pipe_ping_pong) {
|
|
- pipe_pinger_new(0);
|
|
- return run_ping_pong_test();
|
|
+ uv_context_t context;
|
|
+ uv_library_init(&context);
|
|
+ pipe_pinger_new(&context, 0);
|
|
+ return run_ping_pong_test(&context);
|
|
}
|
|
|
|
|
|
TEST_IMPL(pipe_ping_pong_vec) {
|
|
- pipe_pinger_new(1);
|
|
- return run_ping_pong_test();
|
|
+ uv_context_t context;
|
|
+ uv_library_init(&context);
|
|
+ pipe_pinger_new(&context, 1);
|
|
+ return run_ping_pong_test(&context);
|
|
}
|
|
+#endif
|
|
diff --git a/test/test-poll-close.c b/test/test-poll-close.c
|
|
index 2eccddf5b..c5b059d03 100644
|
|
--- a/test/test-poll-close.c
|
|
+++ b/test/test-poll-close.c
|
|
@@ -30,7 +30,7 @@
|
|
#include "uv.h"
|
|
#include "task.h"
|
|
|
|
-#define NUM_SOCKETS 64
|
|
+#define NUM_SOCKETS 4
|
|
|
|
|
|
static int close_cb_called = 0;
|
|
@@ -42,10 +42,17 @@ static void close_cb(uv_handle_t* handle) {
|
|
|
|
|
|
TEST_IMPL(poll_close) {
|
|
+ uv_context_t context;
|
|
+ uv_loop_t *loop;
|
|
+ uv_library_init(&context);
|
|
+ loop = uv_default_loop(&context);
|
|
+
|
|
uv_os_sock_t sockets[NUM_SOCKETS];
|
|
uv_poll_t poll_handles[NUM_SOCKETS];
|
|
int i;
|
|
|
|
+ close_cb_called = 0;
|
|
+
|
|
#ifdef _WIN32
|
|
{
|
|
struct WSAData wsa_data;
|
|
@@ -56,18 +63,19 @@ TEST_IMPL(poll_close) {
|
|
|
|
for (i = 0; i < NUM_SOCKETS; i++) {
|
|
sockets[i] = socket(AF_INET, SOCK_STREAM, 0);
|
|
- uv_poll_init_socket(uv_default_loop(), &poll_handles[i], sockets[i]);
|
|
+ uv_poll_init_socket(loop, &poll_handles[i], sockets[i]);
|
|
uv_poll_start(&poll_handles[i], UV_READABLE | UV_WRITABLE, NULL);
|
|
}
|
|
|
|
for (i = 0; i < NUM_SOCKETS; i++) {
|
|
uv_close((uv_handle_t*) &poll_handles[i], close_cb);
|
|
+ close(sockets[i]);
|
|
}
|
|
|
|
- uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
|
+ uv_run(loop, UV_RUN_DEFAULT);
|
|
|
|
ASSERT(close_cb_called == NUM_SOCKETS);
|
|
|
|
- MAKE_VALGRIND_HAPPY();
|
|
+ MAKE_VALGRIND_HAPPY(loop);
|
|
return 0;
|
|
}
|
|
diff --git a/test/test-random.c b/test/test-random.c
|
|
index 2e3ce4424..da2034457 100644
|
|
--- a/test/test-random.c
|
|
+++ b/test/test-random.c
|
|
@@ -24,7 +24,11 @@
|
|
|
|
#include <string.h>
|
|
|
|
+#ifdef __NUTTX__
|
|
+static char scratch[64];
|
|
+#else
|
|
static char scratch[256];
|
|
+#endif
|
|
static int random_cb_called;
|
|
|
|
|
|
@@ -52,8 +56,13 @@ static void random_cb(uv_random_t* req, int status, void* buf, size_t buflen) {
|
|
TEST_IMPL(random_async) {
|
|
uv_random_t req;
|
|
uv_loop_t* loop;
|
|
+ uv_context_t context;
|
|
+ uv_library_init(&context);
|
|
|
|
- loop = uv_default_loop();
|
|
+ random_cb_called = 0;
|
|
+ memset(scratch, 0, sizeof(scratch));
|
|
+
|
|
+ loop = uv_default_loop(&context);
|
|
ASSERT(UV_EINVAL == uv_random(loop, &req, scratch, sizeof(scratch), -1,
|
|
random_cb));
|
|
ASSERT(UV_E2BIG == uv_random(loop, &req, scratch, -1, -1, random_cb));
|
|
@@ -70,14 +79,22 @@ TEST_IMPL(random_async) {
|
|
ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
|
|
ASSERT(2 == random_cb_called);
|
|
|
|
- MAKE_VALGRIND_HAPPY();
|
|
+ MAKE_VALGRIND_HAPPY(loop);
|
|
return 0;
|
|
}
|
|
|
|
|
|
TEST_IMPL(random_sync) {
|
|
+#ifdef __NUTTX__
|
|
+ char zero[64];
|
|
+ char buf[64];
|
|
+#else
|
|
char zero[256];
|
|
char buf[256];
|
|
+#endif
|
|
+
|
|
+ uv_context_t context;
|
|
+ uv_library_init(&context);
|
|
|
|
ASSERT(UV_EINVAL == uv_random(NULL, NULL, buf, sizeof(buf), -1, NULL));
|
|
ASSERT(UV_E2BIG == uv_random(NULL, NULL, buf, -1, -1, NULL));
|
|
@@ -89,6 +106,6 @@ TEST_IMPL(random_sync) {
|
|
memset(zero, 0, sizeof(zero));
|
|
ASSERT(0 != memcmp(buf, zero, sizeof(zero)));
|
|
|
|
- MAKE_VALGRIND_HAPPY();
|
|
+ uv_library_shutdown(&context);
|
|
return 0;
|
|
}
|
|
diff --git a/test/test-tcp-read-stop.c b/test/test-tcp-read-stop.c
|
|
index 488e8fb49..251d25a11 100644
|
|
--- a/test/test-tcp-read-stop.c
|
|
+++ b/test/test-tcp-read-stop.c
|
|
@@ -59,18 +59,23 @@ static void connect_cb(uv_connect_t* req, int status) {
|
|
|
|
|
|
TEST_IMPL(tcp_read_stop) {
|
|
+ uv_context_t context;
|
|
+ uv_loop_t *loop;
|
|
+ uv_library_init(&context);
|
|
+ loop = uv_default_loop(&context);
|
|
+
|
|
uv_connect_t connect_req;
|
|
struct sockaddr_in addr;
|
|
|
|
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
|
|
- ASSERT(0 == uv_timer_init(uv_default_loop(), &timer_handle));
|
|
- ASSERT(0 == uv_tcp_init(uv_default_loop(), &tcp_handle));
|
|
+ ASSERT(0 == uv_timer_init(loop, &timer_handle));
|
|
+ ASSERT(0 == uv_tcp_init(loop, &tcp_handle));
|
|
ASSERT(0 == uv_tcp_connect(&connect_req,
|
|
&tcp_handle,
|
|
(const struct sockaddr*) &addr,
|
|
connect_cb));
|
|
- ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
|
|
- MAKE_VALGRIND_HAPPY();
|
|
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
|
|
+ MAKE_VALGRIND_HAPPY(loop);
|
|
|
|
return 0;
|
|
}
|
|
diff --git a/test/test-tcp-write-after-connect.c b/test/test-tcp-write-after-connect.c
|
|
index 8a698f44b..35ccc181d 100644
|
|
--- a/test/test-tcp-write-after-connect.c
|
|
+++ b/test/test-tcp-write-after-connect.c
|
|
@@ -32,7 +32,12 @@ uv_buf_t buf = { "HELLO", 4 };
|
|
|
|
|
|
static void write_cb(uv_write_t *req, int status) {
|
|
+#if 0
|
|
ASSERT(status == UV_ECANCELED);
|
|
+#else
|
|
+ ASSERT_WARN("FIXME test behaviour not libuv compliant");
|
|
+ ASSERT(status == -ENOTCONN);
|
|
+#endif
|
|
uv_close((uv_handle_t*) req->handle, NULL);
|
|
}
|
|
|
|
@@ -47,13 +52,21 @@ TEST_IMPL(tcp_write_after_connect) {
|
|
#if defined(__QEMU__)
|
|
RETURN_SKIP("Test does not currently work in QEMU");
|
|
#endif
|
|
+ uv_context_t context;
|
|
+ uv_library_init(&context);
|
|
|
|
struct sockaddr_in sa;
|
|
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &sa));
|
|
- ASSERT(0 == uv_loop_init(&loop));
|
|
+ ASSERT(0 == uv_loop_init(&loop, &context));
|
|
ASSERT(0 == uv_tcp_init(&loop, &tcp_client));
|
|
|
|
+#if 0
|
|
ASSERT(0 == uv_tcp_connect(&connection_request,
|
|
+#else
|
|
+ /* FIXME NuttX does not support NONBLOCKING for tcp_connect */
|
|
+ ASSERT_WARN("FIXME test behaviour not libuv compliant");
|
|
+ ASSERT(-ECONNREFUSED == uv_tcp_connect(&connection_request,
|
|
+#endif
|
|
&tcp_client,
|
|
(const struct sockaddr *)
|
|
&sa,
|
|
@@ -66,7 +79,7 @@ TEST_IMPL(tcp_write_after_connect) {
|
|
|
|
uv_run(&loop, UV_RUN_DEFAULT);
|
|
|
|
- MAKE_VALGRIND_HAPPY();
|
|
+ MAKE_VALGRIND_HAPPY(&loop);
|
|
return 0;
|
|
}
|
|
|
|
diff --git a/test/test-threadpool.c b/test/test-threadpool.c
|
|
index e3d17d754..09b86d5cf 100644
|
|
--- a/test/test-threadpool.c
|
|
+++ b/test/test-threadpool.c
|
|
@@ -44,33 +44,49 @@ static void after_work_cb(uv_work_t* req, int status) {
|
|
|
|
|
|
TEST_IMPL(threadpool_queue_work_simple) {
|
|
+ uv_context_t context;
|
|
+ uv_loop_t *loop;
|
|
+ uv_library_init(&context);
|
|
+ loop = uv_default_loop(&context);
|
|
+
|
|
int r;
|
|
|
|
+ work_cb_count = 0;
|
|
+ after_work_cb_count = 0;
|
|
+
|
|
work_req.data = &data;
|
|
- r = uv_queue_work(uv_default_loop(), &work_req, work_cb, after_work_cb);
|
|
+ r = uv_queue_work(loop, &work_req, work_cb, after_work_cb);
|
|
ASSERT(r == 0);
|
|
- uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
|
+ uv_run(loop, UV_RUN_DEFAULT);
|
|
|
|
ASSERT(work_cb_count == 1);
|
|
ASSERT(after_work_cb_count == 1);
|
|
|
|
- MAKE_VALGRIND_HAPPY();
|
|
+ MAKE_VALGRIND_HAPPY(loop);
|
|
return 0;
|
|
}
|
|
|
|
|
|
TEST_IMPL(threadpool_queue_work_einval) {
|
|
+ uv_context_t context;
|
|
+ uv_loop_t *loop;
|
|
+ uv_library_init(&context);
|
|
+ loop = uv_default_loop(&context);
|
|
+
|
|
int r;
|
|
|
|
+ work_cb_count = 0;
|
|
+ after_work_cb_count = 0;
|
|
+
|
|
work_req.data = &data;
|
|
- r = uv_queue_work(uv_default_loop(), &work_req, NULL, after_work_cb);
|
|
+ r = uv_queue_work(loop, &work_req, NULL, after_work_cb);
|
|
ASSERT(r == UV_EINVAL);
|
|
|
|
- uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
|
+ uv_run(loop, UV_RUN_DEFAULT);
|
|
|
|
ASSERT(work_cb_count == 0);
|
|
ASSERT(after_work_cb_count == 0);
|
|
|
|
- MAKE_VALGRIND_HAPPY();
|
|
+ MAKE_VALGRIND_HAPPY(loop);
|
|
return 0;
|
|
}
|
|
diff --git a/test/test-timer-again.c b/test/test-timer-again.c
|
|
index e87d2edf1..8fd0854b8 100644
|
|
--- a/test/test-timer-again.c
|
|
+++ b/test/test-timer-again.c
|
|
@@ -48,7 +48,7 @@ static void repeat_1_cb(uv_timer_t* handle) {
|
|
ASSERT(uv_timer_get_repeat((uv_timer_t*)handle) == 50);
|
|
|
|
fprintf(stderr, "repeat_1_cb called after %ld ms\n",
|
|
- (long int)(uv_now(uv_default_loop()) - start_time));
|
|
+ (long int)(uv_now(handle->loop) - start_time));
|
|
fflush(stderr);
|
|
|
|
repeat_1_cb_called++;
|
|
@@ -71,7 +71,7 @@ static void repeat_2_cb(uv_timer_t* handle) {
|
|
ASSERT(repeat_2_cb_allowed);
|
|
|
|
fprintf(stderr, "repeat_2_cb called after %ld ms\n",
|
|
- (long int)(uv_now(uv_default_loop()) - start_time));
|
|
+ (long int)(uv_now(handle->loop) - start_time));
|
|
fflush(stderr);
|
|
|
|
repeat_2_cb_called++;
|
|
@@ -93,20 +93,30 @@ static void repeat_2_cb(uv_timer_t* handle) {
|
|
|
|
|
|
TEST_IMPL(timer_again) {
|
|
+ uv_context_t context;
|
|
+ uv_loop_t *loop;
|
|
+ uv_library_init(&context);
|
|
+ loop = uv_default_loop(&context);
|
|
+
|
|
int r;
|
|
|
|
- start_time = uv_now(uv_default_loop());
|
|
+ close_cb_called = 0;
|
|
+ repeat_1_cb_called = 0;
|
|
+ repeat_2_cb_called = 0;
|
|
+ repeat_2_cb_allowed = 0;
|
|
+
|
|
+ start_time = uv_now(loop);
|
|
ASSERT(0 < start_time);
|
|
|
|
/* Verify that it is not possible to uv_timer_again a never-started timer. */
|
|
- r = uv_timer_init(uv_default_loop(), &dummy);
|
|
+ r = uv_timer_init(loop, &dummy);
|
|
ASSERT(r == 0);
|
|
r = uv_timer_again(&dummy);
|
|
ASSERT(r == UV_EINVAL);
|
|
uv_unref((uv_handle_t*)&dummy);
|
|
|
|
/* Start timer repeat_1. */
|
|
- r = uv_timer_init(uv_default_loop(), &repeat_1);
|
|
+ r = uv_timer_init(loop, &repeat_1);
|
|
ASSERT(r == 0);
|
|
r = uv_timer_start(&repeat_1, repeat_1_cb, 50, 0);
|
|
ASSERT(r == 0);
|
|
@@ -120,22 +130,22 @@ TEST_IMPL(timer_again) {
|
|
* Start another repeating timer. It'll be again()ed by the repeat_1 so
|
|
* it should not time out until repeat_1 stops.
|
|
*/
|
|
- r = uv_timer_init(uv_default_loop(), &repeat_2);
|
|
+ r = uv_timer_init(loop, &repeat_2);
|
|
ASSERT(r == 0);
|
|
r = uv_timer_start(&repeat_2, repeat_2_cb, 100, 100);
|
|
ASSERT(r == 0);
|
|
ASSERT(uv_timer_get_repeat(&repeat_2) == 100);
|
|
|
|
- uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
|
+ uv_run(loop, UV_RUN_DEFAULT);
|
|
|
|
ASSERT(repeat_1_cb_called == 10);
|
|
ASSERT(repeat_2_cb_called == 2);
|
|
ASSERT(close_cb_called == 2);
|
|
|
|
fprintf(stderr, "Test took %ld ms (expected ~700 ms)\n",
|
|
- (long int)(uv_now(uv_default_loop()) - start_time));
|
|
+ (long int)(uv_now(loop) - start_time));
|
|
fflush(stderr);
|
|
|
|
- MAKE_VALGRIND_HAPPY();
|
|
+ MAKE_VALGRIND_HAPPY(loop);
|
|
return 0;
|
|
}
|
|
diff --git a/test/test-timer-from-check.c b/test/test-timer-from-check.c
|
|
index a18c7e1fb..d99c7f4c3 100644
|
|
--- a/test/test-timer-from-check.c
|
|
+++ b/test/test-timer-from-check.c
|
|
@@ -62,19 +62,28 @@ static void check_cb(uv_check_t* handle) {
|
|
|
|
|
|
TEST_IMPL(timer_from_check) {
|
|
- ASSERT(0 == uv_prepare_init(uv_default_loop(), &prepare_handle));
|
|
- ASSERT(0 == uv_check_init(uv_default_loop(), &check_handle));
|
|
+ uv_context_t context;
|
|
+ uv_loop_t *loop;
|
|
+ uv_library_init(&context);
|
|
+ loop = uv_default_loop(&context);
|
|
+
|
|
+ prepare_cb_called = 0;
|
|
+ check_cb_called = 0;
|
|
+ timer_cb_called = 0;
|
|
+
|
|
+ ASSERT(0 == uv_prepare_init(loop, &prepare_handle));
|
|
+ ASSERT(0 == uv_check_init(loop, &check_handle));
|
|
ASSERT(0 == uv_check_start(&check_handle, check_cb));
|
|
- ASSERT(0 == uv_timer_init(uv_default_loop(), &timer_handle));
|
|
+ ASSERT(0 == uv_timer_init(loop, &timer_handle));
|
|
ASSERT(0 == uv_timer_start(&timer_handle, timer_cb, 50, 0));
|
|
- ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
|
|
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
|
|
ASSERT(1 == prepare_cb_called);
|
|
ASSERT(1 == check_cb_called);
|
|
ASSERT(1 == timer_cb_called);
|
|
uv_close((uv_handle_t*) &prepare_handle, NULL);
|
|
uv_close((uv_handle_t*) &check_handle, NULL);
|
|
uv_close((uv_handle_t*) &timer_handle, NULL);
|
|
- ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE));
|
|
- MAKE_VALGRIND_HAPPY();
|
|
+ ASSERT(0 == uv_run(loop, UV_RUN_ONCE));
|
|
+ MAKE_VALGRIND_HAPPY(loop);
|
|
return 0;
|
|
}
|
|
diff --git a/test/test-timer.c b/test/test-timer.c
|
|
index c667da00e..dac515dd1 100644
|
|
--- a/test/test-timer.c
|
|
+++ b/test/test-timer.c
|
|
@@ -45,6 +45,7 @@ static void once_close_cb(uv_handle_t* handle) {
|
|
|
|
|
|
static void once_cb(uv_timer_t* handle) {
|
|
+ uv_loop_t *loop = handle->loop;
|
|
printf("ONCE_CB %d\n", once_cb_called);
|
|
|
|
ASSERT(handle != NULL);
|
|
@@ -55,7 +56,7 @@ static void once_cb(uv_timer_t* handle) {
|
|
uv_close((uv_handle_t*)handle, once_close_cb);
|
|
|
|
/* Just call this randomly for the code coverage. */
|
|
- uv_update_time(uv_default_loop());
|
|
+ uv_update_time(loop);
|
|
}
|
|
|
|
|
|
@@ -88,32 +89,42 @@ static void never_cb(uv_timer_t* handle) {
|
|
|
|
|
|
TEST_IMPL(timer) {
|
|
+ uv_context_t context;
|
|
+ uv_loop_t *loop;
|
|
+ uv_library_init(&context);
|
|
+ loop = uv_default_loop(&context);
|
|
+
|
|
uv_timer_t once_timers[10];
|
|
uv_timer_t *once;
|
|
uv_timer_t repeat, never;
|
|
unsigned int i;
|
|
int r;
|
|
|
|
- start_time = uv_now(uv_default_loop());
|
|
+ once_cb_called = 0;
|
|
+ once_close_cb_called = 0;
|
|
+ repeat_cb_called = 0;
|
|
+ repeat_close_cb_called = 0;
|
|
+
|
|
+ start_time = uv_now(loop);
|
|
ASSERT(0 < start_time);
|
|
|
|
/* Let 10 timers time out in 500 ms total. */
|
|
for (i = 0; i < ARRAY_SIZE(once_timers); i++) {
|
|
once = once_timers + i;
|
|
- r = uv_timer_init(uv_default_loop(), once);
|
|
+ r = uv_timer_init(loop, once);
|
|
ASSERT(r == 0);
|
|
r = uv_timer_start(once, once_cb, i * 50, 0);
|
|
ASSERT(r == 0);
|
|
}
|
|
|
|
/* The 11th timer is a repeating timer that runs 4 times */
|
|
- r = uv_timer_init(uv_default_loop(), &repeat);
|
|
+ r = uv_timer_init(loop, &repeat);
|
|
ASSERT(r == 0);
|
|
r = uv_timer_start(&repeat, repeat_cb, 100, 100);
|
|
ASSERT(r == 0);
|
|
|
|
/* The 12th timer should not do anything. */
|
|
- r = uv_timer_init(uv_default_loop(), &never);
|
|
+ r = uv_timer_init(loop, &never);
|
|
ASSERT(r == 0);
|
|
r = uv_timer_start(&never, never_cb, 100, 100);
|
|
ASSERT(r == 0);
|
|
@@ -121,7 +132,7 @@ TEST_IMPL(timer) {
|
|
ASSERT(r == 0);
|
|
uv_unref((uv_handle_t*)&never);
|
|
|
|
- uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
|
+ uv_run(loop, UV_RUN_DEFAULT);
|
|
|
|
ASSERT(once_cb_called == 10);
|
|
ASSERT(once_close_cb_called == 10);
|
|
@@ -129,41 +140,53 @@ TEST_IMPL(timer) {
|
|
ASSERT(repeat_cb_called == 5);
|
|
ASSERT(repeat_close_cb_called == 1);
|
|
|
|
- ASSERT(500 <= uv_now(uv_default_loop()) - start_time);
|
|
+ ASSERT(500 <= uv_now(loop) - start_time);
|
|
|
|
- MAKE_VALGRIND_HAPPY();
|
|
+ MAKE_VALGRIND_HAPPY(loop);
|
|
return 0;
|
|
}
|
|
|
|
|
|
TEST_IMPL(timer_start_twice) {
|
|
+ uv_context_t context;
|
|
+ uv_loop_t *loop;
|
|
+ uv_library_init(&context);
|
|
+ loop = uv_default_loop(&context);
|
|
+
|
|
uv_timer_t once;
|
|
int r;
|
|
|
|
- r = uv_timer_init(uv_default_loop(), &once);
|
|
+ once_cb_called = 0;
|
|
+
|
|
+ r = uv_timer_init(loop, &once);
|
|
ASSERT(r == 0);
|
|
r = uv_timer_start(&once, never_cb, 86400 * 1000, 0);
|
|
ASSERT(r == 0);
|
|
r = uv_timer_start(&once, once_cb, 10, 0);
|
|
ASSERT(r == 0);
|
|
- r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
|
|
+ r = uv_run(loop, UV_RUN_DEFAULT);
|
|
ASSERT(r == 0);
|
|
|
|
ASSERT(once_cb_called == 1);
|
|
|
|
- MAKE_VALGRIND_HAPPY();
|
|
+ MAKE_VALGRIND_HAPPY(loop);
|
|
return 0;
|
|
}
|
|
|
|
|
|
TEST_IMPL(timer_init) {
|
|
+ uv_context_t context;
|
|
+ uv_loop_t *loop;
|
|
+ uv_library_init(&context);
|
|
+ loop = uv_default_loop(&context);
|
|
+
|
|
uv_timer_t handle;
|
|
|
|
- ASSERT(0 == uv_timer_init(uv_default_loop(), &handle));
|
|
+ ASSERT(0 == uv_timer_init(loop, &handle));
|
|
ASSERT(0 == uv_timer_get_repeat(&handle));
|
|
ASSERT(0 == uv_is_active((uv_handle_t*) &handle));
|
|
|
|
- MAKE_VALGRIND_HAPPY();
|
|
+ MAKE_VALGRIND_HAPPY(loop);
|
|
return 0;
|
|
}
|
|
|
|
@@ -179,22 +202,29 @@ static void order_cb_b(uv_timer_t *handle) {
|
|
|
|
|
|
TEST_IMPL(timer_order) {
|
|
+ uv_context_t context;
|
|
+ uv_loop_t *loop;
|
|
+ uv_library_init(&context);
|
|
+ loop = uv_default_loop(&context);
|
|
+
|
|
int first;
|
|
int second;
|
|
uv_timer_t handle_a;
|
|
uv_timer_t handle_b;
|
|
|
|
+ order_cb_called = 0;
|
|
+
|
|
first = 0;
|
|
second = 1;
|
|
- ASSERT(0 == uv_timer_init(uv_default_loop(), &handle_a));
|
|
- ASSERT(0 == uv_timer_init(uv_default_loop(), &handle_b));
|
|
+ ASSERT(0 == uv_timer_init(loop, &handle_a));
|
|
+ ASSERT(0 == uv_timer_init(loop, &handle_b));
|
|
|
|
/* Test for starting handle_a then handle_b */
|
|
handle_a.data = &first;
|
|
ASSERT(0 == uv_timer_start(&handle_a, order_cb_a, 0, 0));
|
|
handle_b.data = &second;
|
|
ASSERT(0 == uv_timer_start(&handle_b, order_cb_b, 0, 0));
|
|
- ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
|
|
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
|
|
|
|
ASSERT(order_cb_called == 2);
|
|
|
|
@@ -208,11 +238,11 @@ TEST_IMPL(timer_order) {
|
|
|
|
handle_a.data = &second;
|
|
ASSERT(0 == uv_timer_start(&handle_a, order_cb_a, 0, 0));
|
|
- ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
|
|
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
|
|
|
|
ASSERT(order_cb_called == 2);
|
|
|
|
- MAKE_VALGRIND_HAPPY();
|
|
+ MAKE_VALGRIND_HAPPY(loop);
|
|
return 0;
|
|
}
|
|
|
|
@@ -226,21 +256,26 @@ static void tiny_timer_cb(uv_timer_t* handle) {
|
|
|
|
|
|
TEST_IMPL(timer_huge_timeout) {
|
|
- ASSERT(0 == uv_timer_init(uv_default_loop(), &tiny_timer));
|
|
- ASSERT(0 == uv_timer_init(uv_default_loop(), &huge_timer1));
|
|
- ASSERT(0 == uv_timer_init(uv_default_loop(), &huge_timer2));
|
|
+ uv_context_t context;
|
|
+ uv_loop_t *loop;
|
|
+ uv_library_init(&context);
|
|
+ loop = uv_default_loop(&context);
|
|
+
|
|
+ ASSERT(0 == uv_timer_init(loop, &tiny_timer));
|
|
+ ASSERT(0 == uv_timer_init(loop, &huge_timer1));
|
|
+ ASSERT(0 == uv_timer_init(loop, &huge_timer2));
|
|
ASSERT(0 == uv_timer_start(&tiny_timer, tiny_timer_cb, 1, 0));
|
|
- ASSERT(0 == uv_timer_start(&huge_timer1, tiny_timer_cb, 0xffffffffffffLL, 0));
|
|
- ASSERT(0 == uv_timer_start(&huge_timer2, tiny_timer_cb, (uint64_t) -1, 0));
|
|
- ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
|
|
- MAKE_VALGRIND_HAPPY();
|
|
+ // ASSERT(0 == uv_timer_start(&huge_timer1, tiny_timer_cb, 0xffffffffffffLL, 0));
|
|
+ ASSERT(0 == uv_timer_start(&huge_timer2, tiny_timer_cb, ((uv_time_t)-1)>>1, 0));
|
|
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
|
|
+ MAKE_VALGRIND_HAPPY(loop);
|
|
return 0;
|
|
}
|
|
|
|
|
|
-static void huge_repeat_cb(uv_timer_t* handle) {
|
|
- static int ncalls;
|
|
+static int ncalls;
|
|
|
|
+static void huge_repeat_cb(uv_timer_t* handle) {
|
|
if (ncalls == 0)
|
|
ASSERT(handle == &huge_timer1);
|
|
else
|
|
@@ -254,12 +289,19 @@ static void huge_repeat_cb(uv_timer_t* handle) {
|
|
|
|
|
|
TEST_IMPL(timer_huge_repeat) {
|
|
- ASSERT(0 == uv_timer_init(uv_default_loop(), &tiny_timer));
|
|
- ASSERT(0 == uv_timer_init(uv_default_loop(), &huge_timer1));
|
|
+ uv_context_t context;
|
|
+ uv_loop_t *loop;
|
|
+ uv_library_init(&context);
|
|
+ loop = uv_default_loop(&context);
|
|
+
|
|
+ ncalls = 0;
|
|
+
|
|
+ ASSERT(0 == uv_timer_init(loop, &tiny_timer));
|
|
+ ASSERT(0 == uv_timer_init(loop, &huge_timer1));
|
|
ASSERT(0 == uv_timer_start(&tiny_timer, huge_repeat_cb, 2, 2));
|
|
- ASSERT(0 == uv_timer_start(&huge_timer1, huge_repeat_cb, 1, (uint64_t) -1));
|
|
- ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
|
|
- MAKE_VALGRIND_HAPPY();
|
|
+ ASSERT(0 == uv_timer_start(&huge_timer1, huge_repeat_cb, 1, ((uv_time_t)-1)>>1));
|
|
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
|
|
+ MAKE_VALGRIND_HAPPY(loop);
|
|
return 0;
|
|
}
|
|
|
|
@@ -273,50 +315,67 @@ static void timer_run_once_timer_cb(uv_timer_t* handle) {
|
|
|
|
|
|
TEST_IMPL(timer_run_once) {
|
|
+ uv_context_t context;
|
|
+ uv_loop_t *loop;
|
|
+ uv_library_init(&context);
|
|
+ loop = uv_default_loop(&context);
|
|
+
|
|
uv_timer_t timer_handle;
|
|
|
|
- ASSERT(0 == uv_timer_init(uv_default_loop(), &timer_handle));
|
|
+ timer_run_once_timer_cb_called = 0;
|
|
+
|
|
+ ASSERT(0 == uv_timer_init(loop, &timer_handle));
|
|
ASSERT(0 == uv_timer_start(&timer_handle, timer_run_once_timer_cb, 0, 0));
|
|
- ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE));
|
|
+ ASSERT(0 == uv_run(loop, UV_RUN_ONCE));
|
|
ASSERT(1 == timer_run_once_timer_cb_called);
|
|
|
|
ASSERT(0 == uv_timer_start(&timer_handle, timer_run_once_timer_cb, 1, 0));
|
|
- ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE));
|
|
+ ASSERT(0 == uv_run(loop, UV_RUN_ONCE));
|
|
ASSERT(2 == timer_run_once_timer_cb_called);
|
|
|
|
uv_close((uv_handle_t*) &timer_handle, NULL);
|
|
- ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE));
|
|
+ ASSERT(0 == uv_run(loop, UV_RUN_ONCE));
|
|
|
|
- MAKE_VALGRIND_HAPPY();
|
|
+ MAKE_VALGRIND_HAPPY(loop);
|
|
return 0;
|
|
}
|
|
|
|
|
|
TEST_IMPL(timer_is_closing) {
|
|
+ uv_context_t context;
|
|
+ uv_loop_t *loop;
|
|
+ uv_library_init(&context);
|
|
+ loop = uv_default_loop(&context);
|
|
+
|
|
uv_timer_t handle;
|
|
|
|
- ASSERT(0 == uv_timer_init(uv_default_loop(), &handle));
|
|
+ ASSERT(0 == uv_timer_init(loop, &handle));
|
|
uv_close((uv_handle_t *)&handle, NULL);
|
|
|
|
ASSERT(UV_EINVAL == uv_timer_start(&handle, never_cb, 100, 100));
|
|
|
|
- MAKE_VALGRIND_HAPPY();
|
|
+ MAKE_VALGRIND_HAPPY(loop);
|
|
return 0;
|
|
}
|
|
|
|
|
|
TEST_IMPL(timer_null_callback) {
|
|
+ uv_context_t context;
|
|
+ uv_loop_t *loop;
|
|
+ uv_library_init(&context);
|
|
+ loop = uv_default_loop(&context);
|
|
+
|
|
uv_timer_t handle;
|
|
|
|
- ASSERT(0 == uv_timer_init(uv_default_loop(), &handle));
|
|
+ ASSERT(0 == uv_timer_init(loop, &handle));
|
|
ASSERT(UV_EINVAL == uv_timer_start(&handle, NULL, 100, 100));
|
|
|
|
- MAKE_VALGRIND_HAPPY();
|
|
+ MAKE_VALGRIND_HAPPY(loop);
|
|
return 0;
|
|
}
|
|
|
|
|
|
-static uint64_t timer_early_check_expected_time;
|
|
+static uv_time_t timer_early_check_expected_time;
|
|
|
|
|
|
static void timer_early_check_cb(uv_timer_t* handle) {
|
|
@@ -326,18 +385,23 @@ static void timer_early_check_cb(uv_timer_t* handle) {
|
|
|
|
|
|
TEST_IMPL(timer_early_check) {
|
|
+ uv_context_t context;
|
|
+ uv_loop_t *loop;
|
|
+ uv_library_init(&context);
|
|
+ loop = uv_default_loop(&context);
|
|
+
|
|
uv_timer_t timer_handle;
|
|
- const uint64_t timeout_ms = 10;
|
|
+ const uv_interval_t timeout_ms = 10;
|
|
|
|
- timer_early_check_expected_time = uv_now(uv_default_loop()) + timeout_ms;
|
|
+ timer_early_check_expected_time = uv_now(loop) + (uv_time_t)timeout_ms;
|
|
|
|
- ASSERT(0 == uv_timer_init(uv_default_loop(), &timer_handle));
|
|
+ ASSERT(0 == uv_timer_init(loop, &timer_handle));
|
|
ASSERT(0 == uv_timer_start(&timer_handle, timer_early_check_cb, timeout_ms, 0));
|
|
- ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
|
|
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
|
|
|
|
uv_close((uv_handle_t*) &timer_handle, NULL);
|
|
- ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_DEFAULT));
|
|
+ ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
|
|
|
|
- MAKE_VALGRIND_HAPPY();
|
|
+ MAKE_VALGRIND_HAPPY(loop);
|
|
return 0;
|
|
}
|
|
diff --git a/test/test-walk-handles.c b/test/test-walk-handles.c
|
|
index 4b0ca6ebc..3cd1c2f6e 100644
|
|
--- a/test/test-walk-handles.c
|
|
+++ b/test/test-walk-handles.c
|
|
@@ -50,10 +50,12 @@ static void timer_cb(uv_timer_t* handle) {
|
|
|
|
|
|
TEST_IMPL(walk_handles) {
|
|
- uv_loop_t* loop;
|
|
+ uv_context_t context;
|
|
+ uv_loop_t *loop;
|
|
+ uv_library_init(&context);
|
|
int r;
|
|
|
|
- loop = uv_default_loop();
|
|
+ loop = uv_default_loop(&context);
|
|
|
|
r = uv_timer_init(loop, &timer);
|
|
ASSERT(r == 0);
|
|
@@ -72,6 +74,6 @@ TEST_IMPL(walk_handles) {
|
|
uv_walk(loop, walk_cb, magic_cookie);
|
|
ASSERT(seen_timer_handle == 0);
|
|
|
|
- MAKE_VALGRIND_HAPPY();
|
|
+ MAKE_VALGRIND_HAPPY(loop);
|
|
return 0;
|
|
}
|
|
--
|
|
2.17.1
|
|
|