From 9351ab50d56e8f702d54ff92e24b91fbd305baea Mon Sep 17 00:00:00 2001 From: Huang Qi Date: Thu, 1 Apr 2021 19:12:59 +0800 Subject: [PATCH] system/libuv: Bump to v1.42.0 Signed-off-by: Huang Qi --- system/libuv/.gitignore | 3 +- .../0001-initial-libuv-port-to-nuttx.patch | 7788 ----------------- system/libuv/0001-libuv-port-for-nuttx.patch | 1810 ++++ system/libuv/Kconfig | 45 + system/libuv/Make.defs | 17 +- system/libuv/Makefile | 303 +- system/libuv/README.md | 17 + system/libuv/libuv/Kconfig | 129 - system/libuv/libuv/Make.defs | 31 - system/libuv/libuv/Makefile | 124 - system/libuv/tests/Kconfig | 35 - system/libuv/tests/Make.defs | 23 - system/libuv/tests/Makefile | 72 - system/libuv/tests/runner-nuttx.c | 152 - system/libuv/tests/runner-nuttx.h | 46 - system/libuv/tests/test_main.c | 56 - 16 files changed, 2182 insertions(+), 8469 deletions(-) delete mode 100644 system/libuv/0001-initial-libuv-port-to-nuttx.patch create mode 100644 system/libuv/0001-libuv-port-for-nuttx.patch create mode 100644 system/libuv/Kconfig create mode 100644 system/libuv/README.md delete mode 100644 system/libuv/libuv/Kconfig delete mode 100644 system/libuv/libuv/Make.defs delete mode 100644 system/libuv/libuv/Makefile delete mode 100644 system/libuv/tests/Kconfig delete mode 100644 system/libuv/tests/Make.defs delete mode 100644 system/libuv/tests/Makefile delete mode 100644 system/libuv/tests/runner-nuttx.c delete mode 100644 system/libuv/tests/runner-nuttx.h delete mode 100644 system/libuv/tests/test_main.c diff --git a/system/libuv/.gitignore b/system/libuv/.gitignore index 253cc0149..95c8049c9 100644 --- a/system/libuv/.gitignore +++ b/system/libuv/.gitignore @@ -1,3 +1,2 @@ -/Kconfig -libuv-* +libuv* *.zip diff --git a/system/libuv/0001-initial-libuv-port-to-nuttx.patch b/system/libuv/0001-initial-libuv-port-to-nuttx.patch deleted file mode 100644 index 8f2276410..000000000 --- a/system/libuv/0001-initial-libuv-port-to-nuttx.patch +++ /dev/null @@ -1,7788 +0,0 @@ -From 3307fabda302b693acbec3a9f11b6542428d5b96 Mon Sep 17 00:00:00 2001 -From: Simon Piriou -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 -+#include -+ -+#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 - #include /* sched_yield() */ - --#ifdef __linux__ -+#if defined (__linux__) || defined(__NUTTX__) - #include - #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 - # include /* _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 - # 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 -+# include -+ -+#else /* __NUTTX__ */ -+ - #if defined(__linux__) || defined(__sun) - # include - #endif -@@ -84,6 +90,7 @@ - #else - # include - #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 - #include - -+#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 -+#include -+#include -+ -+#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 -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include /* 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 -+#include -+#include -+#include -+ -+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 -+ -+#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 -+#include -+ -+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 - #include - -+#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 - --#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 - -+#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 - diff --git a/system/libuv/0001-libuv-port-for-nuttx.patch b/system/libuv/0001-libuv-port-for-nuttx.patch new file mode 100644 index 000000000..4f6982720 --- /dev/null +++ b/system/libuv/0001-libuv-port-for-nuttx.patch @@ -0,0 +1,1810 @@ +diff --git a/include/uv.h b/include/uv.h +index 77503bde..17940e3d 100644 +--- a/include/uv.h ++++ b/include/uv.h +@@ -797,6 +797,16 @@ UV_EXTERN void uv_pipe_connect(uv_connect_t* req, + uv_pipe_t* handle, + const char* name, + uv_connect_cb cb); ++#ifdef CONFIG_NET_RPMSG ++UV_EXTERN int uv_pipe_rpmsg_bind(uv_pipe_t* handle, ++ const char* name, ++ const char* cpu_name); ++UV_EXTERN void uv_pipe_rpmsg_connect(uv_connect_t* req, ++ uv_pipe_t* handle, ++ const char* name, ++ const char* cpu_name, ++ uv_connect_cb cb); ++#endif + UV_EXTERN int uv_pipe_getsockname(const uv_pipe_t* handle, + char* buffer, + size_t* size); +diff --git a/include/uv/unix.h b/include/uv/unix.h +index e3cf7bdd..bf8dc32c 100644 +--- a/include/uv/unix.h ++++ b/include/uv/unix.h +@@ -71,6 +71,8 @@ + # include "uv/posix.h" + #elif defined(__QNX__) + # include "uv/posix.h" ++#elif defined(__NuttX__) ++# include "uv/posix.h" + #endif + + #ifndef NI_MAXHOST +diff --git a/src/fs-poll.c b/src/fs-poll.c +index 89864e23..ceb047cb 100644 +--- a/src/fs-poll.c ++++ b/src/fs-poll.c +@@ -53,7 +53,7 @@ static void poll_cb(uv_fs_t* req); + static void timer_cb(uv_timer_t* timer); + static void timer_close_cb(uv_handle_t* handle); + +-static uv_stat_t zero_statbuf; ++static const uv_stat_t zero_statbuf; + + + int uv_fs_poll_init(uv_loop_t* loop, uv_fs_poll_t* handle) { +diff --git a/src/random.c b/src/random.c +index e75f77de..feef5a44 100644 +--- a/src/random.c ++++ b/src/random.c +@@ -31,7 +31,7 @@ + static int uv__random(void* buf, size_t buflen) { + int rc; + +-#if defined(__PASE__) ++#if defined(__PASE__) || defined(__NuttX__) + rc = uv__random_readpath("/dev/urandom", buf, buflen); + #elif defined(_AIX) || defined(__QNX__) + rc = uv__random_readpath("/dev/random", buf, buflen); +diff --git a/src/threadpool.c b/src/threadpool.c +index 869ae95f..8fabeba5 100644 +--- a/src/threadpool.c ++++ b/src/threadpool.c +@@ -20,6 +20,7 @@ + */ + + #include "uv-common.h" ++#include "uv-global.h" + + #if !defined(_WIN32) + # include "unix/internal.h" +@@ -27,20 +28,11 @@ + + #include + +-#define MAX_THREADPOOL_SIZE 1024 ++#ifndef DEF_THREADPOOL_SIZE ++# define DEF_THREADPOOL_SIZE 4 ++#endif + +-static uv_once_t once = UV_ONCE_INIT; +-static uv_cond_t cond; +-static uv_mutex_t mutex; +-static unsigned int idle_threads; +-static unsigned int slow_io_work_running; +-static unsigned int nthreads; +-static uv_thread_t* threads; +-static uv_thread_t default_threads[4]; +-static QUEUE exit_message; +-static QUEUE wq; +-static QUEUE run_slow_work_message; +-static QUEUE slow_io_pending_wq; ++#define MAX_THREADPOOL_SIZE 1024 + + static unsigned int slow_work_thread_threshold(void) { + return (nthreads + 1) / 2; +@@ -68,16 +60,16 @@ static void worker(void* arg) { + + /* Keep waiting while either no work is present or only slow I/O + and we're at the threshold for that. */ +- while (QUEUE_EMPTY(&wq) || +- (QUEUE_HEAD(&wq) == &run_slow_work_message && +- QUEUE_NEXT(&run_slow_work_message) == &wq && ++ while (QUEUE_EMPTY(&lwq) || ++ (QUEUE_HEAD(&lwq) == &run_slow_work_message && ++ QUEUE_NEXT(&run_slow_work_message) == &lwq && + slow_io_work_running >= slow_work_thread_threshold())) { + idle_threads += 1; + uv_cond_wait(&cond, &mutex); + idle_threads -= 1; + } + +- q = QUEUE_HEAD(&wq); ++ q = QUEUE_HEAD(&lwq); + if (q == &exit_message) { + uv_cond_signal(&cond); + uv_mutex_unlock(&mutex); +@@ -92,7 +84,7 @@ static void worker(void* arg) { + /* If we're at the slow I/O threshold, re-schedule until after all + other work in the queue is done. */ + if (slow_io_work_running >= slow_work_thread_threshold()) { +- QUEUE_INSERT_TAIL(&wq, q); ++ QUEUE_INSERT_TAIL(&lwq, q); + continue; + } + +@@ -110,7 +102,7 @@ static void worker(void* arg) { + + /* If there is more slow I/O work, schedule it to be run as well. */ + if (!QUEUE_EMPTY(&slow_io_pending_wq)) { +- QUEUE_INSERT_TAIL(&wq, &run_slow_work_message); ++ QUEUE_INSERT_TAIL(&lwq, &run_slow_work_message); + if (idle_threads > 0) + uv_cond_signal(&cond); + } +@@ -153,13 +145,21 @@ static void post(QUEUE* q, enum uv__work_kind kind) { + q = &run_slow_work_message; + } + +- QUEUE_INSERT_TAIL(&wq, q); ++ QUEUE_INSERT_TAIL(&lwq, q); + if (idle_threads > 0) + uv_cond_signal(&cond); + uv_mutex_unlock(&mutex); + } + + ++#ifndef _WIN32 ++static void reset_once(void) { ++ uv_once_t child_once = UV_ONCE_INIT; ++ memcpy(&once, &child_once, sizeof(child_once)); ++} ++#endif ++ ++ + void uv__threadpool_cleanup(void) { + unsigned int i; + +@@ -180,6 +180,11 @@ void uv__threadpool_cleanup(void) { + + threads = NULL; + nthreads = 0; ++ ++#ifndef _WIN32 ++ reset_once(); ++#endif ++ + } + + +@@ -212,7 +217,7 @@ static void init_threads(void) { + if (uv_mutex_init(&mutex)) + abort(); + +- QUEUE_INIT(&wq); ++ QUEUE_INIT(&lwq); + QUEUE_INIT(&slow_io_pending_wq); + QUEUE_INIT(&run_slow_work_message); + +@@ -230,14 +235,6 @@ static void init_threads(void) { + } + + +-#ifndef _WIN32 +-static void reset_once(void) { +- uv_once_t child_once = UV_ONCE_INIT; +- memcpy(&once, &child_once, sizeof(child_once)); +-} +-#endif +- +- + static void init_once(void) { + #ifndef _WIN32 + /* Re-initialize the threadpool after fork. +diff --git a/src/unix/core.c b/src/unix/core.c +index 71e9c525..6859fe71 100644 +--- a/src/unix/core.c ++++ b/src/unix/core.c +@@ -58,8 +58,6 @@ + # include + # include /* _NSGetExecutablePath */ + # define environ (*_NSGetEnviron()) +-#else /* defined(__APPLE__) && !TARGET_OS_IPHONE */ +-extern char** environ; + #endif /* !(defined(__APPLE__) && !TARGET_OS_IPHONE) */ + + +@@ -987,7 +985,7 @@ int uv_getrusage(uv_rusage_t* rusage) { + rusage->ru_stime.tv_sec = usage.ru_stime.tv_sec; + rusage->ru_stime.tv_usec = usage.ru_stime.tv_usec; + +-#if !defined(__MVS__) && !defined(__HAIKU__) ++#if !defined(__MVS__) && !defined(__HAIKU__) && !defined(__NuttX__) + rusage->ru_maxrss = usage.ru_maxrss; + rusage->ru_ixrss = usage.ru_ixrss; + rusage->ru_idrss = usage.ru_idrss; +diff --git a/src/unix/loop.c b/src/unix/loop.c +index a88e71c3..dad463b3 100644 +--- a/src/unix/loop.c ++++ b/src/unix/loop.c +@@ -220,8 +220,10 @@ int uv__loop_configure(uv_loop_t* loop, uv_loop_option option, va_list ap) { + if (option != UV_LOOP_BLOCK_SIGNAL) + return UV_ENOSYS; + ++#ifdef SIGPROF + if (va_arg(ap, int) != SIGPROF) + return UV_EINVAL; ++#endif + + loop->flags |= UV_LOOP_BLOCK_SIGPROF; + return 0; +diff --git a/src/unix/nuttx.c b/src/unix/nuttx.c +new file mode 100644 +index 00000000..dfc2cc47 +--- /dev/null ++++ b/src/unix/nuttx.c +@@ -0,0 +1,282 @@ ++/* Copyright Xiaomi, 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. ++ */ ++ ++/* We lean on the fact that POLL{IN,OUT,ERR,HUP} correspond with their ++ * EPOLL* counterparts. We use the POLL* variants in this file because that ++ * is what libuv uses elsewhere. ++ */ ++ ++#include "internal.h" ++#include "uv.h" ++#include "uv-global.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++int uv_exepath(char* buffer, size_t* size) { ++ return UV_ENOTSUP; ++} ++ ++char** uv_setup_args(int argc, char** argv) { ++ return argv; ++} ++ ++void uv__process_title_cleanup(void) { ++} ++ ++int uv_set_process_title(const char* title) { ++ return UV__ERR(pthread_setname_np(pthread_self(), title)); ++} ++ ++int uv_get_process_title(char* buffer, size_t size) { ++ return UV__ERR(pthread_getname_np(pthread_self(), buffer, size)); ++} ++ ++uint64_t uv_get_constrained_memory(void) { ++ return 0; /* Memory constraints are unknown. */ ++} ++ ++int uv_resident_set_memory(size_t* rss) { ++ struct sysinfo info; ++ int ret; ++ ++ ret = sysinfo(&info); ++ if (ret >= 0) ++ { ++ *rss = (info.totalram - info.freeram) * info.mem_unit; ++ } ++ else ++ { ++ ret = UV__ERR(errno); ++ } ++ ++ return ret; ++} ++ ++int uv_uptime(double* uptime) { ++ struct sysinfo info; ++ int ret; ++ ++ ++ ret = sysinfo(&info); ++ if (ret >= 0) ++ { ++ *uptime = info.uptime; ++ } ++ else ++ { ++ ret = UV__ERR(errno); ++ } ++ ++ return ret; ++} ++ ++int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) { ++ *count = sysconf(_SC_NPROCESSORS_ONLN); ++ *cpu_infos = uv__calloc(*count, sizeof(uv_cpu_info_t)); ++ if (!*cpu_infos) { ++ return UV_ENOMEM; ++ } ++ ++ return 0; ++} ++ ++#ifndef CONFIG_NETDEV_IFINDEX ++unsigned int if_nametoindex(const char *ifname) { ++ return 0; ++} ++ ++int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { ++ return UV_ENOSYS; ++} ++ ++void uv_free_interface_addresses(uv_interface_address_t* addresses, int count) { ++} ++#else ++static int uv__ifaddr_exclude(struct ifaddrs *ent) { ++ if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING))) ++ return 1; ++ if (ent->ifa_addr == NULL) ++ return 1; ++ return 0; ++} ++ ++int uv_interface_addresses(uv_interface_address_t** addresses, int* count) { ++ struct ifaddrs* addrs; ++ struct ifaddrs* ent; ++ uv_interface_address_t* address; ++ ++ *count = 0; ++ *addresses = NULL; ++ ++ if (getifaddrs(&addrs) != 0) ++ return UV__ERR(errno); ++ ++ /* Count the number of interfaces */ ++ for (ent = addrs; ent != NULL; ent = ent->ifa_next) { ++ if (uv__ifaddr_exclude(ent)) ++ continue; ++ (*count)++; ++ } ++ ++ if (*count == 0) { ++ freeifaddrs(addrs); ++ return 0; ++ } ++ ++ /* Make sure the memory is initiallized to zero using calloc() */ ++ *addresses = uv__calloc(*count, sizeof(**addresses)); ++ if (*addresses == NULL) { ++ freeifaddrs(addrs); ++ return UV_ENOMEM; ++ } ++ ++ address = *addresses; ++ for (ent = addrs; ent != NULL; ent = ent->ifa_next) { ++ if (uv__ifaddr_exclude(ent)) ++ continue; ++ ++ address->name = uv__strdup(ent->ifa_name); ++ ++ if (ent->ifa_addr->sa_family == AF_INET6) { ++ address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr); ++ } else { ++ address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr); ++ } ++ ++ if (ent->ifa_netmask) { ++ if (ent->ifa_netmask->sa_family == AF_INET6) { ++ address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask); ++ } else { ++ address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask); ++ } ++ } ++ ++ if (ent->ifa_data) { ++ struct sockaddr* addr = ent->ifa_data; ++ memcpy(address->phys_addr, addr->sa_data, sizeof(address->phys_addr)); ++ } ++ ++ address->is_internal = !strcmp(address->name, "lo"); ++ address++; ++ } ++ ++ freeifaddrs(addrs); ++ return 0; ++} ++ ++void uv_free_interface_addresses(uv_interface_address_t* addresses, int count) { ++ int i; ++ ++ for (i = 0; i < count; i++) { ++ uv__free(addresses[i].name); ++ } ++ ++ uv__free(addresses); ++} ++#endif ++ ++#ifndef CONFIG_NET ++int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen) { ++ return UV_ENOTSUP; ++} ++ ++int getsockopt(int sockfd, int level, int option, void *value, socklen_t *value_len) { ++ return UV_ENOTSUP; ++} ++ ++ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags) { ++ return UV_ENOTSUP; ++} ++ ++ssize_t sendmsg(int sockfd, struct msghdr *msg, int flags) { ++ return UV_ENOTSUP; ++} ++ ++int shutdown(int sockfd, int how) { ++ return UV_ENOTSUP; ++} ++#endif ++ ++#ifndef CONFIG_NET_TCP ++void uv__tcp_close(uv_tcp_t* handle) { ++} ++ ++int uv__tcp_nodelay(int fd, int on) { ++ return UV_ENOTSUP; ++} ++ ++int uv__tcp_keepalive(int fd, int on, unsigned int delay) { ++ return UV_ENOTSUP; ++} ++#endif ++ ++#ifndef CONFIG_NET_UDP ++void uv__udp_close(uv_udp_t* handle) { ++} ++ ++void uv__udp_finish_close(uv_udp_t* handle) { ++} ++#endif ++ ++#if CONFIG_TLS_TASK_NELEM == 0 ++# error "libuv depends on CONFIG_TLS_TASK_NELEM, please enable it by menuconfig" ++#endif ++ ++#undef once ++#undef uv__signal_global_init_guard ++#undef uv__signal_lock_pipefd ++ ++static void uv__global_free(void* global) { ++ if (global) { ++ uv_library_shutdown(); ++ uv__free(global); ++ } ++} ++ ++uv__global_t* uv__global_get(void) { ++ static int index = -1; ++ uv__global_t* global = NULL; ++ ++ if (index < 0) { ++ index = task_tls_alloc(uv__global_free); ++ } ++ ++ if (index >= 0) { ++ global = (uv__global_t*)task_tls_get_value(index); ++ if (global == NULL) { ++ global = (uv__global_t*)uv__calloc(1, sizeof(uv__global_t)); ++ if (global) { ++ global->once = UV_ONCE_INIT; ++ global->uv__signal_global_init_guard = UV_ONCE_INIT; ++ global->uv__signal_lock_pipefd[0] = -1; ++ global->uv__signal_lock_pipefd[1] = -1; ++ task_tls_set_value(index, (uintptr_t)global); ++ } ++ } ++ } ++ ++ ASSERT(global != NULL); ++ return global; ++} +diff --git a/src/unix/pipe.c b/src/unix/pipe.c +index 788e038e..9104cb92 100644 +--- a/src/unix/pipe.c ++++ b/src/unix/pipe.c +@@ -28,7 +28,9 @@ + #include + #include + #include +- ++#ifdef CONFIG_NET_RPMSG ++#include ++#endif // CONFIG_NET_RPMSG + + int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) { + uv__stream_init(loop, (uv_stream_t*)handle, UV_NAMED_PIPE); +@@ -90,6 +92,48 @@ err_socket: + return err; + } + ++#ifdef CONFIG_NET_RPMSG ++int uv_pipe_rpmsg_bind(uv_pipe_t* handle, ++ const char* name, ++ const char* cpu_name) { ++ struct sockaddr_rpmsg saddr; ++ int sockfd; ++ int err; ++ ++ /* Already bound? */ ++ if (uv__stream_fd(handle) >= 0) ++ return UV_EINVAL; ++ ++ err = uv__socket(AF_RPMSG, SOCK_STREAM, 0); ++ if (err < 0) ++ goto err_socket; ++ sockfd = err; ++ ++ memset(&saddr, 0, sizeof saddr); ++ uv__strscpy(saddr.rp_name, name, sizeof(saddr.rp_name)); ++ uv__strscpy(saddr.rp_cpu, cpu_name, sizeof(saddr.rp_cpu)); ++ saddr.rp_family = AF_RPMSG; ++ ++ if (bind(sockfd, (struct sockaddr*)&saddr, sizeof saddr)) { ++ err = UV__ERR(errno); ++ /* Convert ENOENT to EACCES for compatibility with Windows. */ ++ if (err == UV_ENOENT) ++ err = UV_EACCES; ++ ++ uv__close(sockfd); ++ goto err_socket; ++ } ++ ++ /* Success. */ ++ handle->flags |= UV_HANDLE_BOUND; ++ handle->pipe_fname = NULL; ++ handle->io_watcher.fd = sockfd; ++ return 0; ++ ++err_socket: ++ return err; ++} ++#endif + + int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) { + if (uv__stream_fd(handle) == -1) +@@ -169,32 +213,18 @@ int uv_pipe_open(uv_pipe_t* handle, uv_file fd) { + return uv__stream_open((uv_stream_t*)handle, fd, flags); + } + +- +-void uv_pipe_connect(uv_connect_t* req, +- uv_pipe_t* handle, +- const char* name, +- uv_connect_cb cb) { +- struct sockaddr_un saddr; +- int new_sock; ++static inline int uv__connect(uv_connect_t* req, ++ uv_pipe_t* handle, ++ struct sockaddr* saddr, ++ socklen_t addrlen, ++ int new_sock, ++ uv_connect_cb cb) ++{ + int err; + int r; + +- new_sock = (uv__stream_fd(handle) == -1); +- +- if (new_sock) { +- err = uv__socket(AF_UNIX, SOCK_STREAM, 0); +- if (err < 0) +- goto out; +- handle->io_watcher.fd = err; +- } +- +- memset(&saddr, 0, sizeof saddr); +- uv__strscpy(saddr.sun_path, name, sizeof(saddr.sun_path)); +- saddr.sun_family = AF_UNIX; +- + do { +- r = connect(uv__stream_fd(handle), +- (struct sockaddr*)&saddr, sizeof saddr); ++ r = connect(uv__stream_fd(handle), saddr, addrlen); + } + while (r == -1 && errno == EINTR); + +@@ -222,6 +252,14 @@ void uv_pipe_connect(uv_connect_t* req, + uv__io_start(handle->loop, &handle->io_watcher, POLLOUT); + + out: ++ return err; ++} ++ ++static inline void uv__connect_handle_err(uv_connect_t* req, ++ uv_pipe_t* handle, ++ int err, ++ uv_connect_cb cb) ++{ + handle->delayed_error = err; + handle->connect_req = req; + +@@ -233,9 +271,66 @@ out: + /* Force callback to run on next tick in case of error. */ + if (err) + uv__io_feed(handle->loop, &handle->io_watcher); ++} ++ ++void uv_pipe_connect(uv_connect_t* req, ++ uv_pipe_t* handle, ++ const char* name, ++ uv_connect_cb cb) { ++ struct sockaddr_un saddr; ++ int new_sock; ++ int err; ++ ++ new_sock = (uv__stream_fd(handle) == -1); ++ ++ if (new_sock) { ++ err = uv__socket(AF_UNIX, SOCK_STREAM, 0); ++ if (err < 0) ++ goto out; ++ handle->io_watcher.fd = err; ++ } ++ ++ memset(&saddr, 0, sizeof saddr); ++ uv__strscpy(saddr.sun_path, name, sizeof(saddr.sun_path)); ++ saddr.sun_family = AF_UNIX; ++ ++ err = uv__connect(req, handle, (struct sockaddr*)&saddr, sizeof saddr, ++ new_sock, cb); + ++out: ++ uv__connect_handle_err(req, handle, err, cb); + } + ++#ifdef CONFIG_NET_RPMSG ++void uv_pipe_rpmsg_connect(uv_connect_t* req, ++ uv_pipe_t* handle, ++ const char* name, ++ const char* cpu_name, ++ uv_connect_cb cb) { ++ struct sockaddr_rpmsg saddr; ++ int new_sock; ++ int err; ++ ++ new_sock = (uv__stream_fd(handle) == -1); ++ ++ if (new_sock) { ++ err = uv__socket(AF_RPMSG, SOCK_STREAM, 0); ++ if (err < 0) ++ goto out; ++ handle->io_watcher.fd = err; ++ } ++ ++ memset(&saddr, 0, sizeof saddr); ++ uv__strscpy(saddr.rp_name, name, sizeof(saddr.rp_name)); ++ uv__strscpy(saddr.rp_cpu, cpu_name, sizeof(saddr.rp_cpu)); ++ saddr.rp_family = AF_RPMSG; ++ err = uv__connect(req, handle, (struct sockaddr*)&saddr, sizeof saddr, ++ new_sock, cb); ++ ++out: ++ uv__connect_handle_err(req, handle, err, cb); ++} ++#endif // CONFIG_NET_RPMSG + + static int uv__pipe_getsockpeername(const uv_pipe_t* handle, + uv__peersockfunc func, +diff --git a/src/unix/posix-poll.c b/src/unix/posix-poll.c +index 0f4bf938..dd36028b 100644 +--- a/src/unix/posix-poll.c ++++ b/src/unix/posix-poll.c +@@ -144,7 +144,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { + int have_signals; + struct pollfd* pe; + int fd; +- int user_timeout; ++ int user_timeout = 0; + int reset_timeout; + + if (loop->nfds == 0) { +@@ -170,11 +170,15 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { + + /* Prepare a set of signals to block around poll(), if any. */ + pset = NULL; ++#ifdef SIGPROF + if (loop->flags & UV_LOOP_BLOCK_SIGPROF) { + pset = &set; + sigemptyset(pset); + sigaddset(pset, SIGPROF); + } ++#else ++ (void) set; ++#endif + + assert(timeout >= -1); + time_base = loop->time; +diff --git a/src/unix/process.c b/src/unix/process.c +index f4aebb04..00409cbc 100644 +--- a/src/unix/process.c ++++ b/src/unix/process.c +@@ -36,8 +36,6 @@ + #if defined(__APPLE__) && !TARGET_OS_IPHONE + # include + # define environ (*_NSGetEnviron()) +-#else +-extern char **environ; + #endif + + #if defined(__linux__) || defined(__GLIBC__) +@@ -48,7 +46,7 @@ extern char **environ; + # include "zos-base.h" + #endif + +- ++#if !(defined(__APPLE__) && (TARGET_OS_TV || TARGET_OS_WATCH)) && !defined(__NuttX__) + static void uv__chld(uv_signal_t* handle, int signum) { + uv_process_t* process; + uv_loop_t* loop; +@@ -207,7 +205,6 @@ static void uv__write_errno(int error_fd) { + } + + +-#if !(defined(__APPLE__) && (TARGET_OS_TV || TARGET_OS_WATCH)) + /* 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. +@@ -345,7 +342,7 @@ static void uv__process_child_init(const uv_process_options_t* options, + int uv_spawn(uv_loop_t* loop, + uv_process_t* process, + const uv_process_options_t* options) { +-#if defined(__APPLE__) && (TARGET_OS_TV || TARGET_OS_WATCH) ++#if (defined(__APPLE__) && (TARGET_OS_TV || TARGET_OS_WATCH)) || defined(__NuttX__) + /* fork is marked __WATCHOS_PROHIBITED __TVOS_PROHIBITED. */ + return UV_ENOSYS; + #else +diff --git a/src/unix/signal.c b/src/unix/signal.c +index 1133c73a..1827832b 100644 +--- a/src/unix/signal.c ++++ b/src/unix/signal.c +@@ -20,6 +20,7 @@ + + #include "uv.h" + #include "internal.h" ++#include "uv-global.h" + + #include + #include +@@ -32,14 +33,6 @@ + # define SA_RESTART 0 + #endif + +-typedef struct { +- uv_signal_t* handle; +- int signum; +-} uv__signal_msg_t; +- +-RB_HEAD(uv__signal_tree_s, uv_signal_s); +- +- + static int uv__signal_unlock(void); + static int uv__signal_start(uv_signal_t* handle, + uv_signal_cb signal_cb, +@@ -50,12 +43,6 @@ static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2); + static void uv__signal_stop(uv_signal_t* handle); + static void uv__signal_unregister_handler(int signum); + +- +-static uv_once_t uv__signal_global_init_guard = UV_ONCE_INIT; +-static struct uv__signal_tree_s uv__signal_tree = +- RB_INITIALIZER(uv__signal_tree); +-static int uv__signal_lock_pipefd[2] = { -1, -1 }; +- + RB_GENERATE_STATIC(uv__signal_tree_s, + uv_signal_s, tree_entry, + uv__signal_compare) +diff --git a/src/unix/thread.c b/src/unix/thread.c +old mode 100644 +new mode 100755 +diff --git a/src/unix/tty.c b/src/unix/tty.c +index 9442cf16..bb7170bc 100644 +--- a/src/unix/tty.c ++++ b/src/unix/tty.c +@@ -66,6 +66,7 @@ static int orig_termios_fd = -1; + static struct termios orig_termios; + static uv_spinlock_t termios_spinlock = UV_SPINLOCK_INITIALIZER; + ++#ifndef __NuttX__ + static int uv__tty_is_slave(const int fd) { + int result; + #if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) +@@ -119,15 +120,13 @@ static int uv__tty_is_slave(const int fd) { + #endif + return result; + } ++#endif + + int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int unused) { + uv_handle_type type; + int flags; +- int newfd; +- int r; + int saved_flags; + int mode; +- char path[256]; + (void)unused; /* deprecated parameter is no longer needed */ + + /* File descriptors that refer to files cannot be monitored with epoll. +@@ -139,7 +138,6 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int unused) { + return UV_EINVAL; + + flags = 0; +- newfd = -1; + + /* Save the fd flags in case we need to restore them due to an error. */ + do +@@ -150,6 +148,7 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int unused) { + return UV__ERR(errno); + mode = saved_flags & O_ACCMODE; + ++#ifndef __NuttX__ + /* Reopen the file descriptor when it refers to a tty. This lets us put the + * tty in non-blocking mode without affecting other processes that share it + * with us. +@@ -161,6 +160,10 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int unused) { + * other processes. + */ + if (type == UV_TTY) { ++ int newfd; ++ int r; ++ char path[256]; ++ + /* Reopening a pty in master mode won't work either because the reopened + * pty will be in slave mode (*BSD) or reopening will allocate a new + * master/slave pair (Linux). Therefore check if the fd points to a +@@ -194,6 +197,7 @@ int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, int fd, int unused) { + } + + skip: ++#endif + uv__stream_init(loop, (uv_stream_t*) tty, UV_TTY); + + /* If anything fails beyond this point we need to remove the handle from +diff --git a/src/unix/udp.c b/src/unix/udp.c +index 49051c07..dbd8a2c7 100644 +--- a/src/unix/udp.c ++++ b/src/unix/udp.c +@@ -932,6 +932,7 @@ static int uv__udp_set_source_membership6(uv_udp_t* handle, + const char* interface_addr, + const struct sockaddr_in6* source_addr, + uv_membership membership) { ++#ifndef __NuttX__ + struct group_source_req mreq; + struct sockaddr_in6 addr6; + int optname; +@@ -973,6 +974,9 @@ static int uv__udp_set_source_membership6(uv_udp_t* handle, + } + + return 0; ++#else ++ return UV_ENOSYS; ++#endif + } + #endif + +diff --git a/src/uv-common.c b/src/uv-common.c +index e81ed79b..d105db1f 100644 +--- a/src/uv-common.c ++++ b/src/uv-common.c +@@ -21,6 +21,7 @@ + + #include "uv.h" + #include "uv-common.h" ++#include "uv-global.h" + + #include + #include +@@ -756,10 +757,6 @@ int uv_loop_configure(uv_loop_t* loop, uv_loop_option option, ...) { + } + + +-static uv_loop_t default_loop_struct; +-static uv_loop_t* default_loop_ptr; +- +- + uv_loop_t* uv_default_loop(void) { + if (default_loop_ptr != NULL) + return default_loop_ptr; +@@ -880,8 +877,6 @@ void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { + __attribute__((destructor)) + #endif + void uv_library_shutdown(void) { +- static int was_shutdown; +- + if (uv__load_relaxed(&was_shutdown)) + return; + +@@ -949,3 +944,22 @@ uint64_t uv_metrics_idle_time(uv_loop_t* loop) { + idle_time += uv_hrtime() - entry_time; + return idle_time; + } ++ ++/* Add uv_global_get here since all system need it but NuttX */ ++ ++#ifndef __NuttX__ ++#undef once ++#undef uv__signal_global_init_guard ++#undef uv__signal_lock_pipefd ++ ++uv__global_t* uv__global_get(void) ++{ ++ static uv__global_t g_uv_common_global = { ++ .once = UV_ONCE_INIT, ++ .uv__signal_global_init_guard = UV_ONCE_INIT, ++ .uv__signal_lock_pipefd = {-1, -1}, ++ }; ++ ++ return &g_uv_common_global; ++} ++#endif +diff --git a/src/uv-global.h b/src/uv-global.h +new file mode 100644 +index 00000000..458fe8ef +--- /dev/null ++++ b/src/uv-global.h +@@ -0,0 +1,92 @@ ++/* 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. ++ */ ++ ++#ifndef UV_GLOBAL_H ++#define UV_GLOBAL_H ++ ++#include "uv.h" ++ ++#if !defined(_WIN32) ++typedef struct { ++ uv_signal_t* handle; ++ int signum; ++} uv__signal_msg_t; ++ ++RB_HEAD(uv__signal_tree_s, uv_signal_s); ++#endif ++ ++typedef struct { ++ /* Member in threadpool.c */ ++ uv_once_t once; ++ uv_cond_t cond; ++ uv_mutex_t mutex; ++ unsigned int idle_threads; ++ unsigned int slow_io_work_running; ++ unsigned int nthreads; ++ uv_thread_t* threads; ++ uv_thread_t default_threads[4]; ++ QUEUE exit_message; ++ QUEUE wq; ++ QUEUE run_slow_work_message; ++ QUEUE slow_io_pending_wq; ++ /* Member in uv-common.c */ ++ int was_shutdown; ++ uv_loop_t default_loop_struct; ++ uv_loop_t* default_loop_ptr; ++#if !defined(_WIN32) ++ /* Member in signal.c */ ++ uv_once_t uv__signal_global_init_guard; ++ struct uv__signal_tree_s uv__signal_tree; ++ int uv__signal_lock_pipefd[2]; ++#endif ++} uv__global_t; ++ ++uv__global_t* uv__global_get(void); ++ ++/* Used in threadpool.c */ ++ ++#define once uv__global_get()->once ++#define cond uv__global_get()->cond ++#define mutex uv__global_get()->mutex ++#define idle_threads uv__global_get()->idle_threads ++#define slow_io_work_running uv__global_get()->slow_io_work_running ++#define nthreads uv__global_get()->nthreads ++#define threads uv__global_get()->threads ++#define default_threads uv__global_get()->default_threads ++#define exit_message uv__global_get()->exit_message ++#define lwq uv__global_get()->wq ++#define run_slow_work_message uv__global_get()->run_slow_work_message ++#define slow_io_pending_wq uv__global_get()->slow_io_pending_wq ++ ++/* Used in uv-common.c */ ++ ++#define was_shutdown uv__global_get()->was_shutdown ++#define default_loop_struct uv__global_get()->default_loop_struct ++#define default_loop_ptr uv__global_get()->default_loop_ptr ++ ++#if !defined(_WIN32) ++/* Used in signal.c */ ++ ++#define uv__signal_global_init_guard uv__global_get()->uv__signal_global_init_guard ++#define uv__signal_tree uv__global_get()->uv__signal_tree ++#define uv__signal_lock_pipefd uv__global_get()->uv__signal_lock_pipefd ++#endif ++ ++#endif +diff --git a/test/run-tests.c b/test/run-tests.c +index 5e53aaa8..cc7c1e81 100644 +--- a/test/run-tests.c ++++ b/test/run-tests.c +@@ -66,7 +66,7 @@ typedef BOOL (WINAPI *sCompareObjectHandles)(_In_ HANDLE, _In_ HANDLE); + + + int main(int argc, char **argv) { +-#ifndef _WIN32 ++#if !defined(_WIN32) && !defined(__NuttX__) + if (0 == geteuid() && NULL == getenv("UV_RUN_AS_ROOT")) { + fprintf(stderr, "The libuv test suite cannot be run as root.\n"); + return EXIT_FAILURE; +diff --git a/test/runner-unix.c b/test/runner-unix.c +index a13648bc..c0b33b41 100644 +--- a/test/runner-unix.c ++++ b/test/runner-unix.c +@@ -39,8 +39,7 @@ + #include + #include + #include +- +-extern char** environ; ++#include + + static void closefd(int fd) { + if (close(fd) == 0 || errno == EINTR || errno == EINPROGRESS) +@@ -79,6 +78,7 @@ 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. */ + int process_start(char* name, char* part, process_info_t* p, int is_helper) { ++ posix_spawn_file_actions_t file_actions; + FILE* stdout_file; + int stdout_fd; + const char* arg; +@@ -115,12 +115,17 @@ int process_start(char* name, char* part, process_info_t* p, int is_helper) { + return -1; + } + ++ posix_spawn_file_actions_init(&file_actions); ++ posix_spawn_file_actions_adddup2(&file_actions, stdout_fd, STDOUT_FILENO); ++ posix_spawn_file_actions_adddup2(&file_actions, stdout_fd, STDERR_FILENO); ++ + if (is_helper) { + if (pipe(pipefd)) { + perror("pipe"); + return -1; + } + ++ posix_spawn_file_actions_addclose(&file_actions, pipefd[0]); + snprintf(fdstr, sizeof(fdstr), "%d", pipefd[1]); + if (setenv("UV_TEST_RUNNER_FD", fdstr, /* overwrite */ 1)) { + perror("setenv"); +@@ -131,25 +136,13 @@ int process_start(char* name, char* part, process_info_t* p, int is_helper) { + p->terminated = 0; + p->status = 0; + +- pid = fork(); +- +- if (pid < 0) { +- perror("fork"); ++ n = posix_spawn(&pid, args[0], &file_actions, NULL, args, environ); ++ posix_spawn_file_actions_destroy(&file_actions); ++ if (n != 0) { ++ fprintf(stderr, "posix_spawn: %s\n", strerror(n)); + return -1; + } + +- if (pid == 0) { +- /* child */ +- if (is_helper) +- closefd(pipefd[0]); +- dup2(stdout_fd, STDOUT_FILENO); +- dup2(stdout_fd, STDERR_FILENO); +- execve(args[0], args, environ); +- perror("execve()"); +- _exit(127); +- } +- +- /* parent */ + p->pid = pid; + p->name = strdup(name); + p->stdout_file = stdout_file; +diff --git a/test/task.h b/test/task.h +index a02c8931..997e55b2 100644 +--- a/test/task.h ++++ b/test/task.h +@@ -100,6 +100,7 @@ typedef enum { + /* Have our own assert, so we are sure it does not get optimized away in + * a release build. + */ ++#undef ASSERT + #define ASSERT(expr) \ + do { \ + if (!(expr)) { \ +@@ -313,6 +314,7 @@ enum test_status { + extern int snprintf(char*, size_t, const char*, ...); + #endif + ++#undef UNUSED + #if defined(__clang__) || \ + defined(__GNUC__) || \ + defined(__INTEL_COMPILER) +diff --git a/test/test-active.c b/test/test-active.c +index 38438956..aed8a36e 100644 +--- a/test/test-active.c ++++ b/test/test-active.c +@@ -44,6 +44,8 @@ TEST_IMPL(active) { + int r; + uv_timer_t timer; + ++ close_cb_called = 0; ++ + r = uv_timer_init(uv_default_loop(), &timer); + ASSERT(r == 0); + +diff --git a/test/test-async-null-cb.c b/test/test-async-null-cb.c +index 52652d91..2b341c4a 100644 +--- a/test/test-async-null-cb.c ++++ b/test/test-async-null-cb.c +@@ -52,6 +52,8 @@ TEST_IMPL(async_null_cb) { + */ + memset(&async_handle, 0xff, sizeof(async_handle)); + ++ check_cb_called = 0; ++ + ASSERT(0 == uv_async_init(uv_default_loop(), &async_handle, NULL)); + ASSERT(0 == uv_check_init(uv_default_loop(), &check_handle)); + ASSERT(0 == uv_check_start(&check_handle, check_cb)); +diff --git a/test/test-async.c b/test/test-async.c +index 619be620..fee1ddd1 100644 +--- a/test/test-async.c ++++ b/test/test-async.c +@@ -108,6 +108,10 @@ static void prepare_cb(uv_prepare_t* handle) { + TEST_IMPL(async) { + int r; + ++ async_cb_called = 0; ++ close_cb_called = 0; ++ prepare_cb_called = 0; ++ + r = uv_mutex_init(&mutex); + ASSERT(r == 0); + uv_mutex_lock(&mutex); +diff --git a/test/test-close-order.c b/test/test-close-order.c +index c2fd6c3d..7a8111f0 100644 +--- a/test/test-close-order.c ++++ b/test/test-close-order.c +@@ -56,6 +56,11 @@ static void timer_cb(uv_timer_t* handle) { + + TEST_IMPL(close_order) { + uv_loop_t* loop; ++ ++ check_cb_called = 0; ++ timer_cb_called = 0; ++ close_cb_called = 0; ++ + loop = uv_default_loop(); + + uv_check_init(loop, &check_handle); +diff --git a/test/test-default-loop-close.c b/test/test-default-loop-close.c +index 51e1e7dc..fd9ad810 100644 +--- a/test/test-default-loop-close.c ++++ b/test/test-default-loop-close.c +@@ -36,6 +36,8 @@ TEST_IMPL(default_loop_close) { + uv_loop_t* loop; + uv_timer_t timer_handle; + ++ timer_cb_called = 0; ++ + loop = uv_default_loop(); + ASSERT_NOT_NULL(loop); + +diff --git a/test/test-fs-copyfile.c b/test/test-fs-copyfile.c +index fa00fe4e..e7e1a409 100644 +--- a/test/test-fs-copyfile.c ++++ b/test/test-fs-copyfile.c +@@ -25,7 +25,8 @@ + #if defined(__unix__) || defined(__POSIX__) || \ + defined(__APPLE__) || defined(__sun) || \ + defined(_AIX) || defined(__MVS__) || \ +- defined(__HAIKU__) || defined(__QNX__) ++ defined(__HAIKU__) || defined(__QNX__) || \ ++ defined(__NuttX__) + #include /* unlink, etc. */ + #else + # include +diff --git a/test/test-idle.c b/test/test-idle.c +index f49d1964..91a20bd2 100644 +--- a/test/test-idle.c ++++ b/test/test-idle.c +@@ -72,6 +72,11 @@ static void check_cb(uv_check_t* handle) { + TEST_IMPL(idle_starvation) { + int r; + ++ idle_cb_called = 0; ++ check_cb_called = 0; ++ timer_cb_called = 0; ++ close_cb_called = 0; ++ + r = uv_idle_init(uv_default_loop(), &idle_handle); + ASSERT(r == 0); + r = uv_idle_start(&idle_handle, idle_cb); +diff --git a/test/test-list.h b/test/test-list.h +index 59b95da9..db8545ed 100644 +--- a/test/test-list.h ++++ b/test/test-list.h +@@ -1112,7 +1112,7 @@ TASK_LIST_START + TEST_ENTRY (req_type_name) + TEST_ENTRY (getters_setters) + +-#ifndef _WIN32 ++#if !defined(_WIN32) && !defined(__NuttX__) + TEST_ENTRY (fork_timer) + TEST_ENTRY (fork_socketpair) + TEST_ENTRY (fork_socketpair_started) +diff --git a/test/test-loop-alive.c b/test/test-loop-alive.c +index cf4d3019..9a7b1024 100644 +--- a/test/test-loop-alive.c ++++ b/test/test-loop-alive.c +@@ -63,5 +63,6 @@ TEST_IMPL(loop_alive) { + ASSERT(r == 0); + ASSERT(!uv_loop_alive(uv_default_loop())); + ++ MAKE_VALGRIND_HAPPY(); + return 0; + } +diff --git a/test/test-loop-close.c b/test/test-loop-close.c +index f0f3e627..d3f8748f 100644 +--- a/test/test-loop-close.c ++++ b/test/test-loop-close.c +@@ -53,6 +53,7 @@ TEST_IMPL(loop_close) { + ASSERT(0 == uv_loop_close(&loop)); + ASSERT(loop.data == (void*) &loop); + ++ MAKE_VALGRIND_HAPPY(); + return 0; + } + +diff --git a/test/test-loop-configure.c b/test/test-loop-configure.c +index d057c1ed..1633f597 100644 +--- a/test/test-loop-configure.c ++++ b/test/test-loop-configure.c +@@ -25,7 +25,7 @@ TEST_IMPL(loop_configure) { + uv_timer_t timer_handle; + uv_loop_t loop; + ASSERT(0 == uv_loop_init(&loop)); +-#ifdef _WIN32 ++#ifndef SIGPROF + ASSERT(UV_ENOSYS == uv_loop_configure(&loop, UV_LOOP_BLOCK_SIGNAL, 0)); + #else + ASSERT(0 == uv_loop_configure(&loop, UV_LOOP_BLOCK_SIGNAL, SIGPROF)); +diff --git a/test/test-loop-handles.c b/test/test-loop-handles.c +index 05cb8466..5db583b5 100644 +--- a/test/test-loop-handles.c ++++ b/test/test-loop-handles.c +@@ -282,6 +282,21 @@ TEST_IMPL(loop_handles) { + int i; + int r; + ++ loop_iteration = 0; ++ prepare_1_cb_called = 0; ++ prepare_1_close_cb_called = 0; ++ prepare_2_cb_called = 0; ++ prepare_2_close_cb_called = 0; ++ check_cb_called = 0; ++ check_close_cb_called = 0; ++ idle_1_cb_called = 0; ++ idle_1_close_cb_called = 0; ++ idles_1_active = 0; ++ idle_2_cb_called = 0; ++ idle_2_close_cb_called = 0; ++ idle_2_cb_started = 0; ++ idle_2_is_active = 0; ++ + r = uv_prepare_init(uv_default_loop(), &prepare_1_handle); + ASSERT(r == 0); + r = uv_prepare_start(&prepare_1_handle, prepare_1_cb); +diff --git a/test/test-loop-stop.c b/test/test-loop-stop.c +index 14b8c111..6aa251fd 100644 +--- a/test/test-loop-stop.c ++++ b/test/test-loop-stop.c +@@ -49,6 +49,11 @@ static void timer_cb(uv_timer_t* handle) { + + TEST_IMPL(loop_stop) { + int r; ++ ++ prepare_called = 0; ++ timer_called = 0; ++ num_ticks = 10; ++ + uv_prepare_init(uv_default_loop(), &prepare_handle); + uv_prepare_start(&prepare_handle, prepare_cb); + uv_timer_init(uv_default_loop(), &timer_handle); +@@ -67,5 +72,6 @@ TEST_IMPL(loop_stop) { + ASSERT(timer_called == 10); + ASSERT(prepare_called == 10); + ++ MAKE_VALGRIND_HAPPY(); + return 0; + } +diff --git a/test/test-pipe-connect-error.c b/test/test-pipe-connect-error.c +index 30c270d9..0e9eea30 100644 +--- a/test/test-pipe-connect-error.c ++++ b/test/test-pipe-connect-error.c +@@ -35,6 +35,11 @@ + static int close_cb_called = 0; + static int connect_cb_called = 0; + ++static void init_globals(void) ++{ ++ close_cb_called = 0; ++ connect_cb_called = 0; ++} + + static void close_cb(uv_handle_t* handle) { + ASSERT_NOT_NULL(handle); +@@ -61,6 +66,7 @@ TEST_IMPL(pipe_connect_bad_name) { + uv_connect_t req; + int r; + ++ init_globals(); + r = uv_pipe_init(uv_default_loop(), &client, 0); + ASSERT(r == 0); + uv_pipe_connect(&req, &client, BAD_PIPENAME, connect_cb); +@@ -84,6 +90,7 @@ TEST_IMPL(pipe_connect_to_file) { + uv_connect_t req; + int r; + ++ init_globals(); + r = uv_pipe_init(uv_default_loop(), &client, 0); + ASSERT(r == 0); + uv_pipe_connect(&req, &client, path, connect_cb_file); +diff --git a/test/test-pipe-connect-prepare.c b/test/test-pipe-connect-prepare.c +index 08b57cbf..e6975b95 100644 +--- a/test/test-pipe-connect-prepare.c ++++ b/test/test-pipe-connect-prepare.c +@@ -64,6 +64,9 @@ static void prepare_cb(uv_prepare_t* handle) { + TEST_IMPL(pipe_connect_on_prepare) { + int r; + ++ close_cb_called = 0; ++ connect_cb_called = 0; ++ + r = uv_pipe_init(uv_default_loop(), &pipe_handle, 0); + ASSERT(r == 0); + +diff --git a/test/test-queue-foreach-delete.c b/test/test-queue-foreach-delete.c +index 049ea776..2b54de1d 100644 +--- a/test/test-queue-foreach-delete.c ++++ b/test/test-queue-foreach-delete.c +@@ -101,6 +101,9 @@ static const unsigned first_handle_number_fs_event = 0; + #define INIT_AND_START(name, loop) \ + do { \ + size_t i; \ ++ name##_cb_calls[0] = 0; \ ++ name##_cb_calls[1] = 0; \ ++ name##_cb_calls[2] = 0; \ + for (i = 0; i < ARRAY_SIZE(name); i++) { \ + int r; \ + r = uv_##name##_init((loop), &(name)[i]); \ +diff --git a/test/test-random.c b/test/test-random.c +index 2e3ce442..6736c342 100644 +--- a/test/test-random.c ++++ b/test/test-random.c +@@ -53,6 +53,9 @@ TEST_IMPL(random_async) { + uv_random_t req; + uv_loop_t* loop; + ++ random_cb_called = 0; ++ memset(scratch, 0, sizeof(scratch)); ++ + loop = uv_default_loop(); + ASSERT(UV_EINVAL == uv_random(loop, &req, scratch, sizeof(scratch), -1, + random_cb)); +@@ -79,6 +82,9 @@ TEST_IMPL(random_sync) { + char zero[256]; + char buf[256]; + ++ random_cb_called = 0; ++ memset(scratch, 0, sizeof(scratch)); ++ + ASSERT(UV_EINVAL == uv_random(NULL, NULL, buf, sizeof(buf), -1, NULL)); + ASSERT(UV_E2BIG == uv_random(NULL, NULL, buf, -1, -1, NULL)); + +diff --git a/test/test-run-nowait.c b/test/test-run-nowait.c +index 43524f63..9f2645b5 100644 +--- a/test/test-run-nowait.c ++++ b/test/test-run-nowait.c +@@ -34,6 +34,9 @@ static void timer_cb(uv_timer_t* handle) { + + TEST_IMPL(run_nowait) { + int r; ++ ++ timer_called = 0; ++ + uv_timer_init(uv_default_loop(), &timer_handle); + uv_timer_start(&timer_handle, timer_cb, 100, 100); + +@@ -41,5 +44,6 @@ TEST_IMPL(run_nowait) { + ASSERT(r != 0); + ASSERT(timer_called == 0); + ++ MAKE_VALGRIND_HAPPY(); + return 0; + } +diff --git a/test/test-run-once.c b/test/test-run-once.c +index 10cbf95e..7de04a91 100644 +--- a/test/test-run-once.c ++++ b/test/test-run-once.c +@@ -37,6 +37,9 @@ static void idle_cb(uv_idle_t* handle) { + + + TEST_IMPL(run_once) { ++ ++ idle_counter = 0; ++ + uv_idle_init(uv_default_loop(), &idle_handle); + uv_idle_start(&idle_handle, idle_cb); + +diff --git a/test/test-strscpy.c b/test/test-strscpy.c +index 4e7db6ff..f1d3e3ac 100644 +--- a/test/test-strscpy.c ++++ b/test/test-strscpy.c +@@ -24,7 +24,9 @@ + #include + + #include "../src/strscpy.h" ++#ifndef __NuttX__ + #include "../src/strscpy.c" ++#endif + + TEST_IMPL(strscpy) { + char d[4]; +diff --git a/test/test-thread.c b/test/test-thread.c +index 8de5a6f0..11e3cf80 100644 +--- a/test/test-thread.c ++++ b/test/test-thread.c +@@ -61,6 +61,11 @@ static void fs_cb(uv_fs_t* handle); + static int thread_called; + static uv_key_t tls_key; + ++static void init_globals(void) ++{ ++ thread_called = 0; ++ tls_key = 0; ++} + + static void getaddrinfo_do(struct getaddrinfo_req* req) { + int r; +@@ -151,6 +156,8 @@ TEST_IMPL(thread_create) { + uv_thread_t tid; + int r; + ++ init_globals(); ++ + r = uv_thread_create(&tid, thread_entry, (void *) 42); + ASSERT(r == 0); + +@@ -172,6 +179,7 @@ TEST_IMPL(threadpool_multiple_event_loops) { + RETURN_SKIP("Test does not currently work in QEMU"); + #endif + ++ init_globals(); + struct test_thread threads[8]; + size_t i; + int r; +@@ -205,6 +213,7 @@ static void tls_thread(void* arg) { + TEST_IMPL(thread_local_storage) { + char name[] = "main"; + uv_thread_t threads[2]; ++ init_globals(); + ASSERT(0 == uv_key_create(&tls_key)); + ASSERT_NULL(uv_key_get(&tls_key)); + uv_key_set(&tls_key, name); +@@ -248,6 +257,7 @@ static void thread_check_stack(void* arg) { + + TEST_IMPL(thread_stack_size) { + uv_thread_t thread; ++ init_globals(); + ASSERT(0 == uv_thread_create(&thread, thread_check_stack, NULL)); + ASSERT(0 == uv_thread_join(&thread)); + return 0; +@@ -257,6 +267,7 @@ TEST_IMPL(thread_stack_size_explicit) { + uv_thread_t thread; + uv_thread_options_t options; + ++ init_globals(); + options.flags = UV_THREAD_HAS_STACK_SIZE; + options.stack_size = 1024 * 1024; + ASSERT(0 == uv_thread_create_ex(&thread, &options, +diff --git a/test/test-threadpool-cancel.c b/test/test-threadpool-cancel.c +index 1e867c51..955d49b3 100644 +--- a/test/test-threadpool-cancel.c ++++ b/test/test-threadpool-cancel.c +@@ -49,6 +49,13 @@ static unsigned timer_cb_called; + static uv_work_t pause_reqs[4]; + static uv_sem_t pause_sems[ARRAY_SIZE(pause_reqs)]; + ++static void init_globals(void) ++{ ++ fs_cb_called = 0; ++ done_cb_called = 0; ++ done2_cb_called = 0; ++ timer_cb_called = 0; ++} + + static void work_cb(uv_work_t* req) { + uv_sem_wait(pause_sems + (req - pause_reqs)); +@@ -168,6 +175,8 @@ TEST_IMPL(threadpool_cancel_getaddrinfo) { + uv_loop_t* loop; + int r; + ++ init_globals(); ++ + INIT_CANCEL_INFO(&ci, reqs); + loop = uv_default_loop(); + saturate_threadpool(); +@@ -201,6 +210,8 @@ TEST_IMPL(threadpool_cancel_getnameinfo) { + uv_loop_t* loop; + int r; + ++ init_globals(); ++ + r = uv_ip4_addr("127.0.0.1", 80, &addr4); + ASSERT(r == 0); + +@@ -234,6 +245,8 @@ TEST_IMPL(threadpool_cancel_random) { + struct random_info req; + uv_loop_t* loop; + ++ init_globals(); ++ + saturate_threadpool(); + loop = uv_default_loop(); + ASSERT(0 == uv_random(loop, +@@ -259,6 +272,8 @@ TEST_IMPL(threadpool_cancel_work) { + uv_loop_t* loop; + unsigned i; + ++ init_globals(); ++ + INIT_CANCEL_INFO(&ci, reqs); + loop = uv_default_loop(); + saturate_threadpool(); +@@ -284,6 +299,8 @@ TEST_IMPL(threadpool_cancel_fs) { + unsigned n; + uv_buf_t iov; + ++ init_globals(); ++ + INIT_CANCEL_INFO(&ci, reqs); + loop = uv_default_loop(); + saturate_threadpool(); +@@ -335,6 +352,8 @@ TEST_IMPL(threadpool_cancel_single) { + uv_loop_t* loop; + uv_work_t req; + ++ init_globals(); ++ + saturate_threadpool(); + loop = uv_default_loop(); + ASSERT(0 == uv_queue_work(loop, &req, (uv_work_cb) abort, nop_done_cb)); +diff --git a/test/test-threadpool.c b/test/test-threadpool.c +index e3d17d75..845c4b6a 100644 +--- a/test/test-threadpool.c ++++ b/test/test-threadpool.c +@@ -27,6 +27,11 @@ static int after_work_cb_count; + static uv_work_t work_req; + static char data; + ++static void init_globals(void) ++{ ++ work_cb_count = 0; ++ after_work_cb_count = 0; ++} + + static void work_cb(uv_work_t* req) { + ASSERT(req == &work_req); +@@ -46,6 +51,8 @@ static void after_work_cb(uv_work_t* req, int status) { + TEST_IMPL(threadpool_queue_work_simple) { + int r; + ++ init_globals(); ++ + work_req.data = &data; + r = uv_queue_work(uv_default_loop(), &work_req, work_cb, after_work_cb); + ASSERT(r == 0); +@@ -62,6 +69,8 @@ TEST_IMPL(threadpool_queue_work_simple) { + TEST_IMPL(threadpool_queue_work_einval) { + int r; + ++ init_globals(); ++ + work_req.data = &data; + r = uv_queue_work(uv_default_loop(), &work_req, NULL, after_work_cb); + ASSERT(r == UV_EINVAL); +diff --git a/test/test-timer-again.c b/test/test-timer-again.c +index 834b59d7..cffc2e07 100644 +--- a/test/test-timer-again.c ++++ b/test/test-timer-again.c +@@ -95,6 +95,11 @@ static void repeat_2_cb(uv_timer_t* handle) { + TEST_IMPL(timer_again) { + int r; + ++ close_cb_called = 0; ++ repeat_1_cb_called = 0; ++ repeat_2_cb_called = 0; ++ repeat_2_cb_allowed = 0; ++ + start_time = uv_now(uv_default_loop()); + ASSERT(0 < start_time); + +diff --git a/test/test-timer-from-check.c b/test/test-timer-from-check.c +index a18c7e1f..745eec4d 100644 +--- a/test/test-timer-from-check.c ++++ b/test/test-timer-from-check.c +@@ -62,6 +62,11 @@ static void check_cb(uv_check_t* handle) { + + + TEST_IMPL(timer_from_check) { ++ ++ prepare_cb_called = 0; ++ check_cb_called = 0; ++ timer_cb_called = 0; ++ + ASSERT(0 == uv_prepare_init(uv_default_loop(), &prepare_handle)); + ASSERT(0 == uv_check_init(uv_default_loop(), &check_handle)); + ASSERT(0 == uv_check_start(&check_handle, check_cb)); +diff --git a/test/test-timer.c b/test/test-timer.c +index d0921a96..a9cb2731 100644 +--- a/test/test-timer.c ++++ b/test/test-timer.c +@@ -32,6 +32,17 @@ static uint64_t start_time; + static uv_timer_t tiny_timer; + static uv_timer_t huge_timer1; + static uv_timer_t huge_timer2; ++static int ncalls = 0; ++ ++void init_globals(void) ++{ ++ once_cb_called = 0; ++ once_close_cb_called = 0; ++ repeat_cb_called = 0; ++ repeat_close_cb_called = 0; ++ order_cb_called = 0; ++ ncalls = 0; ++} + + + static void once_close_cb(uv_handle_t* handle) { +@@ -94,6 +105,8 @@ TEST_IMPL(timer) { + unsigned int i; + int r; + ++ init_globals(); ++ + start_time = uv_now(uv_default_loop()); + ASSERT(0 < start_time); + +@@ -140,6 +153,8 @@ TEST_IMPL(timer_start_twice) { + uv_timer_t once; + int r; + ++ init_globals(); ++ + r = uv_timer_init(uv_default_loop(), &once); + ASSERT(r == 0); + r = uv_timer_start(&once, never_cb, 86400 * 1000, 0); +@@ -159,6 +174,8 @@ TEST_IMPL(timer_start_twice) { + TEST_IMPL(timer_init) { + uv_timer_t handle; + ++ init_globals(); ++ + ASSERT(0 == uv_timer_init(uv_default_loop(), &handle)); + ASSERT(0 == uv_timer_get_repeat(&handle)); + ASSERT_UINT64_LE(0, uv_timer_get_due_in(&handle)); +@@ -185,6 +202,8 @@ TEST_IMPL(timer_order) { + uv_timer_t handle_a; + uv_timer_t handle_b; + ++ init_globals(); ++ + first = 0; + second = 1; + ASSERT(0 == uv_timer_init(uv_default_loop(), &handle_a)); +@@ -227,6 +246,9 @@ static void tiny_timer_cb(uv_timer_t* handle) { + + + TEST_IMPL(timer_huge_timeout) { ++ ++ init_globals(); ++ + 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)); +@@ -243,7 +265,6 @@ TEST_IMPL(timer_huge_timeout) { + + + static void huge_repeat_cb(uv_timer_t* handle) { +- static int ncalls; + + if (ncalls == 0) + ASSERT(handle == &huge_timer1); +@@ -258,6 +279,9 @@ static void huge_repeat_cb(uv_timer_t* handle) { + + + TEST_IMPL(timer_huge_repeat) { ++ ++ init_globals(); ++ + ASSERT(0 == uv_timer_init(uv_default_loop(), &tiny_timer)); + ASSERT(0 == uv_timer_init(uv_default_loop(), &huge_timer1)); + ASSERT(0 == uv_timer_start(&tiny_timer, huge_repeat_cb, 2, 2)); +@@ -279,6 +303,10 @@ static void timer_run_once_timer_cb(uv_timer_t* handle) { + TEST_IMPL(timer_run_once) { + uv_timer_t timer_handle; + ++ init_globals(); ++ ++ timer_run_once_timer_cb_called = 0; ++ + ASSERT(0 == uv_timer_init(uv_default_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)); +@@ -299,6 +327,8 @@ TEST_IMPL(timer_run_once) { + TEST_IMPL(timer_is_closing) { + uv_timer_t handle; + ++ init_globals(); ++ + ASSERT(0 == uv_timer_init(uv_default_loop(), &handle)); + uv_close((uv_handle_t *)&handle, NULL); + +@@ -312,6 +342,8 @@ TEST_IMPL(timer_is_closing) { + TEST_IMPL(timer_null_callback) { + uv_timer_t handle; + ++ init_globals(); ++ + ASSERT(0 == uv_timer_init(uv_default_loop(), &handle)); + ASSERT(UV_EINVAL == uv_timer_start(&handle, NULL, 100, 100)); + +@@ -333,6 +365,8 @@ TEST_IMPL(timer_early_check) { + uv_timer_t timer_handle; + const uint64_t timeout_ms = 10; + ++ init_globals(); ++ + timer_early_check_expected_time = uv_now(uv_default_loop()) + timeout_ms; + + ASSERT(0 == uv_timer_init(uv_default_loop(), &timer_handle)); diff --git a/system/libuv/Kconfig b/system/libuv/Kconfig new file mode 100644 index 000000000..ba487bc2b --- /dev/null +++ b/system/libuv/Kconfig @@ -0,0 +1,45 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config LIBUV + bool "libuv asynchronous I/O Library" + default n + select PIPES + ---help--- + Enable build for libuv asynchronous I/O Library + +if LIBUV + +config LIBUV_THREADPOOL_SIZE + int "libuv default thread pool size" + default 1 + +choice + prompt "libuv utils" + default LIBUV_UTILS_NONE + +config LIBUV_UTILS_NONE + bool "none" + +config LIBUV_UTILS_TEST + bool "uv_run_tests" + +config LIBUV_UTILS_BENCHMARK + bool "uv_run_benchmarks" + +endchoice + +if !LIBUV_UTILS_NONE + +config LIBUV_UTILS_PRIORITY + int "libuv utils priority" + default 100 + +config LIBUV_UTILS_STACKSIZE + int "libuv utils stack size" + default 8192 +endif + +endif diff --git a/system/libuv/Make.defs b/system/libuv/Make.defs index 5e0691a37..f5406cb53 100644 --- a/system/libuv/Make.defs +++ b/system/libuv/Make.defs @@ -18,15 +18,14 @@ # ############################################################################ -# Set up build configuration and environment +ifneq ($(CONFIG_LIBUV),) +CONFIGURED_APPS += $(APPDIR)/system/libuv -LIBUV_DIR := $(APPDIR)/system/libuv +# Enable include. -CONFIG_LIBUV_URL ?= "https://github.com/libuv/libuv/archive" -CONFIG_LIBUV_VERSION ?= 1.38.1 -CONFIG_LIBUV_TARBALL ?= v$(CONFIG_LIBUV_VERSION).zip +CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" \ + $(APPDIR)/system/libuv/libuv/include} +CXXFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" \ + $(APPDIR)/system/libuv/libuv/include} -LIBUV_UNPACKNAME := libuv-$(CONFIG_LIBUV_VERSION) -LIBUV_UNPACKDIR := $(LIBUV_DIR)/$(LIBUV_UNPACKNAME) - -include $(wildcard $(APPDIR)/system/libuv/*/Make.defs) +endif diff --git a/system/libuv/Makefile b/system/libuv/Makefile index fe504bfc7..b6fd578fd 100644 --- a/system/libuv/Makefile +++ b/system/libuv/Makefile @@ -18,6 +18,305 @@ # ############################################################################ -MENUDESC = "libuv async i/o Library" +include $(APPDIR)/Make.defs -include $(APPDIR)/Directory.mk +LIBUV_PATCHS ?= $(sort $(wildcard 000*.patch)) + +LIBUV_VERSION = 1.42.0 +LIBUV_UNPACK = libuv +LIBUV_TARBALL = v$(LIBUV_VERSION).zip +LIBUV_URL_BASE = https://github.com/libuv/libuv/archive/refs/tags/ +LIBUV_URL = $(LIBUV_URL_BASE)/$(LIBUV_TARBALL) + + +$(LIBUV_TARBALL): + @echo "Downloading: $(LIBUV_TARBALL)" + $(Q) curl -L $(LIBUV_URL) -o $(LIBUV_TARBALL) + +$(LIBUV_UNPACK): $(LIBUV_TARBALL) + @echo "Unpacking: $(LIBUV_TARBALL) -> $(LIBUV_UNPACK)" + $(call DELDIR, $(LIBUV_UNPACK)) + $(Q) unzip $(LIBUV_TARBALL) + $(Q) mv libuv-$(LIBUV_VERSION) $(LIBUV_UNPACK) + $(Q) cat $(LIBUV_PATCHS) | \ + patch -s -N -d $(LIBUV_UNPACK) -p1 + +$(LIBUV_UNPACK)/.patch: $(LIBUV_UNPACK) + $(Q) touch $(LIBUV_UNPACK)/.patch + +# Build libuv library + +CFLAGS += -I$(LIBUV_UNPACK)/src +CFLAGS += -I$(LIBUV_UNPACK)/src/unix +CFLAGS += -I$(LIBUV_UNPACK)/test +CFLAGS += -Wno-shadow +CFLAGS += -DDEF_THREADPOOL_SIZE=CONFIG_LIBUV_THREADPOOL_SIZE + +VPATH += $(LIBUV_UNPACK)/src +VPATH += $(LIBUV_UNPACK)/src/unix +VPATH += $(LIBUV_UNPACK)/test + +DEPPATH += --dep-path $(LIBUV_UNPACK)/src +DEPPATH += --dep-path $(LIBUV_UNPACK)/src/unix +DEPPATH += --dep-path $(LIBUV_UNPACK)/test + +CSRCS += core.c +CSRCS += poll.c +CSRCS += loop.c +CSRCS += thread.c +CSRCS += no-proctitle.c +CSRCS += posix-hrtime.c +CSRCS += posix-poll.c +CSRCS += uv-data-getter-setters.c +CSRCS += version.c +CSRCS += idna.c +CSRCS += no-fsevents.c +CSRCS += uv-common.c +CSRCS += strscpy.c +CSRCS += random-devurandom.c +CSRCS += random.c +CSRCS += nuttx.c +CSRCS += tty.c +CSRCS += loop-watcher.c +CSRCS += signal.c +CSRCS += stream.c +CSRCS += threadpool.c +CSRCS += async.c +CSRCS += pipe.c +CSRCS += fs.c +CSRCS += fs-poll.c +CSRCS += timer.c +CSRCS += process.c + +ifneq ($(CONFIG_LIBC_DLFCN),) +CSRCS += dl.c +endif + +ifneq ($(CONFIG_NET),) +CSRCS += getaddrinfo.c +CSRCS += getnameinfo.c +CSRCS += inet.c +endif + +ifneq ($(CONFIG_NET_TCP),) +CSRCS += tcp.c +endif + +ifneq ($(CONFIG_NET_UDP),) +CSRCS += udp.c +endif + +PRIORITY = $(CONFIG_LIBUV_UTILS_PRIORITY) +STACKSIZE = $(CONFIG_LIBUV_UTILS_STACKSIZE) + +ifneq ($(CONFIG_LIBUV_UTILS_TEST),) + +PROGNAME = uv_run_tests +MAINSRC = run-tests.c + +CSRCS += runner.c +CSRCS += runner-unix.c +CSRCS += echo-server.c + +CSRCS += test-active.c +CSRCS += test-async.c +CSRCS += test-async-null-cb.c +CSRCS += test-barrier.c +CSRCS += test-callback-order.c +CSRCS += test-callback-stack.c +CSRCS += test-close-fd.c +CSRCS += test-close-order.c +CSRCS += test-condvar.c +CSRCS += test-connection-fail.c +CSRCS += test-connect-unspecified.c +CSRCS += test-cwd-and-chdir.c +CSRCS += test-default-loop-close.c +CSRCS += test-delayed-accept.c +CSRCS += test-dlerror.c +CSRCS += test-eintr-handling.c +CSRCS += test-embed.c +CSRCS += test-emfile.c +CSRCS += test-env-vars.c +CSRCS += test-error.c +CSRCS += test-fail-always.c +CSRCS += test-fs.c +CSRCS += test-fs-copyfile.c +CSRCS += test-fs-event.c +CSRCS += test-fs-fd-hash.c +CSRCS += test-fs-open-flags.c +CSRCS += test-fs-poll.c +CSRCS += test-fs-readdir.c +CSRCS += test-getaddrinfo.c +CSRCS += test-get-currentexe.c +CSRCS += test-gethostname.c +CSRCS += test-get-loadavg.c +CSRCS += test-get-memory.c +CSRCS += test-getnameinfo.c +CSRCS += test-get-passwd.c +CSRCS += test-getsockname.c +CSRCS += test-getters-setters.c +CSRCS += test-gettimeofday.c +CSRCS += test-handle-fileno.c +CSRCS += test-homedir.c +CSRCS += test-hrtime.c +CSRCS += test-idle.c +CSRCS += test-idna.c +CSRCS += test-ip4-addr.c +CSRCS += test-ip6-addr.c +CSRCS += test-ipc.c +CSRCS += test-ipc-heavy-traffic-deadlock-bug.c +CSRCS += test-ipc-send-recv.c +CSRCS += test-loop-alive.c +CSRCS += test-loop-close.c +CSRCS += test-loop-configure.c +CSRCS += test-loop-handles.c +CSRCS += test-loop-stop.c +CSRCS += test-loop-time.c +CSRCS += test-metrics.c +CSRCS += test-multiple-listen.c +CSRCS += test-mutexes.c +CSRCS += test-not-readable-nor-writable-on-read-error.c +CSRCS += test-not-readable-on-eof.c +CSRCS += test-not-writable-after-shutdown.c +CSRCS += test-osx-select.c +CSRCS += test-pass-always.c +CSRCS += test-ping-pong.c +CSRCS += test-pipe-bind-error.c +CSRCS += test-pipe-close-stdout-read-stdin.c +CSRCS += test-pipe-connect-error.c +CSRCS += test-pipe-connect-multiple.c +CSRCS += test-pipe-connect-prepare.c +CSRCS += test-pipe-getsockname.c +CSRCS += test-pipe-pending-instances.c +CSRCS += test-pipe-sendmsg.c +CSRCS += test-pipe-server-close.c +CSRCS += test-pipe-set-fchmod.c +CSRCS += test-pipe-set-non-blocking.c +CSRCS += test-platform-output.c +CSRCS += test-poll.c +CSRCS += test-poll-close.c +CSRCS += test-poll-close-doesnt-corrupt-stack.c +CSRCS += test-poll-closesocket.c +CSRCS += test-poll-multiple-handles.c +CSRCS += test-poll-oob.c +CSRCS += test-process-priority.c +CSRCS += test-process-title.c +CSRCS += test-process-title-threadsafe.c +CSRCS += test-queue-foreach-delete.c +CSRCS += test-random.c +CSRCS += test-ref.c +CSRCS += test-run-nowait.c +CSRCS += test-run-once.c +CSRCS += test-semaphore.c +CSRCS += test-shutdown-close.c +CSRCS += test-shutdown-eof.c +CSRCS += test-shutdown-simultaneous.c +CSRCS += test-shutdown-twice.c +CSRCS += test-signal.c +CSRCS += test-signal-multiple-loops.c +CSRCS += test-signal-pending-on-close.c +CSRCS += test-socket-buffer-size.c +CSRCS += test-spawn.c +CSRCS += test-stdio-over-pipes.c +CSRCS += test-strscpy.c +CSRCS += test-tcp-alloc-cb-fail.c +CSRCS += test-tcp-bind6-error.c +CSRCS += test-tcp-bind-error.c +CSRCS += test-tcp-close-accept.c +CSRCS += test-tcp-close.c +CSRCS += test-tcp-close-reset.c +CSRCS += test-tcp-close-while-connecting.c +CSRCS += test-tcp-connect6-error.c +CSRCS += test-tcp-connect-error-after-write.c +CSRCS += test-tcp-connect-error.c +CSRCS += test-tcp-connect-timeout.c +CSRCS += test-tcp-create-socket-early.c +CSRCS += test-tcp-flags.c +CSRCS += test-tcp-oob.c +CSRCS += test-tcp-open.c +CSRCS += test-tcp-read-stop.c +CSRCS += test-tcp-read-stop-start.c +CSRCS += test-tcp-shutdown-after-write.c +CSRCS += test-tcp-try-write.c +CSRCS += test-tcp-try-write-error.c +CSRCS += test-tcp-unexpected-read.c +CSRCS += test-tcp-write-after-connect.c +CSRCS += test-tcp-writealot.c +CSRCS += test-tcp-write-fail.c +CSRCS += test-tcp-write-queue-order.c +CSRCS += test-tcp-write-to-half-open-connection.c +CSRCS += test-test-macros.c +CSRCS += test-thread.c +CSRCS += test-thread-equal.c +CSRCS += test-threadpool.c +CSRCS += test-threadpool-cancel.c +CSRCS += test-timer-again.c +CSRCS += test-timer.c +CSRCS += test-timer-from-check.c +CSRCS += test-tmpdir.c +CSRCS += test-tty.c +CSRCS += test-tty-duplicate-key.c +CSRCS += test-tty-escape-sequence-processing.c +CSRCS += test-udp-alloc-cb-fail.c +CSRCS += test-udp-bind.c +CSRCS += test-udp-connect.c +CSRCS += test-udp-create-socket-early.c +CSRCS += test-udp-dgram-too-big.c +CSRCS += test-udp-ipv6.c +CSRCS += test-udp-mmsg.c +CSRCS += test-udp-multicast-interface6.c +CSRCS += test-udp-multicast-interface.c +CSRCS += test-udp-multicast-join6.c +CSRCS += test-udp-multicast-join.c +CSRCS += test-udp-multicast-ttl.c +CSRCS += test-udp-open.c +CSRCS += test-udp-options.c +CSRCS += test-udp-send-and-recv.c +CSRCS += test-udp-send-hang-loop.c +CSRCS += test-udp-send-immediate.c +CSRCS += test-udp-sendmmsg-error.c +CSRCS += test-udp-send-unreachable.c +CSRCS += test-udp-try-send.c +CSRCS += test-uname.c +CSRCS += test-walk-handles.c +CSRCS += test-watcher-cross-stop.c +endif + +ifneq ($(CONFIG_LIBUV_UTILS_BENCHMARK),) + +PROGNAME = uv_run_benchmarks +MAINSRC = run-benchmarks.c + +CSRCS += runner.c +CSRCS += runner-unix.c + +CSRCS += benchmark-async-pummel.c +CSRCS += benchmark-async.c +CSRCS += benchmark-fs-stat.c +CSRCS += benchmark-getaddrinfo.c +CSRCS += benchmark-loop-count.c +CSRCS += benchmark-million-async.c +CSRCS += benchmark-million-timers.c +CSRCS += benchmark-multi-accept.c +CSRCS += benchmark-ping-pongs.c +CSRCS += benchmark-ping-udp.c +CSRCS += benchmark-pound.c +CSRCS += benchmark-pump.c +CSRCS += benchmark-sizes.c +CSRCS += benchmark-spawn.c +CSRCS += benchmark-tcp-write-batch.c +CSRCS += benchmark-thread.c +CSRCS += benchmark-udp-pummel.c + +CSRCS += blackhole-server.c +CSRCS += echo-server.c + +endif + +context:: $(LIBUV_UNPACK)/.patch + +distclean:: + $(call DELDIR, $(LIBUV_UNPACK)) + $(call DELFILE, $(LIBUV_TARBALL)) + +include $(APPDIR)/Application.mk diff --git a/system/libuv/README.md b/system/libuv/README.md new file mode 100644 index 000000000..9d853f207 --- /dev/null +++ b/system/libuv/README.md @@ -0,0 +1,17 @@ +# `libuv` + +Most features of libuv are supported by current port, except SIGPROF relative function (loop_configure). + +Nearly full libuv's test suite avaliable on NuttX, but some known case can't run on sim: + +* loop_update_time +* idle_starvation +* signal_multiple_loops +* signal_pending_on_close +* metrics_idle_time +* metrics_idle_time_thread +* metrics_idle_time_zero + +And some will cause crash by some reason: + +* fs_poll_ref diff --git a/system/libuv/libuv/Kconfig b/system/libuv/libuv/Kconfig deleted file mode 100644 index 76e8f7895..000000000 --- a/system/libuv/libuv/Kconfig +++ /dev/null @@ -1,129 +0,0 @@ -# -# For a description of the syntax of this configuration file, -# see the file kconfig-language.txt in the NuttX tools repository. -# - -config LIBUV - bool "libuv asynchronous I/O Library" - default n - ---help--- - Enable build for libuv asynchronous I/O Library - -if LIBUV - -config LIBUV_NPOLLWAITERS - int "Number of uv loop poll waiters" - default 8 - ---help--- - Maximum number of events a loop can wait on. - -config LIBUV_ASYNC - bool "libuv async support" - default n - select EVENT_FD - select EVENT_FD_POLL - ---help--- - Enable async support in libuv. - Eventfd is required for this feature. - -config LIBUV_TIMER - bool "libuv software timers support" - default n - ---help--- - Enable software timers support in libuv. - -config LIBUV_TIMER_NUTTX - bool "optimized software timers" - default y - depends on LIBUV_TIMER - ---help--- - Replace default libuv timer with optimized implementation - with low memory footprint. - -config LIBUV_STREAM - bool "libuv stream support" - default n - ---help--- - Enable stream support in libuv. - -config LIBUV_STREAM_READ_SIZE - int "Stream read buffer size" - default 128 - depends on LIBUV_STREAM - ---help--- - Defines the size of buffer used for stream reads. - -config LIBUV_PIPE - bool "libuv pipe support" - default n - depends on LIBUV_STREAM - ---help--- - Enable libuv pipe support. - -config LIBUV_FS - bool "libuv FS support" - default n - ---help--- - Enable libuv FS support. - This feature may require LIBUV_WQ to support async FS operations. - -config LIBUV_FS_POLL - bool "libuv fs-poll support" - default n - select LIBUV_FS - select LIBUV_TIMER - ---help--- - Enable libuv uv_fs_poll_*() API. - -config LIBUV_NET - bool - -config LIBUV_TCP - bool "libuv TCP support" - default n - depends on NET_TCP - depends on NET_TCPBACKLOG - select LIBUV_STREAM - select LIBUV_NET - ---help--- - Enable TCP support in libuv. - NET_TCPBACKLOG is required to poll on accept(). - -config LIBUV_WQ - bool "libuv workqueue support" - default n - select LIBUV_ASYNC - ---help--- - Enable workqueue support in libuv - -config LIBUV_WQ_THREADS_COUNT - int "libuv workqueue thread count" - depends on LIBUV_WQ - default 1 - ---help--- - Specify worker thread count shared between all uv loops - -config LIBUV_LOOP_WATCHERS - bool "libuv loop watchers support" - default n - ---help--- - Enable loop watchers support in libuv (idle,prepare and check) - -config LIBUV_CONTEXT - bool "Use static context for loops" - default y - ---help--- - Modify libuv API to remove static memory usage. - User must call "uv_context_init()" before any other libuv API and - must call "uv_library_shutdown()" when done. - This is required for flat memory builds else some libuv structures - will be shared between processes which can lead to inconsistency. - This option disable support for uv_default_loop() API. - -config LIBUV_LOW_FOOTPRINT - bool "Reduce libuv memory usage" - default y - ---help--- - Enable optimizations to reduce libuv memory usage - -endif # LIBUV diff --git a/system/libuv/libuv/Make.defs b/system/libuv/libuv/Make.defs deleted file mode 100644 index 8a6a29609..000000000 --- a/system/libuv/libuv/Make.defs +++ /dev/null @@ -1,31 +0,0 @@ -############################################################################ -# apps/system/libuv/libuv/Make.defs -# -# 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. -# -############################################################################ - -ifneq ($(CONFIG_LIBUV),) -CONFIGURED_APPS += $(APPDIR)/system/libuv/libuv - -# Enable include. - -CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" \ - $(APPDIR)/system/libuv/$(LIBUV_UNPACKNAME)/include} -CXXFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" \ - $(APPDIR)/system/libuv/$(LIBUV_UNPACKNAME)/include} - -endif diff --git a/system/libuv/libuv/Makefile b/system/libuv/libuv/Makefile deleted file mode 100644 index 4cd4f59a5..000000000 --- a/system/libuv/libuv/Makefile +++ /dev/null @@ -1,124 +0,0 @@ -############################################################################ -# apps/system/libuv/Makefile -# -# 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 $(APPDIR)/Make.defs - -LIBUV_PATCHS ?= $(sort $(wildcard $(LIBUV_DIR)/000*.patch)) -UNPACK ?= unzip -q - -$(LIBUV_DIR)/$(CONFIG_LIBUV_TARBALL): - @echo "Downloading: $(CONFIG_LIBUV_TARBALL)" - $(Q) curl -L $(CONFIG_LIBUV_URL)/$(CONFIG_LIBUV_TARBALL) \ - -o $(LIBUV_DIR)/$(CONFIG_LIBUV_TARBALL) - -$(LIBUV_UNPACKDIR): $(LIBUV_DIR)/$(CONFIG_LIBUV_TARBALL) - @echo "Unpacking: $(CONFIG_LIBUV_TARBALL) -> $(LIBUV_UNPACKDIR)" - $(call DELDIR, $(LIBUV_UNPACKDIR)) - $(Q) unzip -q -d "$(LIBUV_DIR)" "$(LIBUV_DIR)/$(CONFIG_LIBUV_TARBALL)" - $(Q) cat $(LIBUV_PATCHS) | \ - patch -s -N -d $(LIBUV_UNPACKDIR) -p1 - $(Q) touch $(LIBUV_UNPACKDIR) - -# Build libuv library - -CFLAGS += -I$(LIBUV_UNPACKDIR)/src -CFLAGS += -I$(LIBUV_UNPACKDIR)/src/unix -CFLAGS += -D__NUTTX__ - -CSRCS += $(LIBUV_UNPACKDIR)/src/unix/core.c -CSRCS += $(LIBUV_UNPACKDIR)/src/unix/poll.c -CSRCS += $(LIBUV_UNPACKDIR)/src/unix/loop.c -CSRCS += $(LIBUV_UNPACKDIR)/src/unix/thread.c -CSRCS += $(LIBUV_UNPACKDIR)/src/unix/no-proctitle.c - -ifeq ($(CONFIG_DEV_URANDOM),y) -CSRCS += $(LIBUV_UNPACKDIR)/src/unix/random-devurandom.c -CSRCS += $(LIBUV_UNPACKDIR)/src/random.c -endif - -ifeq ($(CONFIG_LIBUV_LOOP_WATCHERS),y) -CSRCS += $(LIBUV_UNPACKDIR)/src/unix/loop-watcher.c -endif - -# FIXME signal does not work yet -ifeq ($(CONFIG_LIBUV_SIGNAL),y) -CSRCS += $(LIBUV_UNPACKDIR)/src/unix/signal.c -endif - -# FIXME process does not work yet -ifeq ($(CONFIG_LIBUV_PROCESS),y) -CSRCS += $(LIBUV_UNPACKDIR)/src/unix/process.c -endif - -CSRCS += $(LIBUV_UNPACKDIR)/src/unix/nuttx.c - -ifeq ($(CONFIG_LIBUV_STREAM),y) -CSRCS += $(LIBUV_UNPACKDIR)/src/unix/nuttx_stream.c -endif - -ifeq ($(CONFIG_LIBUV_TCP),y) -CSRCS += $(LIBUV_UNPACKDIR)/src/unix/nuttx_tcp.c -endif - -ifeq ($(CONFIG_LIBUV_WQ),y) -CSRCS += $(LIBUV_UNPACKDIR)/src/unix/nuttx_threadpool.c -endif - -ifeq ($(CONFIG_LIBUV_ASYNC),y) -CSRCS += $(LIBUV_UNPACKDIR)/src/unix/async.c -endif - -ifeq ($(CONFIG_LIBUV_PIPE),y) -CSRCS += $(LIBUV_UNPACKDIR)/src/unix/pipe.c -endif - -ifeq ($(CONFIG_LIBUV_FS),y) -CSRCS += $(LIBUV_UNPACKDIR)/src/unix/fs.c -endif - -ifeq ($(CONFIG_LIBUV_FS_POLL),y) -CSRCS += $(LIBUV_UNPACKDIR)/src/fs-poll.c -endif - -ifeq ($(CONFIG_LIBUV_TIMER),y) -ifeq ($(CONFIG_LIBUV_TIMER_NUTTX),y) -CSRCS += $(LIBUV_UNPACKDIR)/src/unix/nuttx_timer.c -else -CSRCS += $(LIBUV_UNPACKDIR)/src/timer.c -endif -endif - -CSRCS += $(LIBUV_UNPACKDIR)/src/uv-common.c -CSRCS += $(LIBUV_UNPACKDIR)/src/strscpy.c - -ifeq ($(CONFIG_LIBUV_NET),y) -CSRCS += $(LIBUV_UNPACKDIR)/src/inet.c -endif - -context:: $(LIBUV_UNPACKDIR) - -clean:: - $(call DELFILE, $(OBJS)) - -distclean:: - $(call DELDIR, $(LIBUV_UNPACKDIR)) - $(call DELFILE, $(LIBUV_DIR)/$(CONFIG_LIBUV_TARBALL)) - -include $(APPDIR)/Application.mk diff --git a/system/libuv/tests/Kconfig b/system/libuv/tests/Kconfig deleted file mode 100644 index cf3d7cac9..000000000 --- a/system/libuv/tests/Kconfig +++ /dev/null @@ -1,35 +0,0 @@ -# -# For a description of the syntax of this configuration file, -# see the file kconfig-language.txt in the NuttX tools repository. -# - -menuconfig LIBUV_UNIT_TESTS - tristate "libuv unit-tests command" - default n - depends on LIBUV - select LIBUV_TIMER - select LIBUV_ASYNC - select LIBUV_WQ - select LIBUV_LOOP_WATCHERS - select LIBUV_CONTEXT - ---help--- - Add executable that runs all libuv unit-tests. - -if LIBUV_UNIT_TESTS - -config LIBUV_UNIT_TESTS_PROGNAME - string "libuv unit-tests program name" - default "libuvtest" - ---help--- - This is the name of the program that will be used when the NSH ELF - program is installed. - -config LIBUV_UNIT_TESTS_PRIORITY - int "libuv unit-tests task priority" - default 100 - -config LIBUV_UNIT_TESTS_STACKSIZE - int "libuv unit-tests stack size" - default DEFAULT_TASK_STACKSIZE - -endif # LIBUV_UNIT_TESTS diff --git a/system/libuv/tests/Make.defs b/system/libuv/tests/Make.defs deleted file mode 100644 index a6214fefa..000000000 --- a/system/libuv/tests/Make.defs +++ /dev/null @@ -1,23 +0,0 @@ -############################################################################ -# apps/system/libuv/tests/Make.defs -# -# 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. -# -############################################################################ - -ifneq ($(CONFIG_LIBUV_UNIT_TESTS),) -CONFIGURED_APPS += $(APPDIR)/system/libuv/tests -endif diff --git a/system/libuv/tests/Makefile b/system/libuv/tests/Makefile deleted file mode 100644 index d232725c1..000000000 --- a/system/libuv/tests/Makefile +++ /dev/null @@ -1,72 +0,0 @@ -############################################################################ -# apps/system/libuv/tests/Makefile -# -# 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 $(APPDIR)/Make.defs - -# libuv unit-tests command - -PROGNAME := $(CONFIG_LIBUV_UNIT_TESTS_PROGNAME) -PRIORITY := $(CONFIG_LIBUV_UNIT_TESTS_PRIORITY) -STACKSIZE := $(CONFIG_LIBUV_UNIT_TESTS_STACKSIZE) -MODULE := $(CONFIG_LIBUV_UNIT_TESTS) - -# Files - -MAINSRC := test_main.c -CSRCS += runner-nuttx.c -CSRCS += $(LIBUV_UNPACKDIR)/test/runner.c - -# Tests - -CSRCS += $(LIBUV_UNPACKDIR)/test/test-loop-time.c -CSRCS += $(LIBUV_UNPACKDIR)/test/test-async.c -CSRCS += $(LIBUV_UNPACKDIR)/test/test-ip4-addr.c -CSRCS += $(LIBUV_UNPACKDIR)/test/test-active.c -CSRCS += $(LIBUV_UNPACKDIR)/test/test-idle.c -CSRCS += $(LIBUV_UNPACKDIR)/test/test-timer.c -CSRCS += $(LIBUV_UNPACKDIR)/test/test-timer-from-check.c -CSRCS += $(LIBUV_UNPACKDIR)/test/test-timer-again.c -CSRCS += $(LIBUV_UNPACKDIR)/test/test-threadpool.c -CSRCS += $(LIBUV_UNPACKDIR)/test/test-walk-handles.c -CSRCS += $(LIBUV_UNPACKDIR)/test/test-poll-close.c -CSRCS += $(LIBUV_UNPACKDIR)/test/test-loop-close.c -CSRCS += $(LIBUV_UNPACKDIR)/test/test-loop-stop.c -CSRCS += $(LIBUV_UNPACKDIR)/test/test-tcp-read-stop.c -CSRCS += $(LIBUV_UNPACKDIR)/test/test-ping-pong.c -CSRCS += $(LIBUV_UNPACKDIR)/test/test-tcp-write-after-connect.c -CSRCS += $(LIBUV_UNPACKDIR)/test/test-fs-copyfile.c -CSRCS += $(LIBUV_UNPACKDIR)/test/test-fs-poll.c -ifeq ($(CONFIG_DEV_URANDOM),y) -CSRCS += $(LIBUV_UNPACKDIR)/test/test-random.c -endif -# Test helpers - -CSRCS += $(LIBUV_UNPACKDIR)/test/echo-server.c - -# Compilation flags - -CFLAGS += -I$(LIBUV_UNPACKDIR)/test -CFLAGS += -I. -CFLAGS += -D__NUTTX__ - -clean:: - $(call DELFILE, $(OBJS)) - -include $(APPDIR)/Application.mk diff --git a/system/libuv/tests/runner-nuttx.c b/system/libuv/tests/runner-nuttx.c deleted file mode 100644 index bb13455c1..000000000 --- a/system/libuv/tests/runner-nuttx.c +++ /dev/null @@ -1,152 +0,0 @@ -/**************************************************************************** - * apps/system/libuv/tests/runner-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. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include -#include -#include -#include - -#include -#include "runner-nuttx.h" -#include "runner.h" - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -static uint32_t get_time_ms(void); -static void *process_launcher(void *arg); - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -static uint32_t get_time_ms(void) -{ - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - return (uint32_t)(((uint64_t) ts.tv_sec) * 1000 + - (ts.tv_nsec / 1000 / 1000)); -} - -static void *process_launcher(void *arg) -{ - process_info_t *p = (process_info_t *)arg; - p->task->main(); - sem_post(&p->sem); - return NULL; -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -void platform_init(int argc, char **argv) -{ -} - -int process_start(task_entry_t *task, process_info_t *p, int is_helper) -{ - if (is_helper) - { - printf("===> START HELPER %s/%s\n", - task->task_name, task->process_name); - } - else - { - printf("===> START TEST %s\n", task->task_name); - } - - p->task = task; - - if (sem_init(&p->sem, 0, 0)) - { - return -1; - } - - if (pthread_create(&p->tid, NULL, process_launcher, p) != 0) - { - fprintf(stderr, "Failed to start process %s\n", task->process_name); - sem_destroy(&p->sem); - return -1; - } - - return 0; -} - -int process_wait(process_info_t *vec, int n, int timeout) -{ - uv_time_t time = get_time_ms(); - - while (--n >= 0) - { - int found = 0; - while ((uv_time_t)(get_time_ms()-time) < (uv_time_t)timeout) - { - if (sem_trywait(&vec[n].sem) == 0) - { - FAR pthread_addr_t value; - pthread_join(vec[n].tid, &value); - found = 1; - break; - } - - if (errno != EAGAIN) - { - break; - } - - /* Let NuttX update time */ - - usleep(100 * 1000); - } - - if (!found) - { - /* Timeout or error */ - - return -1; - } - } - - return 0; -} - -int process_terminate(process_info_t *p) -{ - /* TODO */ - - return 0; -} - -int process_reap(process_info_t *p) -{ - /* TODO */ - - return 0; -} - -void process_cleanup(process_info_t *p) -{ -} diff --git a/system/libuv/tests/runner-nuttx.h b/system/libuv/tests/runner-nuttx.h deleted file mode 100644 index c1f8f9f93..000000000 --- a/system/libuv/tests/runner-nuttx.h +++ /dev/null @@ -1,46 +0,0 @@ -/**************************************************************************** - * apps/system/libuv/tests/runner-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 TEST_RUNNER_NUTTX_H -#define TEST_RUNNER_NUTTX_H - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include -#include - -/**************************************************************************** - * Public Type Declarations - ****************************************************************************/ - -struct task_entry_s; - -struct process_info_s -{ - pthread_t tid; - sem_t sem; - struct task_entry_s *task; -}; - -typedef struct process_info_s process_info_t; - -#endif /* TEST_RUNNER_NUTTX_H */ diff --git a/system/libuv/tests/test_main.c b/system/libuv/tests/test_main.c deleted file mode 100644 index 067bb6fba..000000000 --- a/system/libuv/tests/test_main.c +++ /dev/null @@ -1,56 +0,0 @@ -/**************************************************************************** - * apps/system/libuv/tests/test_main.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. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include -#include -#include - -#include "runner.h" -#include "test-list.h" - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -int main(int argc, FAR char **argv) -{ - platform_init(argc, argv); - - if (argc > 1) - { - if (strcmp(argv[1], "--list") == 0) - { - print_tests(stdout); - return 0; - } - - if (argc > 2) - { - return run_test_part(argv[1], argv[2]); - } - } - - return run_tests(0); -} -