Commit d15664a5 authored by Jason Madden's avatar Jason Madden

Bump libuv to 1.21. Fixes #1244

parent 7420a0da
......@@ -7,6 +7,8 @@
1.3.5 (unreleased)
==================
- Update the bundled libuv from 1.20.1 to 1.21.0.
- Update Python versions tested on Travis, including PyPy to 6.0. See :issue:`1195`.
- :mod:`gevent.queue` imports ``_PySimpleQueue`` instead of
......
......@@ -336,3 +336,10 @@ Bob Burger <rgburger@beckman.com>
Thomas Versteeg <thomasversteeg@gmx.com>
zzzjim <zzzjim@users.noreply.github.com>
Alex Arslan <ararslan@comcast.net>
Kyle Farnung <kfarnung@microsoft.com>
ssrlive <30760636+ssrlive@users.noreply.github.com>
Tobias Nießen <tniessen@tnie.de>
Björn Linse <bjorn.linse@gmail.com>
zyxwvu Shi <i@shiyc.cn>
Peter Johnson <johnson.peter@gmail.com>
Paolo Greppi <paolo.greppi@libpf.com>
This diff is collapsed.
......@@ -137,7 +137,10 @@ $ git rebase upstream/v1.x # or upstream/master
### TEST
Bug fixes and features should come with tests. Add your tests in the
`test/` directory. Each new test needs to be registered in `test/test-list.h`. If you add a new test file, it needs to be registered in two places:
`test/` directory. Each new test needs to be registered in `test/test-list.h`.
If you add a new test file, it needs to be registered in three places:
- `CMakeLists.txt`: add the file's name to the `uv_test_sources` list.
- `Makefile.am`: add the file's name to the `test_run_tests_SOURCES` list.
- `uv.gyp`: add the file's name to the `sources` list in the `run-tests` target.
......
2018.04.19, Version 1.20.1 (Stable)
2018.06.23, Version 1.21.0 (Stable)
Changes since version 1.20.3:
* unix,windows: map EFTYPE errno (cjihrig)
* win: perform case insensitive PATH= comparison (cjihrig)
* win, fs: uv_fs_fchmod support for -A files (Bartosz Sosnowski)
* src,lib: fix comments (Tobias Nießen)
* win,process: allow child pipe handles to be opened in overlapped mode (Björn
Linse)
* src,test: fix idiosyncratic comment style (Bert Belder)
* test: fs_fchmod_archive_readonly must return a value (Bert Belder)
* win,pipe: fix incorrect error code returned from uv_pipe_write_impl() (Bert
Belder)
* win,pipe: properly set uv_write_t.send_handle in uv_write2() (Bert Belder)
* test: add vectored uv_write() ping-pong tests (Bert Belder)
* win,pipe: support vectored uv_write() calls (Bert Belder)
* win,pipe: refactor pipe read cancellation logic (Bert Belder)
* test: improve output from IPC test helpers (Bert Belder)
* test: add test for IPC deadlock on Windows (
* win,pipe: fix IPC pipe deadlock (Bert Belder)
* unix: catch some cases of watching fd twice (Ben Noordhuis)
* test: use custom timeout for getaddrinfo_fail_sync (Ben Noordhuis)
* Revert "win: add Windows XP support to uv_if_indextoname()" (Bert Belder)
* win,thread: remove fallback uv_cond implementation (Bert Belder)
* src,test: s/olny/only (cjihrig)
* unix: close signal pipe fds on unload (Ben Noordhuis)
* win: allow setting udp socket options before bind (cjihrig)
* unix: return UV_ENOTSUP on FICLONE_FORCE failure (cjihrig)
* win,pipe: remove unreferenced local variable (Bert Belder)
* win,code: remove GetQueuedCompletionStatus-based poller (Bert Belder)
* win: remove the remaining dynamic kernel32 imports (Bert Belder)
* test: speedup process-title-threadsafe on macOS (cjihrig)
* core: move all include files except uv.h to uv/ (Saúl Ibarra Corretgé)
* win: move stdint-msvc2008.h to include/uv/ (Ben Noordhuis)
* build: fix cygwin install (Ben Noordhuis)
* build,win: remove MinGW Makefile (Saúl Ibarra Corretgé)
* build: add a cmake build file (Ben Noordhuis)
* build: add test suite option to cmake build (Ben Noordhuis)
* unix: set errno in uv_fs_copyfile() (cjihrig)
* samples: fix inconsistency in parse_opts vs usage (zyxwvu Shi)
* linux: handle exclusive POLLHUP with UV_DISCONNECT (Brad King)
* include: declare uv_cpu_times_s in higher scope (Peter Johnson)
* doc: add uv_fs_fsync() AIX limitations (jBarz)
* unix,win: add uv_fs_lchown() (Paolo Greppi)
* unix: disable clang variable length array warning (Peter Johnson)
* doc: document uv_pipe_t::ipc (Ed Schouten)
* doc: undocument uv_req_type's UV_REQ_TYPE_PRIVATE (Ed Schouten)
* doc: document UV_*_MAP() macros (Ed Schouten)
* win: remove use of min() macro in pipe.c (Peter Johnson)
* doc: add jbarz as maintainer (
2018.05.08, Version 1.20.3 (Stable), 8cfd67e59195251dff793ee47c185c9d6a8f3818
Changes since version 1.20.2:
* win: add Windows XP support to uv_if_indextoname() (ssrlive)
* win: fix `'floor' undefined` compiler warning (ssrlive)
* win, pipe: stop read for overlapped pipe (Bartosz Sosnowski)
* build: fix utf-8 name of copyright holder (Jérémy Lal)
* zos: initialize pollfd revents (jBarz)
* zos,doc: add system V message queue note (jBarz)
* linux: don't use uv__nonblock_ioctl() on sparc (Ben Noordhuis)
2018.04.23, Version 1.20.2 (Stable), c51fd3f66bbb386a1efdeba6812789f35a372d1e
Changes since version 1.20.1:
* zos: use custom semaphore (jBarz)
* win: fix registry API error handling (Kyle Farnung)
* build: add support for 64-bit AIX (Richard Lau)
* aix: guard STATIC_ASSERT for glibc work around (Richard Lau)
2018.04.19, Version 1.20.1 (Stable), 36ac2fc8edfd5ff3e9be529be1d4a3f0d5364e94
Changes since version 1.20.0:
......
......@@ -14,6 +14,7 @@ libuv is currently managed by the following individuals:
- GPG key: AF2E EA41 EC34 47BF DD86 FED9 D706 3CCE 19B7 E890 (pubkey-indutny)
* **Imran Iqbal** ([@iWuzHere](https://github.com/iWuzHere))
- GPG key: 9DFE AA5F 481B BF77 2D90 03CE D592 4925 2F8E C41A (pubkey-iwuzhere)
* **John Barboza** ([@jbarz](https://github.com/jbarz))
* **Santiago Gimeno** ([@santigimeno](https://github.com/santigimeno))
- GPG key: 612F 0EAD 9401 6223 79DF 4402 F28C 3C8D A33C 03BE (pubkey-santigimeno)
* **Saúl Ibarra Corretgé** ([@saghul](https://github.com/saghul))
......
......@@ -17,7 +17,10 @@ ACLOCAL_AMFLAGS = -I m4
AM_CPPFLAGS = -I$(top_srcdir)/include \
-I$(top_srcdir)/src
include_HEADERS=include/uv.h include/uv-errno.h include/uv-threadpool.h include/uv-version.h
include_HEADERS=include/uv.h
uvincludedir = $(includedir)/uv
uvinclude_HEADERS=include/uv/errno.h include/uv/threadpool.h include/uv/version.h
CLEANFILES =
......@@ -42,7 +45,7 @@ endif
if WINNT
include_HEADERS += include/uv-win.h include/tree.h
uvinclude_HEADERS += include/uv/win.h include/uv/tree.h
AM_CPPFLAGS += -I$(top_srcdir)/src/win \
-DWIN32_LEAN_AND_MEAN \
-D_WIN32_WINNT=0x0600
......@@ -82,7 +85,7 @@ libuv_la_SOURCES += src/win/async.c \
else # WINNT
include_HEADERS += include/uv-unix.h
uvinclude_HEADERS += include/uv/unix.h
AM_CPPFLAGS += -I$(top_srcdir)/src/unix
libuv_la_SOURCES += src/unix/async.c \
src/unix/atomic-ops.h \
......@@ -121,7 +124,6 @@ EXTRA_DIST = test/fixtures/empty_file \
README.md \
checksparse.sh \
vcbuild.bat \
Makefile.mingw \
common.gypi \
gyp_uv.py \
uv.gyp
......@@ -191,6 +193,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-idle.c \
test/test-ip4-addr.c \
test/test-ip6-addr.c \
test/test-ipc-heavy-traffic-deadlock-bug.c \
test/test-ipc-send-recv.c \
test/test-ipc.c \
test/test-list.h \
......@@ -332,19 +335,19 @@ libuv_la_CFLAGS += -D_ALL_SOURCE \
-D_LINUX_SOURCE_COMPAT \
-D_THREAD_SAFE \
-DHAVE_SYS_AHAFS_EVPRODS_H
include_HEADERS += include/uv-aix.h
uvinclude_HEADERS += include/uv/aix.h
libuv_la_SOURCES += src/unix/aix.c src/unix/aix-common.c
endif
if ANDROID
include_HEADERS += include/android-ifaddrs.h \
include/pthread-barrier.h
uvinclude_HEADERS += include/uv/android-ifaddrs.h \
include/uv/pthread-barrier.h
libuv_la_SOURCES += src/unix/android-ifaddrs.c \
src/unix/pthread-fixes.c
endif
if CYGWIN
include_HEADERS += include/uv-posix.h
uvinclude_HEADERS += include/uv/posix.h
libuv_la_CFLAGS += -D_GNU_SOURCE
libuv_la_SOURCES += src/unix/cygwin.c \
src/unix/bsd-ifaddrs.c \
......@@ -358,8 +361,8 @@ libuv_la_SOURCES += src/unix/cygwin.c \
endif
if DARWIN
include_HEADERS += include/uv-darwin.h \
include/pthread-barrier.h
uvinclude_HEADERS += include/uv/darwin.h \
include/uv/pthread-barrier.h
libuv_la_CFLAGS += -D_DARWIN_USE_64_BIT_INODE=1
libuv_la_CFLAGS += -D_DARWIN_UNLIMITED_SELECT=1
libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \
......@@ -372,7 +375,7 @@ test_run_tests_LDFLAGS += -lutil
endif
if DRAGONFLY
include_HEADERS += include/uv-bsd.h
uvinclude_HEADERS += include/uv/bsd.h
libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \
src/unix/freebsd.c \
src/unix/kqueue.c \
......@@ -381,7 +384,7 @@ test_run_tests_LDFLAGS += -lutil
endif
if FREEBSD
include_HEADERS += include/uv-bsd.h
uvinclude_HEADERS += include/uv/bsd.h
libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \
src/unix/freebsd.c \
src/unix/kqueue.c \
......@@ -390,7 +393,7 @@ test_run_tests_LDFLAGS += -lutil
endif
if LINUX
include_HEADERS += include/uv-linux.h
uvinclude_HEADERS += include/uv/linux.h
libuv_la_CFLAGS += -D_GNU_SOURCE
libuv_la_SOURCES += src/unix/linux-core.c \
src/unix/linux-inotify.c \
......@@ -417,7 +420,7 @@ libuv_la_SOURCES += src/unix/cygwin.c \
endif
if NETBSD
include_HEADERS += include/uv-bsd.h
uvinclude_HEADERS += include/uv/bsd.h
libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \
src/unix/kqueue.c \
src/unix/netbsd.c \
......@@ -426,7 +429,7 @@ test_run_tests_LDFLAGS += -lutil
endif
if OPENBSD
include_HEADERS += include/uv-bsd.h
uvinclude_HEADERS += include/uv/bsd.h
libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \
src/unix/kqueue.c \
src/unix/openbsd.c \
......@@ -435,14 +438,14 @@ test_run_tests_LDFLAGS += -lutil
endif
if SUNOS
include_HEADERS += include/uv-sunos.h
uvinclude_HEADERS += include/uv/sunos.h
libuv_la_CFLAGS += -D__EXTENSIONS__ -D_XOPEN_SOURCE=500
libuv_la_SOURCES += src/unix/no-proctitle.c \
src/unix/sunos.c
endif
if OS390
include_HEADERS += include/pthread-barrier.h
uvinclude_HEADERS += include/uv/pthread-barrier.h
libuv_la_CFLAGS += -D_UNIX03_THREADS \
-D_UNIX03_SOURCE \
-D_OPEN_SYS_IF_EXT=1 \
......
# Copyright (c) 2013, Ben Noordhuis <info@bnoordhuis.nl>
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
CC ?= gcc
CFLAGS += -Wall \
-Wextra \
-Wno-unused-parameter \
-Wstrict-prototypes \
-Iinclude \
-Isrc \
-Isrc/win \
-DWIN32_LEAN_AND_MEAN \
-D_WIN32_WINNT=0x0600
INCLUDES = include/stdint-msvc2008.h \
include/tree.h \
include/uv-errno.h \
include/uv-threadpool.h \
include/uv-version.h \
include/uv-win.h \
include/uv.h \
src/heap-inl.h \
src/queue.h \
src/uv-common.h \
src/win/atomicops-inl.h \
src/win/handle-inl.h \
src/win/internal.h \
src/win/req-inl.h \
src/win/stream-inl.h \
src/win/winapi.h \
src/win/winsock.h
OBJS = src/fs-poll.o \
src/inet.o \
src/threadpool.o \
src/uv-common.o \
src/version.o \
src/win/async.o \
src/win/core.o \
src/win/detect-wakeup.o \
src/win/dl.o \
src/win/error.o \
src/win/fs-event.o \
src/win/fs.o \
src/win/getaddrinfo.o \
src/win/getnameinfo.o \
src/win/handle.o \
src/win/loop-watcher.o \
src/win/pipe.o \
src/win/poll.o \
src/win/process-stdio.o \
src/win/process.o \
src/win/req.o \
src/win/signal.o \
src/win/stream.o \
src/win/tcp.o \
src/win/thread.o \
src/win/timer.o \
src/win/tty.o \
src/win/udp.o \
src/win/util.o \
src/win/winapi.o \
src/win/winsock.o
all: libuv.a
clean:
-$(RM) $(OBJS) libuv.a
libuv.a: $(OBJS)
$(AR) crs $@ $^
$(OBJS): %.o : %.c $(INCLUDES)
$(CC) $(CFLAGS) -c -o $@ $<
......@@ -169,6 +169,16 @@ $ make check
$ make install
```
To build with [CMake](https://cmake.org/):
```bash
$ mkdir -p out/cmake ; cd out/cmake ; cmake -DBUILD_TESTING=ON ../..
$ make all test
# Or manually:
$ ./uv_run_tests # shared library build
$ ./uv_run_tests_a # static library build
```
To build with GYP, first run:
```bash
......@@ -322,6 +332,13 @@ describes the package in more detail.
AIX support for filesystem events is not compiled when building with `gyp`.
### z/OS Notes
z/OS creates System V semaphores and message queues. These persist on the system
after the process terminates unless the event loop is closed.
Use the `ipcrm` command to manually clear up System V resources.
## Patches
See the [guidelines for contributing][].
......
......@@ -26,8 +26,8 @@ SPARSE_FLAGS=${SPARSE_FLAGS:-"
"}
SOURCES="
include/tree.h
include/uv-unix.h
include/uv/tree.h
include/uv/unix.h
include/uv.h
src/fs-poll.c
src/inet.c
......@@ -113,6 +113,7 @@ test/test-homedir.c
test/test-hrtime.c
test/test-idle.c
test/test-ip6-addr.c
test/test-ipc-heavy-traffic-deadlock-bug.c
test/test-ipc-send-recv.c
test/test-ipc.c
test/test-loop-handles.c
......@@ -195,7 +196,7 @@ OS400)
Darwin)
SPARSE_FLAGS="$SPARSE_FLAGS -D__APPLE__=1"
SOURCES="$SOURCES
include/uv-bsd.h
include/uv/bsd.h
src/unix/darwin.c
src/unix/kqueue.c
src/unix/fsevents.c"
......@@ -203,21 +204,21 @@ Darwin)
DragonFly)
SPARSE_FLAGS="$SPARSE_FLAGS -D__DragonFly__=1"
SOURCES="$SOURCES
include/uv-bsd.h
include/uv/bsd.h
src/unix/kqueue.c
src/unix/freebsd.c"
;;
FreeBSD)
SPARSE_FLAGS="$SPARSE_FLAGS -D__FreeBSD__=1"
SOURCES="$SOURCES
include/uv-bsd.h
include/uv/bsd.h
src/unix/kqueue.c
src/unix/freebsd.c"
;;
Linux)
SPARSE_FLAGS="$SPARSE_FLAGS -D__linux__=1"
SOURCES="$SOURCES
include/uv-linux.h
include/uv/linux.h
src/unix/linux-inotify.c
src/unix/linux-core.c
src/unix/linux-syscalls.c
......@@ -226,21 +227,21 @@ Linux)
NetBSD)
SPARSE_FLAGS="$SPARSE_FLAGS -D__NetBSD__=1"
SOURCES="$SOURCES
include/uv-bsd.h
include/uv/bsd.h
src/unix/kqueue.c
src/unix/netbsd.c"
;;
OpenBSD)
SPARSE_FLAGS="$SPARSE_FLAGS -D__OpenBSD__=1"
SOURCES="$SOURCES
include/uv-bsd.h
include/uv/bsd.h
src/unix/kqueue.c
src/unix/openbsd.c"
;;
SunOS)
SPARSE_FLAGS="$SPARSE_FLAGS -D__sun=1"
SOURCES="$SOURCES
include/uv-sunos.h
include/uv/sunos.h
src/unix/sunos.c"
;;
esac
......
......@@ -134,7 +134,7 @@
}]
]
}],
['OS in "freebsd dragonflybsd linux openbsd solaris android"', {
['OS in "freebsd dragonflybsd linux openbsd solaris android aix"', {
'cflags': [ '-Wall' ],
'cflags_cc': [ '-fno-rtti', '-fno-exceptions' ],
'target_conditions': [
......@@ -162,6 +162,10 @@
'cflags': [ '-pthread' ],
'ldflags': [ '-pthread' ],
}],
[ 'OS=="aix" and target_arch=="ppc64"', {
'cflags': [ '-maix64' ],
'ldflags': [ '-maix64' ],
}],
],
}],
['OS=="mac"', {
......
......@@ -13,7 +13,7 @@
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
AC_PREREQ(2.57)
AC_INIT([libuv], [1.20.1], [https://github.com/libuv/libuv/issues])
AC_INIT([libuv], [1.21.0], [https://github.com/libuv/libuv/issues])
AC_CONFIG_MACRO_DIR([m4])
m4_include([m4/libuv-extra-automake-flags.m4])
m4_include([m4/as_case.m4])
......
......@@ -45,21 +45,21 @@ extern "C" {
# define UV_EXTERN /* nothing */
#endif
#include "uv-errno.h"
#include "uv-version.h"
#include "uv/errno.h"
#include "uv/version.h"
#include <stddef.h>
#include <stdio.h>
#if defined(_MSC_VER) && _MSC_VER < 1600
# include "stdint-msvc2008.h"
# include "uv/stdint-msvc2008.h"
#else
# include <stdint.h>
#endif
#if defined(_WIN32)
# include "uv-win.h"
# include "uv/win.h"
#else
# include "uv-unix.h"
# include "uv/unix.h"
#endif
/* Expand this list if necessary. */
......@@ -142,6 +142,7 @@ extern "C" {
XX(EHOSTDOWN, "host is down") \
XX(EREMOTEIO, "remote I/O error") \
XX(ENOTTY, "inappropriate ioctl for device") \
XX(EFTYPE, "inappropriate file type or format") \
#define UV_HANDLE_TYPE_MAP(XX) \
XX(ASYNC, async) \
......@@ -503,7 +504,7 @@ UV_EXTERN int uv_try_write(uv_stream_t* handle,
struct uv_write_s {
UV_REQ_FIELDS
uv_write_cb cb;
uv_stream_t* send_handle;
uv_stream_t* send_handle; /* TODO: make private and unix-only in v2.x. */
uv_stream_t* handle;
UV_WRITE_PRIVATE_FIELDS
};
......@@ -865,7 +866,13 @@ typedef enum {
* flags may be specified to create a duplex data stream.
*/
UV_READABLE_PIPE = 0x10,
UV_WRITABLE_PIPE = 0x20
UV_WRITABLE_PIPE = 0x20,
/*
* Open the child pipe handle in overlapped mode on Windows.
* On Unix it is silently ignored.
*/
UV_OVERLAPPED_PIPE = 0x40
} uv_stdio_flags;
typedef struct uv_stdio_container_s {
......@@ -997,16 +1004,18 @@ UV_EXTERN int uv_queue_work(uv_loop_t* loop,
UV_EXTERN int uv_cancel(uv_req_t* req);
struct uv_cpu_times_s {
uint64_t user;
uint64_t nice;
uint64_t sys;
uint64_t idle;
uint64_t irq;
};
struct uv_cpu_info_s {
char* model;
int speed;
struct uv_cpu_times_s {
uint64_t user;
uint64_t nice;
uint64_t sys;
uint64_t idle;
uint64_t irq;
} cpu_times;
struct uv_cpu_times_s cpu_times;
};
struct uv_interface_address_s {
......@@ -1132,6 +1141,7 @@ typedef enum {
UV_FS_READLINK,
UV_FS_CHOWN,
UV_FS_FCHOWN,
UV_FS_LCHOWN,
UV_FS_REALPATH,
UV_FS_COPYFILE
} uv_fs_type;
......@@ -1336,6 +1346,12 @@ UV_EXTERN int uv_fs_fchown(uv_loop_t* loop,
uv_uid_t uid,
uv_gid_t gid,
uv_fs_cb cb);
UV_EXTERN int uv_fs_lchown(uv_loop_t* loop,
uv_fs_t* req,
const char* path,
uv_uid_t uid,
uv_gid_t gid,
uv_fs_cb cb);
enum uv_fs_event {
......
......@@ -433,5 +433,11 @@
# define UV__ENOTTY (-4029)
#endif
#if defined(EFTYPE) && !defined(_WIN32)
# define UV__EFTYPE UV__ERR(EFTYPE)
#else
# define UV__EFTYPE (-4028)
#endif
#endif /* UV_ERRNO_H_ */
......@@ -22,7 +22,7 @@
#ifndef UV_MVS_H
#define UV_MVS_H
#define UV_PLATFORM_SEM_T int
#define UV_PLATFORM_SEM_T long
#define UV_PLATFORM_LOOP_FIELDS \
void* ep; \
......
......@@ -42,32 +42,32 @@
#include <pthread.h>
#include <signal.h>
#include "uv-threadpool.h"
#include "uv/threadpool.h"
#if defined(__linux__)
# include "uv-linux.h"
# include "uv/linux.h"
#elif defined (__MVS__)
# include "uv-os390.h"
# include "uv/os390.h"
#elif defined(__PASE__)
# include "uv-posix.h"
# include "uv/posix.h"
#elif defined(_AIX)
# include "uv-aix.h"
# include "uv/aix.h"
#elif defined(__sun)
# include "uv-sunos.h"
# include "uv/sunos.h"
#elif defined(__APPLE__)
# include "uv-darwin.h"
# include "uv/darwin.h"
#elif defined(__DragonFly__) || \
defined(__FreeBSD__) || \
defined(__FreeBSD_kernel__) || \
defined(__OpenBSD__) || \
defined(__NetBSD__)
# include "uv-bsd.h"
# include "uv/bsd.h"
#elif defined(__CYGWIN__) || defined(__MSYS__)
# include "uv-posix.h"
# include "uv/posix.h"
#endif
#ifndef PTHREAD_BARRIER_SERIAL_THREAD
# include "pthread-barrier.h"
# include "uv/pthread-barrier.h"
#endif
#ifndef NI_MAXHOST
......
......@@ -31,8 +31,8 @@
*/
#define UV_VERSION_MAJOR 1
#define UV_VERSION_MINOR 20
#define UV_VERSION_PATCH 1
#define UV_VERSION_MINOR 21
#define UV_VERSION_PATCH 0
#define UV_VERSION_IS_RELEASE 1
#define UV_VERSION_SUFFIX ""
......
......@@ -53,13 +53,13 @@ typedef struct pollfd {
#include <sys/stat.h>
#if defined(_MSC_VER) && _MSC_VER < 1600
# include "stdint-msvc2008.h"
# include "uv/stdint-msvc2008.h"
#else
# include <stdint.h>
#endif
#include "tree.h"
#include "uv-threadpool.h"
#include "uv/tree.h"
#include "uv/threadpool.h"
#define MAX_PIPENAME_LEN 256
......@@ -86,8 +86,8 @@ typedef struct pollfd {
#define SIGKILL 9
#define SIGWINCH 28
/* The CRT defines SIGABRT_COMPAT as 6, which equals SIGABRT on many */
/* unix-like platforms. However MinGW doesn't define it, so we do. */
/* The CRT defines SIGABRT_COMPAT as 6, which equals SIGABRT on many unix-like
* platforms. However MinGW doesn't define it, so we do. */
#ifndef SIGABRT_COMPAT
# define SIGABRT_COMPAT 6
#endif
......@@ -244,7 +244,7 @@ typedef union {
CRITICAL_SECTION waiters_count_lock;
HANDLE signal_event;
HANDLE broadcast_event;
} fallback;
} unused_; /* TODO: retained for ABI compatibility; remove me in v2.x. */
} uv_cond_t;
typedef union {
......@@ -368,10 +368,10 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
} u; \
struct uv_req_s* next_req;
#define UV_WRITE_PRIVATE_FIELDS \
int ipc_header; \
uv_buf_t write_buffer; \
HANDLE event_handle; \
#define UV_WRITE_PRIVATE_FIELDS \
int coalesced; \
uv_buf_t write_buffer; \
HANDLE event_handle; \
HANDLE wait_handle;
#define UV_CONNECT_PRIVATE_FIELDS \
......@@ -459,16 +459,17 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
#define uv_pipe_connection_fields \
uv_timer_t* eof_timer; \
uv_write_t ipc_header_write_req; \
int ipc_pid; \
uint64_t remaining_ipc_rawdata_bytes; \
struct { \
void* queue[2]; \
int queue_len; \
} pending_ipc_info; \
uv_write_t dummy; /* TODO: retained for ABI compat; remove this in v2.x. */ \
DWORD ipc_remote_pid; \
union { \
uint32_t payload_remaining; \
uint64_t dummy; /* TODO: retained for ABI compat; remove this in v2.x. */ \
} ipc_data_frame; \
void* ipc_xfer_queue[2]; \
int ipc_xfer_queue_length; \
uv_write_t* non_overlapped_writes_tail; \
uv_mutex_t readfile_mutex; \
volatile HANDLE readfile_thread;
CRITICAL_SECTION readfile_thread_lock; \
volatile HANDLE readfile_thread_handle;
#define UV_PIPE_PRIVATE_FIELDS \
HANDLE handle; \
......@@ -478,8 +479,8 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
struct { uv_pipe_connection_fields } conn; \
} pipe;
/* TODO: put the parser states in an union - TTY handles are always */
/* half-duplex so read-state can safely overlap write-state. */
/* TODO: put the parser states in an union - TTY handles are always half-duplex
* so read-state can safely overlap write-state. */
#define UV_TTY_PRIVATE_FIELDS \
HANDLE handle; \
union { \
......
......@@ -3,7 +3,7 @@ exec_prefix=${prefix}
libdir=@libdir@
includedir=@includedir@
Name: @PACKAGE_NAME@
Name: libuv
Version: @PACKAGE_VERSION@
Description: multi-platform support library with a focus on asynchronous I/O.
URL: http://libuv.org/
......
dnl Macros to check the presence of generic (non-typed) symbols.
dnl Copyright (c) 2006-2008 Diego Pettenà <flameeyes gmail com>
dnl Copyright (c) 2006-2008 Diego Pettenò <flameeyes gmail com>
dnl Copyright (c) 2006-2008 xine project
dnl
dnl This program is free software; you can redistribute it and/or modify
......@@ -316,4 +316,4 @@ AC_DEFUN([CC_ATTRIBUTE_ALIGNED], [
AC_DEFINE_UNQUOTED([ATTRIBUTE_ALIGNED_MAX], [$cc_cv_attribute_aligned],
[Define the highest alignment supported])
fi
])
\ No newline at end of file
])
......@@ -19,7 +19,7 @@
#include <string.h>
#if defined(_MSC_VER) && _MSC_VER < 1600
# include "stdint-msvc2008.h"
# include "uv/stdint-msvc2008.h"
#else
# include <stdint.h>
#endif
......
......@@ -23,7 +23,7 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "android-ifaddrs.h"
#include "uv/android-ifaddrs.h"
#include "uv-common.h"
#include <string.h>
......
......@@ -174,8 +174,8 @@ void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
case UV_SIGNAL:
uv__signal_close((uv_signal_t*) handle);
/* Signal handles may not be closed immediately. The signal code will */
/* itself close uv__make_close_pending whenever appropriate. */
/* Signal handles may not be closed immediately. The signal code will
* itself close uv__make_close_pending whenever appropriate. */
return;
default:
......@@ -927,6 +927,11 @@ int uv__io_active(const uv__io_t* w, unsigned int events) {
}
int uv__fd_exists(uv_loop_t* loop, int fd) {
return (unsigned) fd < loop->nwatchers && loop->watchers[fd] != NULL;
}
int uv_getrusage(uv_rusage_t* rusage) {
struct rusage usage;
......
......@@ -865,9 +865,11 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) {
/* If an error occurred that the sendfile fallback also won't handle, or
this is a force clone then exit. Otherwise, fall through to try using
sendfile(). */
if ((errno != ENOTTY && errno != EOPNOTSUPP && errno != EXDEV) ||
req->flags & UV_FS_COPYFILE_FICLONE_FORCE) {
err = -errno;
if (errno != ENOTTY && errno != EOPNOTSUPP && errno != EXDEV) {
err = UV__ERR(errno);
goto out;
} else if (req->flags & UV_FS_COPYFILE_FICLONE_FORCE) {
err = UV_ENOTSUP;
goto out;
}
} else {
......@@ -927,7 +929,11 @@ out:
}
}
return result;
if (result == 0)
return 0;
errno = UV__ERR(result);
return -1;
#endif
}
......@@ -1114,6 +1120,7 @@ static void uv__fs_work(struct uv__work* w) {
X(COPYFILE, uv__fs_copyfile(req));
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));
X(FDATASYNC, uv__fs_fdatasync(req));
X(FSTAT, uv__fs_fstat(req->file, &req->statbuf));
X(FSYNC, uv__fs_fsync(req));
......@@ -1240,6 +1247,20 @@ int uv_fs_fchown(uv_loop_t* loop,
}
int uv_fs_lchown(uv_loop_t* loop,
uv_fs_t* req,
const char* path,
uv_uid_t uid,
uv_gid_t gid,
uv_fs_cb cb) {
INIT(LCHOWN);
PATH;
req->uid = uid;
req->gid = gid;
POST;
}
int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
INIT(FDATASYNC);
req->file = file;
......
......@@ -185,6 +185,18 @@ struct uv__stream_queued_fds_s {
#define uv__nonblock uv__nonblock_fcntl
#endif
/* On Linux, uv__nonblock_fcntl() and uv__nonblock_ioctl() do not commute
* when O_NDELAY is not equal to O_NONBLOCK. Case in point: linux/sparc32
* and linux/sparc64, where O_NDELAY is O_NONBLOCK + another bit.
*
* Libuv uses uv__nonblock_fcntl() directly sometimes so ensure that it
* commutes with uv__nonblock().
*/
#if defined(__linux__) && O_NDELAY != O_NONBLOCK
#undef uv__nonblock
#define uv__nonblock uv__nonblock_fcntl
#endif
/* core */
int uv__cloexec_ioctl(int fd, int set);
int uv__cloexec_fcntl(int fd, int set);
......@@ -207,6 +219,7 @@ 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 */
int uv__io_fork(uv_loop_t* loop);
int uv__fd_exists(uv_loop_t* loop, int fd);
/* async */
void uv__async_stop(uv_loop_t* loop);
......
......@@ -261,8 +261,8 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
w = loop->watchers[fd];
if (w == NULL) {
/* File descriptor that we've stopped watching, disarm it. */
/* TODO batch up */
/* File descriptor that we've stopped watching, disarm it.
* TODO: batch up. */
struct kevent events[1];
EV_SET(events + 0, fd, ev->filter, EV_DELETE, 0, 0, 0);
......
......@@ -51,7 +51,7 @@
#ifdef HAVE_IFADDRS_H
# if defined(__ANDROID__)
# include "android-ifaddrs.h"
# include "uv/android-ifaddrs.h"
# else
# include <ifaddrs.h>
# endif
......@@ -388,7 +388,8 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
* free when we switch over to edge-triggered I/O.
*/
if (pe->events == POLLERR || pe->events == POLLHUP)
pe->events |= w->pevents & (POLLIN | POLLOUT | UV__POLLPRI);
pe->events |=
w->pevents & (POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI);
if (pe->events != 0) {
/* Run signal watchers last. This also affects child process watchers
......
......@@ -19,7 +19,7 @@
*/
#include "uv.h"
#include "tree.h"
#include "uv/tree.h"
#include "internal.h"
#include <stdint.h>
......
......@@ -20,7 +20,7 @@
*/
#include "uv.h"
#include "tree.h"
#include "uv/tree.h"
#include "internal.h"
#include "heap-inl.h"
#include <stdlib.h>
......
......@@ -215,6 +215,7 @@ uv__os390_epoll* epoll_create1(int flags) {
maybe_resize(lst, 1);
lst->items[lst->size - 1].fd = lst->msg_queue;
lst->items[lst->size - 1].events = POLLIN;
lst->items[lst->size - 1].revents = 0;
uv_once(&once, epoll_init);
uv_mutex_lock(&global_epoll_lock);
QUEUE_INSERT_TAIL(&global_epoll_queue, &lst->member);
......@@ -252,6 +253,7 @@ int epoll_ctl(uv__os390_epoll* lst,
}
lst->items[fd].fd = fd;
lst->items[fd].events = event->events;
lst->items[fd].revents = 0;
} else if (op == EPOLL_CTL_MOD) {
if (fd >= lst->size || lst->items[fd].fd == -1) {
uv_mutex_unlock(&global_epoll_lock);
......
......@@ -134,6 +134,9 @@ void uv__pipe_close(uv_pipe_t* handle) {
int uv_pipe_open(uv_pipe_t* handle, uv_file fd) {
int err;
if (uv__fd_exists(handle->loop, fd))
return UV_EEXIST;
err = uv__nonblock(fd, 1);
if (err)
return err;
......
......@@ -68,6 +68,9 @@ static void uv__poll_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) {
int err;
if (uv__fd_exists(loop, fd))
return UV_EEXIST;
err = uv__io_check_fd(loop, fd);
if (err)
return err;
......
......@@ -54,8 +54,7 @@ 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];
static int uv__signal_lock_pipefd[2] = { -1, -1 };
RB_GENERATE_STATIC(uv__signal_tree_s,
uv_signal_s, tree_entry,
......@@ -64,7 +63,7 @@ RB_GENERATE_STATIC(uv__signal_tree_s,
static void uv__signal_global_reinit(void);
static void uv__signal_global_init(void) {
if (!uv__signal_lock_pipefd[0])
if (uv__signal_lock_pipefd[0] == -1)
/* pthread_atfork can register before and after handlers, one
* for each child. This only registers one for the child. That
* state is both persistent and cumulative, so if we keep doing
......@@ -74,15 +73,11 @@ static void uv__signal_global_init(void) {
if (pthread_atfork(NULL, NULL, &uv__signal_global_reinit))
abort();
if (uv__make_pipe(uv__signal_lock_pipefd, 0))
abort();
if (uv__signal_unlock())
abort();
uv__signal_global_reinit();
}
static void uv__signal_global_reinit(void) {
UV_DESTRUCTOR(static void uv__signal_global_fini(void)) {
/* We can only use signal-safe functions here.
* That includes read/write and close, fortunately.
* We do all of this directly here instead of resetting
......@@ -90,11 +85,26 @@ static void uv__signal_global_reinit(void) {
* uv__signal_global_once_init is only called from uv_loop_init
* and this needs to function in existing loops.
*/
uv__close(uv__signal_lock_pipefd[0]);
uv__signal_lock_pipefd[0] = -1;
uv__close(uv__signal_lock_pipefd[1]);
uv__signal_lock_pipefd[1] = -1;
uv__signal_global_init();
if (uv__signal_lock_pipefd[0] != -1) {
uv__close(uv__signal_lock_pipefd[0]);
uv__signal_lock_pipefd[0] = -1;
}
if (uv__signal_lock_pipefd[1] != -1) {
uv__close(uv__signal_lock_pipefd[1]);
uv__signal_lock_pipefd[1] = -1;
}
}
static void uv__signal_global_reinit(void) {
uv__signal_global_fini();
if (uv__make_pipe(uv__signal_lock_pipefd, 0))
abort();
if (uv__signal_unlock())
abort();
}
......@@ -103,7 +113,6 @@ void uv__signal_global_once_init(void) {
}
static int uv__signal_lock(void) {
int r;
char data;
......
......@@ -1121,6 +1121,7 @@ static int uv__stream_recv_cmsg(uv_stream_t* stream, struct msghdr* msg) {
#ifdef __clang__
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wgnu-folding-constant"
# pragma clang diagnostic ignored "-Wvla-extension"
#endif
static void uv__read(uv_stream_t* stream) {
......@@ -1311,7 +1312,7 @@ static void uv__stream_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
assert(uv__stream_fd(stream) >= 0);
/* Ignore POLLHUP here. Even it it's set, there may still be data to read. */
/* Ignore POLLHUP here. Even if it's set, there may still be data to read. */
if (events & (POLLIN | POLLERR | POLLHUP))
uv__read(stream);
......
......@@ -263,6 +263,9 @@ int uv__tcp_connect(uv_connect_t* req,
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;
......
......@@ -423,87 +423,6 @@ int uv_sem_trywait(uv_sem_t* sem) {
return UV_EINVAL; /* Satisfy the compiler. */
}
#elif defined(__MVS__)
int uv_sem_init(uv_sem_t* sem, unsigned int value) {
uv_sem_t semid;
int err;
union {
int val;
struct semid_ds* buf;
unsigned short* array;
} arg;
semid = semget(IPC_PRIVATE, 1, S_IRUSR | S_IWUSR);
if (semid == -1)
return UV__ERR(errno);
arg.val = value;
if (-1 == semctl(semid, 0, SETVAL, arg)) {
err = errno;
if (-1 == semctl(*sem, 0, IPC_RMID))
abort();
return UV__ERR(err);
}
*sem = semid;
return 0;
}
void uv_sem_destroy(uv_sem_t* sem) {
if (-1 == semctl(*sem, 0, IPC_RMID))
abort();
}
void uv_sem_post(uv_sem_t* sem) {
struct sembuf buf;
buf.sem_num = 0;
buf.sem_op = 1;
buf.sem_flg = 0;
if (-1 == semop(*sem, &buf, 1))
abort();
}
void uv_sem_wait(uv_sem_t* sem) {
struct sembuf buf;
int op_status;
buf.sem_num = 0;
buf.sem_op = -1;
buf.sem_flg = 0;
do
op_status = semop(*sem, &buf, 1);
while (op_status == -1 && errno == EINTR);
if (op_status)
abort();
}
int uv_sem_trywait(uv_sem_t* sem) {
struct sembuf buf;
int op_status;
buf.sem_num = 0;
buf.sem_op = -1;
buf.sem_flg = IPC_NOWAIT;
do
op_status = semop(*sem, &buf, 1);
while (op_status == -1 && errno == EINTR);
if (op_status) {
if (errno == EAGAIN)
return UV_EAGAIN;
abort();
}
return 0;
}
#else /* !(defined(__APPLE__) && defined(__MACH__)) */
#ifdef __GLIBC__
......@@ -517,18 +436,22 @@ int uv_sem_trywait(uv_sem_t* sem) {
* a pointer to the actual struct we're using underneath. */
static uv_once_t glibc_version_check_once = UV_ONCE_INIT;
static int glibc_needs_custom_semaphore = 0;
static int platform_needs_custom_semaphore = 0;
static void glibc_version_check(void) {
const char* version = gnu_get_libc_version();
glibc_needs_custom_semaphore =
platform_needs_custom_semaphore =
version[0] == '2' && version[1] == '.' &&
atoi(version + 2) < 21;
}
#else /* !defined(__GLIBC__) */
#elif defined(__MVS__)
#define platform_needs_custom_semaphore 1
#define glibc_needs_custom_semaphore 0
#else /* !defined(__GLIBC__) && !defined(__MVS__) */
#define platform_needs_custom_semaphore 0
#endif
......@@ -538,8 +461,9 @@ typedef struct uv_semaphore_s {
unsigned int value;
} uv_semaphore_t;
#if defined(__GLIBC__) || platform_needs_custom_semaphore
STATIC_ASSERT(sizeof(uv_sem_t) >= sizeof(uv_semaphore_t*));
#endif
static int uv__custom_sem_init(uv_sem_t* sem_, unsigned int value) {
int err;
......@@ -670,7 +594,7 @@ int uv_sem_init(uv_sem_t* sem, unsigned int value) {
uv_once(&glibc_version_check_once, glibc_version_check);
#endif
if (glibc_needs_custom_semaphore)
if (platform_needs_custom_semaphore)
return uv__custom_sem_init(sem, value);
else
return uv__sem_init(sem, value);
......@@ -678,7 +602,7 @@ int uv_sem_init(uv_sem_t* sem, unsigned int value) {
void uv_sem_destroy(uv_sem_t* sem) {
if (glibc_needs_custom_semaphore)
if (platform_needs_custom_semaphore)
uv__custom_sem_destroy(sem);
else
uv__sem_destroy(sem);
......@@ -686,7 +610,7 @@ void uv_sem_destroy(uv_sem_t* sem) {
void uv_sem_post(uv_sem_t* sem) {
if (glibc_needs_custom_semaphore)
if (platform_needs_custom_semaphore)
uv__custom_sem_post(sem);
else
uv__sem_post(sem);
......@@ -694,7 +618,7 @@ void uv_sem_post(uv_sem_t* sem) {
void uv_sem_wait(uv_sem_t* sem) {
if (glibc_needs_custom_semaphore)
if (platform_needs_custom_semaphore)
uv__custom_sem_wait(sem);
else
uv__sem_wait(sem);
......@@ -702,7 +626,7 @@ void uv_sem_wait(uv_sem_t* sem) {
int uv_sem_trywait(uv_sem_t* sem) {
if (glibc_needs_custom_semaphore)
if (platform_needs_custom_semaphore)
return uv__custom_sem_trywait(sem);
else
return uv__sem_trywait(sem);
......
......@@ -624,6 +624,9 @@ int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
if (handle->io_watcher.fd != -1)
return UV_EBUSY;
if (uv__fd_exists(handle->loop, sock))
return UV_EEXIST;
err = uv__nonblock(sock, 1);
if (err)
return err;
......
......@@ -32,13 +32,13 @@
#include <stddef.h>
#if defined(_MSC_VER) && _MSC_VER < 1600
# include "stdint-msvc2008.h"
# include "uv/stdint-msvc2008.h"
#else
# include <stdint.h>
#endif
#include "uv.h"
#include "tree.h"
#include "uv/tree.h"
#include "queue.h"
#if EDOM > 0
......
......@@ -71,8 +71,8 @@ int uv_async_send(uv_async_t* handle) {
return -1;
}
/* The user should make sure never to call uv_async_send to a closing */
/* or closed handle. */
/* The user should make sure never to call uv_async_send to a closing or
* closed handle. */
assert(!(handle->flags & UV__HANDLE_CLOSING));
if (!uv__atomic_exchange_set(&handle->async_sent)) {
......
......@@ -29,10 +29,10 @@
/* Atomic set operation on char */
#ifdef _MSC_VER /* MSVC */
/* _InterlockedOr8 is supported by MSVC on x32 and x64. It is slightly less */
/* efficient than InterlockedExchange, but InterlockedExchange8 does not */
/* exist, and interlocked operations on larger targets might require the */
/* target to be aligned. */
/* _InterlockedOr8 is supported by MSVC on x32 and x64. It is slightly less
* efficient than InterlockedExchange, but InterlockedExchange8 does not exist,
* and interlocked operations on larger targets might require the target to be
* aligned. */
#pragma intrinsic(_InterlockedOr8)
static char INLINE uv__atomic_exchange_set(char volatile* target) {
......
......@@ -359,58 +359,7 @@ int uv_backend_timeout(const uv_loop_t* loop) {
}
static void uv_poll(uv_loop_t* loop, DWORD timeout) {
DWORD bytes;
ULONG_PTR key;
OVERLAPPED* overlapped;
uv_req_t* req;
int repeat;
uint64_t timeout_time;
timeout_time = loop->time + timeout;
for (repeat = 0; ; repeat++) {
GetQueuedCompletionStatus(loop->iocp,
&bytes,
&key,
&overlapped,
timeout);
if (overlapped) {
/* Package was dequeued */
req = uv_overlapped_to_req(overlapped);
uv_insert_pending_req(loop, req);
/* Some time might have passed waiting for I/O,
* so update the loop time here.
*/
uv_update_time(loop);
} else if (GetLastError() != WAIT_TIMEOUT) {
/* Serious error */
uv_fatal_error(GetLastError(), "GetQueuedCompletionStatus");
} else if (timeout > 0) {
/* GetQueuedCompletionStatus can occasionally return a little early.
* Make sure that the desired timeout target time is reached.
*/
uv_update_time(loop);
if (timeout_time > loop->time) {
timeout = (DWORD)(timeout_time - loop->time);
/* The first call to GetQueuedCompletionStatus should return very
* close to the target time and the second should reach it, but
* this is not stated in the documentation. To make sure a busy
* loop cannot happen, the timeout is increased exponentially
* starting on the third round.
*/
timeout += repeat ? (1 << (repeat - 1)) : 0;
continue;
}
}
break;
}
}
static void uv_poll_ex(uv_loop_t* loop, DWORD timeout) {
static void uv__poll(uv_loop_t* loop, DWORD timeout) {
BOOL success;
uv_req_t* req;
OVERLAPPED_ENTRY overlappeds[128];
......@@ -422,12 +371,12 @@ static void uv_poll_ex(uv_loop_t* loop, DWORD timeout) {
timeout_time = loop->time + timeout;
for (repeat = 0; ; repeat++) {
success = pGetQueuedCompletionStatusEx(loop->iocp,
overlappeds,
ARRAY_SIZE(overlappeds),
&count,
timeout,
FALSE);
success = GetQueuedCompletionStatusEx(loop->iocp,
overlappeds,
ARRAY_SIZE(overlappeds),
&count,
timeout,
FALSE);
if (success) {
for (i = 0; i < count; i++) {
......@@ -485,12 +434,6 @@ int uv_run(uv_loop_t *loop, uv_run_mode mode) {
DWORD timeout;
int r;
int ran_pending;
void (*poll)(uv_loop_t* loop, DWORD timeout);
if (pGetQueuedCompletionStatusEx)
poll = &uv_poll_ex;
else
poll = &uv_poll;
r = uv__loop_alive(loop);
if (!r)
......@@ -508,7 +451,7 @@ int uv_run(uv_loop_t *loop, uv_run_mode mode) {
if ((mode == UV_RUN_ONCE && !ran_pending) || mode == UV_RUN_DEFAULT)
timeout = uv_backend_timeout(loop);
(*poll)(loop, timeout);
uv__poll(loop, timeout);
uv_check_invoke(loop);
uv_process_endgames(loop);
......
......@@ -46,8 +46,8 @@ void uv_fatal_error(const int errorno, const char* syscall) {
errmsg = "Unknown error";
}
/* FormatMessage messages include a newline character already, */
/* so don't add another. */
/* FormatMessage messages include a newline character already, so don't add
* another. */
if (syscall) {
fprintf(stderr, "%s: (%d) %s", syscall, errorno, errmsg);
} else {
......
......@@ -326,12 +326,11 @@ INLINE static int fs__readlink_handle(HANDLE handle, char** target_ptr,
reparse_data->SymbolicLinkReparseBuffer.SubstituteNameLength /
sizeof(WCHAR);
/* Real symlinks can contain pretty much everything, but the only thing */
/* we really care about is undoing the implicit conversion to an NT */
/* namespaced path that CreateSymbolicLink will perform on absolute */
/* paths. If the path is win32-namespaced then the user must have */
/* explicitly made it so, and we better just return the unmodified */
/* reparse data. */
/* Real symlinks can contain pretty much everything, but the only thing we
* really care about is undoing the implicit conversion to an NT namespaced
* path that CreateSymbolicLink will perform on absolute paths. If the path
* is win32-namespaced then the user must have explicitly made it so, and
* we better just return the unmodified reparse data. */
if (w_target_len >= 4 &&
w_target[0] == L'\\' &&
w_target[1] == L'?' &&
......@@ -352,8 +351,8 @@ INLINE static int fs__readlink_handle(HANDLE handle, char** target_ptr,
(w_target[5] == L'N' || w_target[5] == L'n') &&
(w_target[6] == L'C' || w_target[6] == L'c') &&
w_target[7] == L'\\') {
/* \??\UNC\<server>\<share>\ - make sure the final path looks like */
/* \\<server>\<share>\ */
/* \??\UNC\<server>\<share>\ - make sure the final path looks like
* \\<server>\<share>\ */
w_target += 6;
w_target[0] = L'\\';
w_target_len -= 6;
......@@ -368,11 +367,11 @@ INLINE static int fs__readlink_handle(HANDLE handle, char** target_ptr,
w_target_len = reparse_data->MountPointReparseBuffer.SubstituteNameLength /
sizeof(WCHAR);
/* Only treat junctions that look like \??\<drive>:\ as symlink. */
/* Junctions can also be used as mount points, like \??\Volume{<guid>}, */
/* but that's confusing for programs since they wouldn't be able to */
/* actually understand such a path when returned by uv_readlink(). */
/* UNC paths are never valid for junctions so we don't care about them. */
/* Only treat junctions that look like \??\<drive>:\ as symlink. Junctions
* can also be used as mount points, like \??\Volume{<guid>}, but that's
* confusing for programs since they wouldn't be able to actually
* understand such a path when returned by uv_readlink(). UNC paths are
* never valid for junctions so we don't care about them. */
if (!(w_target_len >= 6 &&
w_target[0] == L'\\' &&
w_target[1] == L'?' &&
......@@ -409,8 +408,8 @@ void fs__open(uv_fs_t* req) {
int fd, current_umask;
int flags = req->fs.info.file_flags;
/* Obtain the active umask. umask() never fails and returns the previous */
/* umask. */
/* Obtain the active umask. umask() never fails and returns the previous
* umask. */
current_umask = umask(0);
umask(current_umask);
......@@ -530,8 +529,8 @@ void fs__open(uv_fs_t* req) {
DWORD error = GetLastError();
if (error == ERROR_FILE_EXISTS && (flags & UV_FS_O_CREAT) &&
!(flags & UV_FS_O_EXCL)) {
/* Special case: when ERROR_FILE_EXISTS happens and UV_FS_O_CREAT was */
/* specified, it means the path referred to a directory. */
/* Special case: when ERROR_FILE_EXISTS happens and UV_FS_O_CREAT was
* specified, it means the path referred to a directory. */
SET_REQ_UV_ERROR(req, UV_EISDIR, error);
} else {
SET_REQ_WIN32_ERROR(req, GetLastError());
......@@ -756,9 +755,9 @@ void fs__unlink(uv_fs_t* req) {
}
if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
/* Do not allow deletion of directories, unless it is a symlink. When */
/* the path refers to a non-symlink directory, report EPERM as mandated */
/* by POSIX.1. */
/* Do not allow deletion of directories, unless it is a symlink. When the
* path refers to a non-symlink directory, report EPERM as mandated by
* POSIX.1. */
/* Check if it is a reparse point. If it's not, it's a normal directory. */
if (!(info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
......@@ -767,8 +766,8 @@ void fs__unlink(uv_fs_t* req) {
return;
}
/* Read the reparse point and check if it is a valid symlink. */
/* If not, don't unlink. */
/* Read the reparse point and check if it is a valid symlink. If not, don't
* unlink. */
if (fs__readlink_handle(handle, NULL, NULL) < 0) {
DWORD error = GetLastError();
if (error == ERROR_SYMLINK_NOT_SUPPORTED)
......@@ -1490,6 +1489,7 @@ static void fs__chmod(uv_fs_t* req) {
static void fs__fchmod(uv_fs_t* req) {
int fd = req->file.fd;
int clear_archive_flag;
HANDLE handle;
NTSTATUS nt_status;
IO_STATUS_BLOCK io_status;
......@@ -1497,7 +1497,11 @@ static void fs__fchmod(uv_fs_t* req) {
VERIFY_FD(fd, req);
handle = uv__get_osfhandle(fd);
handle = ReOpenFile(uv__get_osfhandle(fd), FILE_WRITE_ATTRIBUTES, 0, 0);
if (handle == INVALID_HANDLE_VALUE) {
SET_REQ_WIN32_ERROR(req, GetLastError());
return;
}
nt_status = pNtQueryInformationFile(handle,
&io_status,
......@@ -1507,7 +1511,27 @@ static void fs__fchmod(uv_fs_t* req) {
if (!NT_SUCCESS(nt_status)) {
SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(nt_status));
return;
goto fchmod_cleanup;
}
/* Test if the Archive attribute is cleared */
if ((file_info.FileAttributes & FILE_ATTRIBUTE_ARCHIVE) == 0) {
/* Set Archive flag, otherwise setting or clearing the read-only
flag will not work */
file_info.FileAttributes |= FILE_ATTRIBUTE_ARCHIVE;
nt_status = pNtSetInformationFile(handle,
&io_status,
&file_info,
sizeof file_info,
FileBasicInformation);
if (!NT_SUCCESS(nt_status)) {
SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(nt_status));
goto fchmod_cleanup;
}
/* Remeber to clear the flag later on */
clear_archive_flag = 1;
} else {
clear_archive_flag = 0;
}
if (req->fs.info.mode & _S_IWRITE) {
......@@ -1524,10 +1548,28 @@ static void fs__fchmod(uv_fs_t* req) {
if (!NT_SUCCESS(nt_status)) {
SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(nt_status));
return;
goto fchmod_cleanup;
}
if (clear_archive_flag) {
file_info.FileAttributes &= ~FILE_ATTRIBUTE_ARCHIVE;
if (file_info.FileAttributes == 0) {
file_info.FileAttributes = FILE_ATTRIBUTE_NORMAL;
}
nt_status = pNtSetInformationFile(handle,
&io_status,
&file_info,
sizeof file_info,
FileBasicInformation);
if (!NT_SUCCESS(nt_status)) {
SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(nt_status));
goto fchmod_cleanup;
}
}
SET_REQ_SUCCESS(req);
fchmod_cleanup:
CloseHandle(handle);
}
......@@ -1787,17 +1829,13 @@ static void fs__symlink(uv_fs_t* req) {
fs__create_junction(req, pathw, new_pathw);
return;
}
if (!pCreateSymbolicLinkW) {
SET_REQ_UV_ERROR(req, UV_ENOSYS, ERROR_NOT_SUPPORTED);
return;
}
if (req->fs.info.file_flags & UV_FS_SYMLINK_DIR)
flags = SYMBOLIC_LINK_FLAG_DIRECTORY | uv__file_symlink_usermode_flag;
else
flags = uv__file_symlink_usermode_flag;
if (pCreateSymbolicLinkW(new_pathw, pathw, flags)) {
if (CreateSymbolicLinkW(new_pathw, pathw, flags)) {
SET_REQ_RESULT(req, 0);
return;
}
......@@ -1854,7 +1892,7 @@ static size_t fs__realpath_handle(HANDLE handle, char** realpath_ptr) {
WCHAR* w_realpath_ptr = NULL;
WCHAR* w_realpath_buf;
w_realpath_len = pGetFinalPathNameByHandleW(handle, NULL, 0, VOLUME_NAME_DOS);
w_realpath_len = GetFinalPathNameByHandleW(handle, NULL, 0, VOLUME_NAME_DOS);
if (w_realpath_len == 0) {
return -1;
}
......@@ -1866,10 +1904,8 @@ static size_t fs__realpath_handle(HANDLE handle, char** realpath_ptr) {
}
w_realpath_ptr = w_realpath_buf;
if (pGetFinalPathNameByHandleW(handle,
w_realpath_ptr,
w_realpath_len,
VOLUME_NAME_DOS) == 0) {
if (GetFinalPathNameByHandleW(
handle, w_realpath_ptr, w_realpath_len, VOLUME_NAME_DOS) == 0) {
uv__free(w_realpath_buf);
SetLastError(ERROR_INVALID_HANDLE);
return -1;
......@@ -1901,11 +1937,6 @@ static size_t fs__realpath_handle(HANDLE handle, char** realpath_ptr) {
static void fs__realpath(uv_fs_t* req) {
HANDLE handle;
if (!pGetFinalPathNameByHandleW) {
SET_REQ_UV_ERROR(req, UV_ENOSYS, ERROR_NOT_SUPPORTED);
return;
}
handle = CreateFileW(req->file.pathw,
0,
0,
......@@ -1940,6 +1971,10 @@ static void fs__fchown(uv_fs_t* req) {
}
static void fs__lchown(uv_fs_t* req) {
req->result = 0;
}
static void uv__fs_work(struct uv__work* w) {
uv_fs_t* req;
......@@ -1977,6 +2012,7 @@ static void uv__fs_work(struct uv__work* w) {
XX(REALPATH, realpath)
XX(CHOWN, chown)
XX(FCHOWN, fchown);
XX(LCHOWN, lchown);
default:
assert(!"bad uv_fs_type");
}
......@@ -2262,6 +2298,19 @@ int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_uid_t uid,
}
int uv_fs_lchown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid,
uv_gid_t gid, uv_fs_cb cb) {
int err;
INIT(UV_FS_LCHOWN);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
POST;
}
int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
int err;
......
......@@ -71,8 +71,8 @@ int uv__getaddrinfo_translate_error(int sys_err) {
#endif
/* adjust size value to be multiple of 4. Use to keep pointer aligned */
/* Do we need different versions of this for different architectures? */
/* Adjust size value to be multiple of 4. Use to keep pointer aligned.
* Do we need different versions of this for different architectures? */
#define ALIGNED_SIZE(X) ((((X) + 3) >> 2) << 2)
#ifndef NDIS_IF_MAX_STRING_SIZE
......@@ -124,8 +124,7 @@ static void uv__getaddrinfo_done(struct uv__work* w, int status) {
}
if (req->retcode == 0) {
/* convert addrinfoW to addrinfo */
/* first calculate required length */
/* Convert addrinfoW to addrinfo. First calculate required length. */
addrinfow_ptr = req->addrinfow;
while (addrinfow_ptr != NULL) {
addrinfo_len += addrinfo_struct_len +
......@@ -313,8 +312,8 @@ int uv_getaddrinfo(uv_loop_t* loop,
/* save alloc_ptr now so we can free if error */
req->alloc = (void*)alloc_ptr;
/* convert node string to UTF16 into allocated memory and save pointer in */
/* the request. */
/* Convert node string to UTF16 into allocated memory and save pointer in the
* request. */
if (node != NULL) {
req->node = (WCHAR*)alloc_ptr;
if (MultiByteToWideChar(CP_UTF8,
......@@ -331,8 +330,8 @@ int uv_getaddrinfo(uv_loop_t* loop,
req->node = NULL;
}
/* convert service string to UTF16 into allocated memory and save pointer */
/* in the req. */
/* Convert service string to UTF16 into allocated memory and save pointer in
* the req. */
if (service != NULL) {
req->service = (WCHAR*)alloc_ptr;
if (MultiByteToWideChar(CP_UTF8,
......
......@@ -164,10 +164,10 @@ INLINE static void uv_process_endgames(uv_loop_t* loop) {
INLINE static HANDLE uv__get_osfhandle(int fd)
{
/* _get_osfhandle() raises an assert in debug builds if the FD is invalid. */
/* But it also correctly checks the FD and returns INVALID_HANDLE_VALUE */
/* for invalid FDs in release builds (or if you let the assert continue). */
/* So this wrapper function disables asserts when calling _get_osfhandle. */
/* _get_osfhandle() raises an assert in debug builds if the FD is invalid.
* But it also correctly checks the FD and returns INVALID_HANDLE_VALUE for
* invalid FDs in release builds (or if you let the assert continue). So this
* wrapper function disables asserts when calling _get_osfhandle. */
HANDLE handle;
UV_BEGIN_DISABLE_CRT_ASSERT();
......
......@@ -25,7 +25,7 @@
#include "uv.h"
#include "../uv-common.h"
#include "tree.h"
#include "uv/tree.h"
#include "winapi.h"
#include "winsock.h"
......@@ -99,7 +99,6 @@ extern UV_THREAD_LOCAL int uv__crt_assert_enabled;
/* Only used by uv_pipe_t handles. */
#define UV_HANDLE_NON_OVERLAPPED_PIPE 0x01000000
#define UV_HANDLE_PIPESERVER 0x02000000
#define UV_HANDLE_PIPE_READ_CANCELABLE 0x04000000
/* Only used by uv_tty_t handles. */
#define UV_HANDLE_TTY_READABLE 0x01000000
......@@ -127,8 +126,9 @@ extern UV_THREAD_LOCAL int uv__crt_assert_enabled;
typedef struct {
WSAPROTOCOL_INFOW socket_info;
int delayed_error;
} uv__ipc_socket_info_ex;
uint32_t delayed_error;
uint32_t flags; /* Either zero or UV_HANDLE_CONNECTION. */
} uv__ipc_socket_xfer_info_t;
int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb);
int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client);
......@@ -150,11 +150,10 @@ void uv_process_tcp_connect_req(uv_loop_t* loop, uv_tcp_t* handle,
void uv_tcp_close(uv_loop_t* loop, uv_tcp_t* tcp);
void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle);
int uv_tcp_import(uv_tcp_t* tcp, uv__ipc_socket_info_ex* socket_info_ex,
int tcp_connection);
int uv_tcp_duplicate_socket(uv_tcp_t* handle, int pid,
LPWSAPROTOCOL_INFOW protocol_info);
int uv__tcp_xfer_export(uv_tcp_t* handle,
int pid,
uv__ipc_socket_xfer_info_t* xfer_info);
int uv__tcp_xfer_import(uv_tcp_t* tcp, uv__ipc_socket_xfer_info_t* xfer_info);
/*
......@@ -178,14 +177,14 @@ int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb);
int uv_pipe_accept(uv_pipe_t* server, uv_stream_t* client);
int uv_pipe_read_start(uv_pipe_t* handle, uv_alloc_cb alloc_cb,
uv_read_cb read_cb);
int uv_pipe_write(uv_loop_t* loop, uv_write_t* req, uv_pipe_t* handle,
const uv_buf_t bufs[], unsigned int nbufs, uv_write_cb cb);
int uv_pipe_write2(uv_loop_t* loop, uv_write_t* req, uv_pipe_t* handle,
const uv_buf_t bufs[], unsigned int nbufs, uv_stream_t* send_handle,
uv_write_cb cb);
void uv__pipe_pause_read(uv_pipe_t* handle);
void uv__pipe_unpause_read(uv_pipe_t* handle);
void uv__pipe_stop_read(uv_pipe_t* handle);
void uv__pipe_read_stop(uv_pipe_t* handle);
int uv__pipe_write(uv_loop_t* loop,
uv_write_t* req,
uv_pipe_t* handle,
const uv_buf_t bufs[],
size_t nbufs,
uv_stream_t* send_handle,
uv_write_cb cb);
void uv_process_pipe_read_req(uv_loop_t* loop, uv_pipe_t* handle,
uv_req_t* req);
......@@ -332,7 +331,6 @@ void uv__fs_poll_endgame(uv_loop_t* loop, uv_fs_poll_t* handle);
void uv__util_init(void);
uint64_t uv__hrtime(double scale);
int uv_current_pid(void);
__declspec(noreturn) void uv_fatal_error(const int errorno, const char* syscall);
int uv__getpwuid_r(uv_passwd_t* pwd);
int uv__convert_utf16_to_utf8(const WCHAR* utf16, int utf16len, char** utf8);
......
This diff is collapsed.
......@@ -91,16 +91,16 @@ static void uv__fast_poll_submit_poll_req(uv_loop_t* loop, uv_poll_t* handle) {
handle->mask_events_1 = handle->events;
handle->mask_events_2 = 0;
} else {
/* Just wait until there's an unsubmitted req. */
/* This will happen almost immediately as one of the 2 outstanding */
/* requests is about to return. When this happens, */
/* uv__fast_poll_process_poll_req will be called, and the pending */
/* events, if needed, will be processed in a subsequent request. */
/* Just wait until there's an unsubmitted req. This will happen almost
* immediately as one of the 2 outstanding requests is about to return.
* When this happens, uv__fast_poll_process_poll_req will be called, and
* the pending events, if needed, will be processed in a subsequent
* request. */
return;
}
/* Setting Exclusive to TRUE makes the other poll request return if there */
/* is any. */
/* Setting Exclusive to TRUE makes the other poll request return if there is
* any. */
afd_poll_info->Exclusive = TRUE;
afd_poll_info->NumberOfHandles = 1;
afd_poll_info->Timeout.QuadPart = INT64_MAX;
......@@ -257,8 +257,8 @@ static int uv__fast_poll_close(uv_loop_t* loop, uv_poll_t* handle) {
uv_want_endgame(loop, (uv_handle_t*) handle);
return 0;
} else {
/* Cancel outstanding poll requests by executing another, unique poll */
/* request that forces the outstanding ones to return. */
/* Cancel outstanding poll requests by executing another, unique poll
* request that forces the outstanding ones to return. */
return uv__fast_poll_cancel_poll_req(loop, handle);
}
}
......@@ -316,9 +316,8 @@ static SOCKET uv__fast_poll_get_peer_socket(uv_loop_t* loop,
return INVALID_SOCKET;
}
/* If we didn't (try) to create a peer socket yet, try to make one. Don't */
/* try again if the peer socket creation failed earlier for the same */
/* protocol. */
/* If we didn't (try) to create a peer socket yet, try to make one. Don't try
* again if the peer socket creation failed earlier for the same protocol. */
peer_socket = loop->poll_peer_sockets[index];
if (peer_socket == 0) {
peer_socket = uv__fast_poll_create_peer_socket(loop->iocp, protocol_info);
......@@ -357,8 +356,8 @@ static DWORD WINAPI uv__slow_poll_thread_proc(void* arg) {
efds.fd_count = 0;
}
/* Make the select() time out after 3 minutes. If select() hangs because */
/* the user closed the socket, we will at least not hang indefinitely. */
/* Make the select() time out after 3 minutes. If select() hangs because the
* user closed the socket, we will at least not hang indefinitely. */
timeout.tv_sec = 3 * 60;
timeout.tv_usec = 0;
......@@ -522,10 +521,10 @@ int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle,
if (ioctlsocket(socket, FIONBIO, &yes) == SOCKET_ERROR)
return uv_translate_sys_error(WSAGetLastError());
/* Try to obtain a base handle for the socket. This increases this chances */
/* that we find an AFD handle and are able to use the fast poll mechanism. */
/* This will always fail on windows XP/2k3, since they don't support the */
/* SIO_BASE_HANDLE ioctl. */
/* Try to obtain a base handle for the socket. This increases this chances that
* we find an AFD handle and are able to use the fast poll mechanism. This will
* always fail on windows XP/2k3, since they don't support the. SIO_BASE_HANDLE
* ioctl. */
#ifndef NDEBUG
base_socket = INVALID_SOCKET;
#endif
......@@ -557,9 +556,9 @@ int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle,
return uv_translate_sys_error(WSAGetLastError());
}
/* Get the peer socket that is needed to enable fast poll. If the returned */
/* value is NULL, the protocol is not implemented by MSAFD and we'll have */
/* to use slow mode. */
/* Get the peer socket that is needed to enable fast poll. If the returned
* value is NULL, the protocol is not implemented by MSAFD and we'll have to
* use slow mode. */
peer_socket = uv__fast_poll_get_peer_socket(loop, &protocol_info);
if (peer_socket != INVALID_SOCKET) {
......
......@@ -105,10 +105,9 @@ static int uv__create_stdio_pipe_pair(uv_loop_t* loop,
int err;
if (flags & UV_READABLE_PIPE) {
/* The server needs inbound access too, otherwise CreateNamedPipe() */
/* won't give us the FILE_READ_ATTRIBUTES permission. We need that to */
/* probe the state of the write buffer when we're trying to shutdown */
/* the pipe. */
/* The server needs inbound access too, otherwise CreateNamedPipe() won't
* give us the FILE_READ_ATTRIBUTES permission. We need that to probe the
* state of the write buffer when we're trying to shutdown the pipe. */
server_access |= PIPE_ACCESS_OUTBOUND | PIPE_ACCESS_INBOUND;
client_access |= GENERIC_READ | FILE_WRITE_ATTRIBUTES;
}
......@@ -131,12 +130,13 @@ static int uv__create_stdio_pipe_pair(uv_loop_t* loop,
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
BOOL overlap = server_pipe->ipc || (flags & UV_OVERLAPPED_PIPE);
child_pipe = CreateFileA(pipe_name,
client_access,
0,
&sa,
OPEN_EXISTING,
server_pipe->ipc ? FILE_FLAG_OVERLAPPED : 0,
overlap ? FILE_FLAG_OVERLAPPED : 0,
NULL);
if (child_pipe == INVALID_HANDLE_VALUE) {
err = GetLastError();
......@@ -159,8 +159,8 @@ static int uv__create_stdio_pipe_pair(uv_loop_t* loop,
}
#endif
/* Do a blocking ConnectNamedPipe. This should not block because we have */
/* both ends of the pipe created. */
/* Do a blocking ConnectNamedPipe. This should not block because we have both
* ends of the pipe created. */
if (!ConnectNamedPipe(server_pipe->handle, NULL)) {
if (GetLastError() != ERROR_PIPE_CONNECTED) {
err = GetLastError();
......@@ -194,11 +194,11 @@ static int uv__duplicate_handle(uv_loop_t* loop, HANDLE handle, HANDLE* dup) {
HANDLE current_process;
/* _get_osfhandle will sometimes return -2 in case of an error. This seems */
/* to happen when fd <= 2 and the process' corresponding stdio handle is */
/* set to NULL. Unfortunately DuplicateHandle will happily duplicate */
/* (HANDLE) -2, so this situation goes unnoticed until someone tries to */
/* use the duplicate. Therefore we filter out known-invalid handles here. */
/* _get_osfhandle will sometimes return -2 in case of an error. This seems to
* happen when fd <= 2 and the process' corresponding stdio handle is set to
* NULL. Unfortunately DuplicateHandle will happily duplicate (HANDLE) -2, so
* this situation goes unnoticed until someone tries to use the duplicate.
* Therefore we filter out known-invalid handles here. */
if (handle == INVALID_HANDLE_VALUE ||
handle == NULL ||
handle == (HANDLE) -2) {
......@@ -284,8 +284,8 @@ int uv__stdio_create(uv_loop_t* loop,
return ERROR_OUTOFMEMORY;
}
/* Prepopulate the buffer with INVALID_HANDLE_VALUE handles so we can */
/* clean up on failure. */
/* Prepopulate the buffer with INVALID_HANDLE_VALUE handles so we can clean
* up on failure. */
CHILD_STDIO_COUNT(buffer) = count;
for (i = 0; i < count; i++) {
CHILD_STDIO_CRT_FLAGS(buffer, i) = 0;
......@@ -303,12 +303,12 @@ int uv__stdio_create(uv_loop_t* loop,
switch (fdopt.flags & (UV_IGNORE | UV_CREATE_PIPE | UV_INHERIT_FD |
UV_INHERIT_STREAM)) {
case UV_IGNORE:
/* Starting a process with no stdin/stout/stderr can confuse it. */
/* So no matter what the user specified, we make sure the first */
/* three FDs are always open in their typical modes, e.g. stdin */
/* be readable and stdout/err should be writable. For FDs > 2, don't */
/* do anything - all handles in the stdio buffer are initialized with */
/* INVALID_HANDLE_VALUE, which should be okay. */
/* Starting a process with no stdin/stout/stderr can confuse it. So no
* matter what the user specified, we make sure the first three FDs are
* always open in their typical modes, e. g. stdin be readable and
* stdout/err should be writable. For FDs > 2, don't do anything - all
* handles in the stdio buffer are initialized with.
* INVALID_HANDLE_VALUE, which should be okay. */
if (i <= 2) {
DWORD access = (i == 0) ? FILE_GENERIC_READ :
FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES;
......@@ -323,14 +323,14 @@ int uv__stdio_create(uv_loop_t* loop,
break;
case UV_CREATE_PIPE: {
/* Create a pair of two connected pipe ends; one end is turned into */
/* an uv_pipe_t for use by the parent. The other one is given to */
/* the child. */
/* Create a pair of two connected pipe ends; one end is turned into an
* uv_pipe_t for use by the parent. The other one is given to the
* child. */
uv_pipe_t* parent_pipe = (uv_pipe_t*) fdopt.data.stream;
HANDLE child_pipe = INVALID_HANDLE_VALUE;
/* Create a new, connected pipe pair. stdio[i].stream should point */
/* to an uninitialized, but not connected pipe handle. */
/* Create a new, connected pipe pair. stdio[i]. stream should point to
* an uninitialized, but not connected pipe handle. */
assert(fdopt.data.stream->type == UV_NAMED_PIPE);
assert(!(fdopt.data.stream->flags & UV_HANDLE_CONNECTION));
assert(!(fdopt.data.stream->flags & UV_HANDLE_PIPESERVER));
......@@ -354,8 +354,8 @@ int uv__stdio_create(uv_loop_t* loop,
/* Make an inheritable duplicate of the handle. */
err = uv__duplicate_fd(loop, fdopt.data.fd, &child_handle);
if (err) {
/* If fdopt.data.fd is not valid and fd fd <= 2, then ignore the */
/* error. */
/* If fdopt. data. fd is not valid and fd <= 2, then ignore the
* error. */
if (fdopt.data.fd <= 2 && err == ERROR_INVALID_HANDLE) {
CHILD_STDIO_CRT_FLAGS(buffer, i) = 0;
CHILD_STDIO_HANDLE(buffer, i) = INVALID_HANDLE_VALUE;
......@@ -418,8 +418,8 @@ int uv__stdio_create(uv_loop_t* loop,
if (stream_handle == NULL ||
stream_handle == INVALID_HANDLE_VALUE) {
/* The handle is already closed, or not yet created, or the */
/* stream type is not supported. */
/* The handle is already closed, or not yet created, or the stream
* type is not supported. */
err = ERROR_NOT_SUPPORTED;
goto error;
}
......
......@@ -360,8 +360,8 @@ static WCHAR* search_path(const WCHAR *file,
return NULL;
}
/* Find the start of the filename so we can split the directory from the */
/* name. */
/* Find the start of the filename so we can split the directory from the
* name. */
for (file_name_start = (WCHAR*)file + file_len;
file_name_start > file
&& file_name_start[-1] != L'\\'
......@@ -556,8 +556,8 @@ int make_program_args(char** args, int verbatim_arguments, WCHAR** dst_ptr) {
arg_count++;
}
/* Adjust for potential quotes. Also assume the worst-case scenario */
/* that every character needs escaping, so we need twice as much space. */
/* Adjust for potential quotes. Also assume the worst-case scenario that
* every character needs escaping, so we need twice as much space. */
dst_len = dst_len * 2 + arg_count * 2;
/* Allocate buffer for the final command line. */
......@@ -831,8 +831,13 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) {
*/
static WCHAR* find_path(WCHAR *env) {
for (; env != NULL && *env != 0; env += wcslen(env) + 1) {
if (wcsncmp(env, L"PATH=", 5) == 0)
if ((env[0] == L'P' || env[0] == L'p') &&
(env[1] == L'A' || env[1] == L'a') &&
(env[2] == L'T' || env[2] == L't') &&
(env[3] == L'H' || env[3] == L'h') &&
(env[4] == L'=')) {
return &env[5];
}
}
return NULL;
......@@ -865,8 +870,8 @@ void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle) {
assert(handle->exit_cb_pending);
handle->exit_cb_pending = 0;
/* If we're closing, don't call the exit callback. Just schedule a close */
/* callback now. */
/* If we're closing, don't call the exit callback. Just schedule a close
* callback now. */
if (handle->flags & UV__HANDLE_CLOSING) {
uv_want_endgame(loop, (uv_handle_t*) handle);
return;
......@@ -878,14 +883,14 @@ void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle) {
handle->wait_handle = INVALID_HANDLE_VALUE;
}
/* Set the handle to inactive: no callbacks will be made after the exit */
/* callback.*/
/* Set the handle to inactive: no callbacks will be made after the exit
* callback. */
uv__handle_stop(handle);
if (GetExitCodeProcess(handle->process_handle, &status)) {
exit_code = status;
} else {
/* Unable to to obtain the exit code. This should never happen. */
/* Unable to obtain the exit code. This should never happen. */
exit_code = uv_translate_sys_error(GetLastError());
}
......@@ -900,8 +905,8 @@ void uv_process_close(uv_loop_t* loop, uv_process_t* handle) {
uv__handle_closing(handle);
if (handle->wait_handle != INVALID_HANDLE_VALUE) {
/* This blocks until either the wait was cancelled, or the callback has */
/* completed. */
/* This blocks until either the wait was cancelled, or the callback has
* completed. */
BOOL r = UnregisterWaitEx(handle->wait_handle, INVALID_HANDLE_VALUE);
if (!r) {
/* This should never happen, and if it happens, we can't recover... */
......@@ -1104,14 +1109,13 @@ int uv_spawn(uv_loop_t* loop,
goto done;
}
/* Spawn succeeded */
/* Beyond this point, failure is reported asynchronously. */
/* Spawn succeeded. Beyond this point, failure is reported asynchronously. */
process->process_handle = info.hProcess;
process->pid = info.dwProcessId;
/* If the process isn't spawned as detached, assign to the global job */
/* object so windows will kill it when the parent process dies. */
/* If the process isn't spawned as detached, assign to the global job object
* so windows will kill it when the parent process dies. */
if (!(options->flags & UV_PROCESS_DETACHED)) {
uv_once(&uv_global_job_handle_init_guard_, uv__init_global_job_handle);
......@@ -1138,7 +1142,8 @@ int uv_spawn(uv_loop_t* loop,
if (fdopt->flags & UV_CREATE_PIPE &&
fdopt->data.stream->type == UV_NAMED_PIPE &&
((uv_pipe_t*) fdopt->data.stream)->ipc) {
((uv_pipe_t*) fdopt->data.stream)->pipe.conn.ipc_pid = info.dwProcessId;
((uv_pipe_t*) fdopt->data.stream)->pipe.conn.ipc_remote_pid =
info.dwProcessId;
}
}
......@@ -1154,8 +1159,8 @@ int uv_spawn(uv_loop_t* loop,
assert(!err);
/* Make the handle active. It will remain active until the exit callback */
/* is made or the handle is closed, whichever happens first. */
/* Make the handle active. It will remain active until the exit callback is
* made or the handle is closed, whichever happens first. */
uv__handle_start(process);
/* Cleanup, whether we succeeded or failed. */
......@@ -1186,16 +1191,16 @@ static int uv__kill(HANDLE process_handle, int signum) {
case SIGTERM:
case SIGKILL:
case SIGINT: {
/* Unconditionally terminate the process. On Windows, killed processes */
/* normally return 1. */
/* Unconditionally terminate the process. On Windows, killed processes
* normally return 1. */
DWORD status;
int err;
if (TerminateProcess(process_handle, 1))
return 0;
/* If the process already exited before TerminateProcess was called, */
/* TerminateProcess will fail with ERROR_ACCESS_DENIED. */
/* If the process already exited before TerminateProcess was called,.
* TerminateProcess will fail with ERROR_ACCESS_DENIED. */
err = GetLastError();
if (err == ERROR_ACCESS_DENIED &&
GetExitCodeProcess(process_handle, &status) &&
......
......@@ -47,13 +47,13 @@ void uv_signals_init(void) {
static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2) {
/* Compare signums first so all watchers with the same signnum end up */
/* adjacent. */
/* Compare signums first so all watchers with the same signnum end up
* adjacent. */
if (w1->signum < w2->signum) return -1;
if (w1->signum > w2->signum) return 1;
/* Sort by loop pointer, so we can easily look up the first item after */
/* { .signum = x, .loop = NULL } */
/* Sort by loop pointer, so we can easily look up the first item after
* { .signum = x, .loop = NULL }. */
if ((uintptr_t) w1->loop < (uintptr_t) w2->loop) return -1;
if ((uintptr_t) w1->loop > (uintptr_t) w2->loop) return 1;
......@@ -118,10 +118,10 @@ static BOOL WINAPI uv__signal_control_handler(DWORD type) {
case CTRL_CLOSE_EVENT:
if (uv__signal_dispatch(SIGHUP)) {
/* Windows will terminate the process after the control handler */
/* returns. After that it will just terminate our process. Therefore */
/* block the signal handler so the main loop has some time to pick */
/* up the signal and do something for a few seconds. */
/* Windows will terminate the process after the control handler
* returns. After that it will just terminate our process. Therefore
* block the signal handler so the main loop has some time to pick up
* the signal and do something for a few seconds. */
Sleep(INFINITE);
return TRUE;
}
......@@ -129,8 +129,8 @@ static BOOL WINAPI uv__signal_control_handler(DWORD type) {
case CTRL_LOGOFF_EVENT:
case CTRL_SHUTDOWN_EVENT:
/* These signals are only sent to services. Services have their own */
/* notification mechanism, so there's no point in handling these. */
/* These signals are only sent to services. Services have their own
* notification mechanism, so there's no point in handling these. */
default:
/* We don't handle these. */
......@@ -193,10 +193,10 @@ int uv__signal_start(uv_signal_t* handle,
if (signum != SIGWINCH && (signum <= 0 || signum >= NSIG))
return UV_EINVAL;
/* Short circuit: if the signal watcher is already watching {signum} don't */
/* go through the process of deregistering and registering the handler. */
/* Additionally, this avoids pending signals getting lost in the (small) */
/* time frame that handle->signum == 0. */
/* Short circuit: if the signal watcher is already watching {signum} don't go
* through the process of deregistering and registering the handler.
* Additionally, this avoids pending signals getting lost in the (small) time
* frame that handle->signum == 0. */
if (signum == handle->signum) {
handle->signal_cb = signal_cb;
return 0;
......@@ -237,9 +237,9 @@ void uv_process_signal_req(uv_loop_t* loop, uv_signal_t* handle,
(volatile LONG*) &handle->pending_signum, 0);
assert(dispatched_signum != 0);
/* Check if the pending signal equals the signum that we are watching for. */
/* These can get out of sync when the handler is stopped and restarted */
/* while the signal_req is pending. */
/* Check if the pending signal equals the signum that we are watching for.
* These can get out of sync when the handler is stopped and restarted while
* the signal_req is pending. */
if (dispatched_signum == handle->signum)
handle->signal_cb(handle, dispatched_signum);
......
......@@ -105,12 +105,10 @@ int uv_read_stop(uv_stream_t* handle) {
err = 0;
if (handle->type == UV_TTY) {
err = uv_tty_read_stop((uv_tty_t*) handle);
} else if (handle->type == UV_NAMED_PIPE) {
uv__pipe_read_stop((uv_pipe_t*) handle);
} else {
if (handle->type == UV_NAMED_PIPE) {
uv__pipe_stop_read((uv_pipe_t*) handle);
} else {
handle->flags &= ~UV_HANDLE_READING;
}
handle->flags &= ~UV_HANDLE_READING;
DECREASE_ACTIVE_COUNT(handle->loop, handle);
}
......@@ -136,7 +134,8 @@ int uv_write(uv_write_t* req,
err = uv_tcp_write(loop, req, (uv_tcp_t*) handle, bufs, nbufs, cb);
break;
case UV_NAMED_PIPE:
err = uv_pipe_write(loop, req, (uv_pipe_t*) handle, bufs, nbufs, cb);
err = uv__pipe_write(
loop, req, (uv_pipe_t*) handle, bufs, nbufs, NULL, cb);
break;
case UV_TTY:
err = uv_tty_write(loop, req, (uv_tty_t*) handle, bufs, nbufs, cb);
......@@ -158,25 +157,18 @@ int uv_write2(uv_write_t* req,
uv_loop_t* loop = handle->loop;
int err;
if (!(handle->flags & UV_HANDLE_WRITABLE)) {
return UV_EPIPE;
if (send_handle == NULL) {
return uv_write(req, handle, bufs, nbufs, cb);
}
err = ERROR_INVALID_PARAMETER;
switch (handle->type) {
case UV_NAMED_PIPE:
err = uv_pipe_write2(loop,
req,
(uv_pipe_t*) handle,
bufs,
nbufs,
send_handle,
cb);
break;
default:
assert(0);
if (handle->type != UV_NAMED_PIPE || !((uv_pipe_t*) handle)->ipc) {
return UV_EINVAL;
} else if (!(handle->flags & UV_HANDLE_WRITABLE)) {
return UV_EPIPE;
}
err = uv__pipe_write(
loop, req, (uv_pipe_t*) handle, bufs, nbufs, send_handle, cb);
return uv_translate_sys_error(err);
}
......
This diff is collapsed.
......@@ -26,17 +26,6 @@
#include "uv.h"
#include "internal.h"
#define HAVE_CONDVAR_API() (pInitializeConditionVariable != NULL)
static int uv_cond_fallback_init(uv_cond_t* cond);
static void uv_cond_fallback_destroy(uv_cond_t* cond);
static void uv_cond_fallback_signal(uv_cond_t* cond);
static void uv_cond_fallback_broadcast(uv_cond_t* cond);
static void uv_cond_fallback_wait(uv_cond_t* cond, uv_mutex_t* mutex);
static int uv_cond_fallback_timedwait(uv_cond_t* cond,
uv_mutex_t* mutex, uint64_t timeout);
static int uv_cond_condvar_init(uv_cond_t* cond);
static void uv_cond_condvar_destroy(uv_cond_t* cond);
static void uv_cond_condvar_signal(uv_cond_t* cond);
......@@ -69,8 +58,8 @@ static void uv__once_inner(uv_once_t* guard, void (*callback)(void)) {
guard->ran = 1;
} else {
/* We lost the race. Destroy the event we created and wait for the */
/* existing one to become signaled. */
/* We lost the race. Destroy the event we created and wait for the existing
* one to become signaled. */
CloseHandle(created_event);
result = WaitForSingleObject(existing_event, INFINITE);
assert(result == WAIT_OBJECT_0);
......@@ -377,220 +366,35 @@ int uv_sem_trywait(uv_sem_t* sem) {
}
/* This condition variable implementation is based on the SetEvent solution
* (section 3.2) at http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
* We could not use the SignalObjectAndWait solution (section 3.4) because
* it want the 2nd argument (type uv_mutex_t) of uv_cond_wait() and
* uv_cond_timedwait() to be HANDLEs, but we use CRITICAL_SECTIONs.
*/
static int uv_cond_fallback_init(uv_cond_t* cond) {
int err;
/* Initialize the count to 0. */
cond->fallback.waiters_count = 0;
InitializeCriticalSection(&cond->fallback.waiters_count_lock);
/* Create an auto-reset event. */
cond->fallback.signal_event = CreateEvent(NULL, /* no security */
FALSE, /* auto-reset event */
FALSE, /* non-signaled initially */
NULL); /* unnamed */
if (!cond->fallback.signal_event) {
err = GetLastError();
goto error2;
}
/* Create a manual-reset event. */
cond->fallback.broadcast_event = CreateEvent(NULL, /* no security */
TRUE, /* manual-reset */
FALSE, /* non-signaled */
NULL); /* unnamed */
if (!cond->fallback.broadcast_event) {
err = GetLastError();
goto error;
}
return 0;
error:
CloseHandle(cond->fallback.signal_event);
error2:
DeleteCriticalSection(&cond->fallback.waiters_count_lock);
return uv_translate_sys_error(err);
}
static int uv_cond_condvar_init(uv_cond_t* cond) {
pInitializeConditionVariable(&cond->cond_var);
return 0;
}
int uv_cond_init(uv_cond_t* cond) {
uv__once_init();
if (HAVE_CONDVAR_API())
return uv_cond_condvar_init(cond);
else
return uv_cond_fallback_init(cond);
}
static void uv_cond_fallback_destroy(uv_cond_t* cond) {
if (!CloseHandle(cond->fallback.broadcast_event))
abort();
if (!CloseHandle(cond->fallback.signal_event))
abort();
DeleteCriticalSection(&cond->fallback.waiters_count_lock);
}
static void uv_cond_condvar_destroy(uv_cond_t* cond) {
/* nothing to do */
InitializeConditionVariable(&cond->cond_var);
return 0;
}
void uv_cond_destroy(uv_cond_t* cond) {
if (HAVE_CONDVAR_API())
uv_cond_condvar_destroy(cond);
else
uv_cond_fallback_destroy(cond);
}
static void uv_cond_fallback_signal(uv_cond_t* cond) {
int have_waiters;
/* Avoid race conditions. */
EnterCriticalSection(&cond->fallback.waiters_count_lock);
have_waiters = cond->fallback.waiters_count > 0;
LeaveCriticalSection(&cond->fallback.waiters_count_lock);
if (have_waiters)
SetEvent(cond->fallback.signal_event);
}
static void uv_cond_condvar_signal(uv_cond_t* cond) {
pWakeConditionVariable(&cond->cond_var);
/* nothing to do */
UV__UNUSED(cond);
}
void uv_cond_signal(uv_cond_t* cond) {
if (HAVE_CONDVAR_API())
uv_cond_condvar_signal(cond);
else
uv_cond_fallback_signal(cond);
}
static void uv_cond_fallback_broadcast(uv_cond_t* cond) {
int have_waiters;
/* Avoid race conditions. */
EnterCriticalSection(&cond->fallback.waiters_count_lock);
have_waiters = cond->fallback.waiters_count > 0;
LeaveCriticalSection(&cond->fallback.waiters_count_lock);
if (have_waiters)
SetEvent(cond->fallback.broadcast_event);
}
static void uv_cond_condvar_broadcast(uv_cond_t* cond) {
pWakeAllConditionVariable(&cond->cond_var);
WakeConditionVariable(&cond->cond_var);
}
void uv_cond_broadcast(uv_cond_t* cond) {
if (HAVE_CONDVAR_API())
uv_cond_condvar_broadcast(cond);
else
uv_cond_fallback_broadcast(cond);
}
static int uv_cond_wait_helper(uv_cond_t* cond, uv_mutex_t* mutex,
DWORD dwMilliseconds) {
DWORD result;
int last_waiter;
HANDLE handles[2] = {
cond->fallback.signal_event,
cond->fallback.broadcast_event
};
/* Avoid race conditions. */
EnterCriticalSection(&cond->fallback.waiters_count_lock);
cond->fallback.waiters_count++;
LeaveCriticalSection(&cond->fallback.waiters_count_lock);
/* It's ok to release the <mutex> here since Win32 manual-reset events */
/* maintain state when used with <SetEvent>. This avoids the "lost wakeup" */
/* bug. */
uv_mutex_unlock(mutex);
/* Wait for either event to become signaled due to <uv_cond_signal> being */
/* called or <uv_cond_broadcast> being called. */
result = WaitForMultipleObjects(2, handles, FALSE, dwMilliseconds);
EnterCriticalSection(&cond->fallback.waiters_count_lock);
cond->fallback.waiters_count--;
last_waiter = result == WAIT_OBJECT_0 + 1
&& cond->fallback.waiters_count == 0;
LeaveCriticalSection(&cond->fallback.waiters_count_lock);
/* Some thread called <pthread_cond_broadcast>. */
if (last_waiter) {
/* We're the last waiter to be notified or to stop waiting, so reset the */
/* the manual-reset event. */
ResetEvent(cond->fallback.broadcast_event);
}
/* Reacquire the <mutex>. */
uv_mutex_lock(mutex);
if (result == WAIT_OBJECT_0 || result == WAIT_OBJECT_0 + 1)
return 0;
if (result == WAIT_TIMEOUT)
return UV_ETIMEDOUT;
abort();
return -1; /* Satisfy the compiler. */
}
static void uv_cond_fallback_wait(uv_cond_t* cond, uv_mutex_t* mutex) {
if (uv_cond_wait_helper(cond, mutex, INFINITE))
abort();
}
static void uv_cond_condvar_wait(uv_cond_t* cond, uv_mutex_t* mutex) {
if (!pSleepConditionVariableCS(&cond->cond_var, mutex, INFINITE))
abort();
WakeAllConditionVariable(&cond->cond_var);
}
void uv_cond_wait(uv_cond_t* cond, uv_mutex_t* mutex) {
if (HAVE_CONDVAR_API())
uv_cond_condvar_wait(cond, mutex);
else
uv_cond_fallback_wait(cond, mutex);
}
static int uv_cond_fallback_timedwait(uv_cond_t* cond,
uv_mutex_t* mutex, uint64_t timeout) {
return uv_cond_wait_helper(cond, mutex, (DWORD)(timeout / 1e6));
if (!SleepConditionVariableCS(&cond->cond_var, mutex, INFINITE))
abort();
}
static int uv_cond_condvar_timedwait(uv_cond_t* cond,
uv_mutex_t* mutex, uint64_t timeout) {
if (pSleepConditionVariableCS(&cond->cond_var, mutex, (DWORD)(timeout / 1e6)))
int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex, uint64_t timeout) {
if (SleepConditionVariableCS(&cond->cond_var, mutex, (DWORD)(timeout / 1e6)))
return 0;
if (GetLastError() != ERROR_TIMEOUT)
abort();
......@@ -598,15 +402,6 @@ static int uv_cond_condvar_timedwait(uv_cond_t* cond,
}
int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex,
uint64_t timeout) {
if (HAVE_CONDVAR_API())
return uv_cond_condvar_timedwait(cond, mutex, timeout);
else
return uv_cond_fallback_timedwait(cond, mutex, timeout);
}
int uv_barrier_init(uv_barrier_t* barrier, unsigned int count) {
int err;
......
......@@ -24,7 +24,7 @@
#include "uv.h"
#include "internal.h"
#include "tree.h"
#include "uv/tree.h"
#include "handle-inl.h"
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -34,21 +34,6 @@ sNtQueryVolumeInformationFile pNtQueryVolumeInformationFile;
sNtQueryDirectoryFile pNtQueryDirectoryFile;
sNtQuerySystemInformation pNtQuerySystemInformation;
/* Kernel32 function pointers */
sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx;
sSetFileCompletionNotificationModes pSetFileCompletionNotificationModes;
sCreateSymbolicLinkW pCreateSymbolicLinkW;
sCancelIoEx pCancelIoEx;
sInitializeConditionVariable pInitializeConditionVariable;
sSleepConditionVariableCS pSleepConditionVariableCS;
sSleepConditionVariableSRW pSleepConditionVariableSRW;
sWakeAllConditionVariable pWakeAllConditionVariable;
sWakeConditionVariable pWakeConditionVariable;
sCancelSynchronousIo pCancelSynchronousIo;
sGetFinalPathNameByHandleW pGetFinalPathNameByHandleW;
/* Powrprof.dll function pointer */
sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotification;
......@@ -58,7 +43,6 @@ sSetWinEventHook pSetWinEventHook;
void uv_winapi_init(void) {
HMODULE ntdll_module;
HMODULE kernel32_module;
HMODULE powrprof_module;
HMODULE user32_module;
......@@ -114,46 +98,6 @@ void uv_winapi_init(void) {
uv_fatal_error(GetLastError(), "GetProcAddress");
}
kernel32_module = GetModuleHandleA("kernel32.dll");
if (kernel32_module == NULL) {
uv_fatal_error(GetLastError(), "GetModuleHandleA");
}
pGetQueuedCompletionStatusEx = (sGetQueuedCompletionStatusEx) GetProcAddress(
kernel32_module,
"GetQueuedCompletionStatusEx");
pSetFileCompletionNotificationModes = (sSetFileCompletionNotificationModes)
GetProcAddress(kernel32_module, "SetFileCompletionNotificationModes");
pCreateSymbolicLinkW = (sCreateSymbolicLinkW)
GetProcAddress(kernel32_module, "CreateSymbolicLinkW");
pCancelIoEx = (sCancelIoEx)
GetProcAddress(kernel32_module, "CancelIoEx");
pInitializeConditionVariable = (sInitializeConditionVariable)
GetProcAddress(kernel32_module, "InitializeConditionVariable");
pSleepConditionVariableCS = (sSleepConditionVariableCS)
GetProcAddress(kernel32_module, "SleepConditionVariableCS");
pSleepConditionVariableSRW = (sSleepConditionVariableSRW)
GetProcAddress(kernel32_module, "SleepConditionVariableSRW");
pWakeAllConditionVariable = (sWakeAllConditionVariable)
GetProcAddress(kernel32_module, "WakeAllConditionVariable");
pWakeConditionVariable = (sWakeConditionVariable)
GetProcAddress(kernel32_module, "WakeConditionVariable");
pCancelSynchronousIo = (sCancelSynchronousIo)
GetProcAddress(kernel32_module, "CancelSynchronousIo");
pGetFinalPathNameByHandleW = (sGetFinalPathNameByHandleW)
GetProcAddress(kernel32_module, "GetFinalPathNameByHandleW");
powrprof_module = LoadLibraryA("powrprof.dll");
if (powrprof_module != NULL) {
pPowerRegisterSuspendResumeNotification = (sPowerRegisterSuspendResumeNotification)
......
This diff is collapsed.
......@@ -256,8 +256,8 @@ int uv_ntstatus_to_winsock_error(NTSTATUS status) {
default:
if ((status & (FACILITY_NTWIN32 << 16)) == (FACILITY_NTWIN32 << 16) &&
(status & (ERROR_SEVERITY_ERROR | ERROR_SEVERITY_WARNING))) {
/* It's a windows error that has been previously mapped to an */
/* ntstatus code. */
/* It's a windows error that has been previously mapped to an ntstatus
* code. */
return (DWORD) (status & 0xffff);
} else {
/* The default fallback for unmappable ntstatus codes. */
......@@ -519,8 +519,8 @@ int WSAAPI uv_msafd_poll(SOCKET socket, AFD_POLL_INFO* info_in,
sizeof *info_out);
if (overlapped == NULL) {
/* If this is a blocking operation, wait for the event to become */
/* signaled, and then grab the real status from the io status block. */
/* If this is a blocking operation, wait for the event to become signaled,
* and then grab the real status from the io status block. */
if (status == STATUS_PENDING) {
DWORD r = WaitForSingleObject(event, INFINITE);
......
This diff is collapsed.
......@@ -211,6 +211,8 @@ if sys.platform != 'win32':
if sys.platform.startswith('linux'):
_add_library('dl')
_add_library('rt')
_define_macro('_GNU_SOURCE', 1)
_define_macro('_POSIX_C_SOURCE', '200112')
elif sys.platform == 'darwin':
_define_macro('_DARWIN_USE_64_BIT_INODE', 1)
_define_macro('_DARWIN_UNLIMITED_SELECT', 1)
......@@ -230,6 +232,7 @@ elif WIN:
_define_macro('_CRT_NONSTDC_NO_DEPRECATE', 1)
_define_macro('_CRT_SECURE_NO_WARNINGS', 1)
_define_macro('_WIN32_WINNT', '0x0600')
_define_macro('WIN32_LEAN_AND_MEAN', 1)
_add_library('advapi32')
_add_library('iphlpapi')
_add_library('psapi')
......
......@@ -151,8 +151,9 @@ class loop(AbstractLoop):
self._signal_idle = ffi.new("uv_timer_t*")
libuv.uv_timer_init(self._ptr, self._signal_idle)
self._signal_idle.data = self._handle_to_self
sig_cb = ffi.cast('void(*)(uv_timer_t*)', libuv.python_check_callback)
libuv.uv_timer_start(self._signal_idle,
ffi.cast('void(*)(uv_timer_t*)', libuv.python_check_callback),
sig_cb,
300,
300)
libuv.uv_unref(self._signal_idle)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment