Commit d15664a5 authored by Jason Madden's avatar Jason Madden

Bump libuv to 1.21. Fixes #1244

parent 7420a0da
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
1.3.5 (unreleased) 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`. - Update Python versions tested on Travis, including PyPy to 6.0. See :issue:`1195`.
- :mod:`gevent.queue` imports ``_PySimpleQueue`` instead of - :mod:`gevent.queue` imports ``_PySimpleQueue`` instead of
......
...@@ -336,3 +336,10 @@ Bob Burger <rgburger@beckman.com> ...@@ -336,3 +336,10 @@ Bob Burger <rgburger@beckman.com>
Thomas Versteeg <thomasversteeg@gmx.com> Thomas Versteeg <thomasversteeg@gmx.com>
zzzjim <zzzjim@users.noreply.github.com> zzzjim <zzzjim@users.noreply.github.com>
Alex Arslan <ararslan@comcast.net> 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 ...@@ -137,7 +137,10 @@ $ git rebase upstream/v1.x # or upstream/master
### TEST ### TEST
Bug fixes and features should come with tests. Add your tests in the 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. - `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. - `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: Changes since version 1.20.0:
......
...@@ -14,6 +14,7 @@ libuv is currently managed by the following individuals: ...@@ -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) - GPG key: AF2E EA41 EC34 47BF DD86 FED9 D706 3CCE 19B7 E890 (pubkey-indutny)
* **Imran Iqbal** ([@iWuzHere](https://github.com/iWuzHere)) * **Imran Iqbal** ([@iWuzHere](https://github.com/iWuzHere))
- GPG key: 9DFE AA5F 481B BF77 2D90 03CE D592 4925 2F8E C41A (pubkey-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)) * **Santiago Gimeno** ([@santigimeno](https://github.com/santigimeno))
- GPG key: 612F 0EAD 9401 6223 79DF 4402 F28C 3C8D A33C 03BE (pubkey-santigimeno) - GPG key: 612F 0EAD 9401 6223 79DF 4402 F28C 3C8D A33C 03BE (pubkey-santigimeno)
* **Saúl Ibarra Corretgé** ([@saghul](https://github.com/saghul)) * **Saúl Ibarra Corretgé** ([@saghul](https://github.com/saghul))
......
...@@ -17,7 +17,10 @@ ACLOCAL_AMFLAGS = -I m4 ...@@ -17,7 +17,10 @@ ACLOCAL_AMFLAGS = -I m4
AM_CPPFLAGS = -I$(top_srcdir)/include \ AM_CPPFLAGS = -I$(top_srcdir)/include \
-I$(top_srcdir)/src -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 = CLEANFILES =
...@@ -42,7 +45,7 @@ endif ...@@ -42,7 +45,7 @@ endif
if WINNT 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 \ AM_CPPFLAGS += -I$(top_srcdir)/src/win \
-DWIN32_LEAN_AND_MEAN \ -DWIN32_LEAN_AND_MEAN \
-D_WIN32_WINNT=0x0600 -D_WIN32_WINNT=0x0600
...@@ -82,7 +85,7 @@ libuv_la_SOURCES += src/win/async.c \ ...@@ -82,7 +85,7 @@ libuv_la_SOURCES += src/win/async.c \
else # WINNT else # WINNT
include_HEADERS += include/uv-unix.h uvinclude_HEADERS += include/uv/unix.h
AM_CPPFLAGS += -I$(top_srcdir)/src/unix AM_CPPFLAGS += -I$(top_srcdir)/src/unix
libuv_la_SOURCES += src/unix/async.c \ libuv_la_SOURCES += src/unix/async.c \
src/unix/atomic-ops.h \ src/unix/atomic-ops.h \
...@@ -121,7 +124,6 @@ EXTRA_DIST = test/fixtures/empty_file \ ...@@ -121,7 +124,6 @@ EXTRA_DIST = test/fixtures/empty_file \
README.md \ README.md \
checksparse.sh \ checksparse.sh \
vcbuild.bat \ vcbuild.bat \
Makefile.mingw \
common.gypi \ common.gypi \
gyp_uv.py \ gyp_uv.py \
uv.gyp uv.gyp
...@@ -191,6 +193,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \ ...@@ -191,6 +193,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-idle.c \ test/test-idle.c \
test/test-ip4-addr.c \ test/test-ip4-addr.c \
test/test-ip6-addr.c \ test/test-ip6-addr.c \
test/test-ipc-heavy-traffic-deadlock-bug.c \
test/test-ipc-send-recv.c \ test/test-ipc-send-recv.c \
test/test-ipc.c \ test/test-ipc.c \
test/test-list.h \ test/test-list.h \
...@@ -332,19 +335,19 @@ libuv_la_CFLAGS += -D_ALL_SOURCE \ ...@@ -332,19 +335,19 @@ libuv_la_CFLAGS += -D_ALL_SOURCE \
-D_LINUX_SOURCE_COMPAT \ -D_LINUX_SOURCE_COMPAT \
-D_THREAD_SAFE \ -D_THREAD_SAFE \
-DHAVE_SYS_AHAFS_EVPRODS_H -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 libuv_la_SOURCES += src/unix/aix.c src/unix/aix-common.c
endif endif
if ANDROID if ANDROID
include_HEADERS += include/android-ifaddrs.h \ uvinclude_HEADERS += include/uv/android-ifaddrs.h \
include/pthread-barrier.h include/uv/pthread-barrier.h
libuv_la_SOURCES += src/unix/android-ifaddrs.c \ libuv_la_SOURCES += src/unix/android-ifaddrs.c \
src/unix/pthread-fixes.c src/unix/pthread-fixes.c
endif endif
if CYGWIN if CYGWIN
include_HEADERS += include/uv-posix.h uvinclude_HEADERS += include/uv/posix.h
libuv_la_CFLAGS += -D_GNU_SOURCE libuv_la_CFLAGS += -D_GNU_SOURCE
libuv_la_SOURCES += src/unix/cygwin.c \ libuv_la_SOURCES += src/unix/cygwin.c \
src/unix/bsd-ifaddrs.c \ src/unix/bsd-ifaddrs.c \
...@@ -358,8 +361,8 @@ libuv_la_SOURCES += src/unix/cygwin.c \ ...@@ -358,8 +361,8 @@ libuv_la_SOURCES += src/unix/cygwin.c \
endif endif
if DARWIN if DARWIN
include_HEADERS += include/uv-darwin.h \ uvinclude_HEADERS += include/uv/darwin.h \
include/pthread-barrier.h include/uv/pthread-barrier.h
libuv_la_CFLAGS += -D_DARWIN_USE_64_BIT_INODE=1 libuv_la_CFLAGS += -D_DARWIN_USE_64_BIT_INODE=1
libuv_la_CFLAGS += -D_DARWIN_UNLIMITED_SELECT=1 libuv_la_CFLAGS += -D_DARWIN_UNLIMITED_SELECT=1
libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \ libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \
...@@ -372,7 +375,7 @@ test_run_tests_LDFLAGS += -lutil ...@@ -372,7 +375,7 @@ test_run_tests_LDFLAGS += -lutil
endif endif
if DRAGONFLY if DRAGONFLY
include_HEADERS += include/uv-bsd.h uvinclude_HEADERS += include/uv/bsd.h
libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \ libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \
src/unix/freebsd.c \ src/unix/freebsd.c \
src/unix/kqueue.c \ src/unix/kqueue.c \
...@@ -381,7 +384,7 @@ test_run_tests_LDFLAGS += -lutil ...@@ -381,7 +384,7 @@ test_run_tests_LDFLAGS += -lutil
endif endif
if FREEBSD if FREEBSD
include_HEADERS += include/uv-bsd.h uvinclude_HEADERS += include/uv/bsd.h
libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \ libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \
src/unix/freebsd.c \ src/unix/freebsd.c \
src/unix/kqueue.c \ src/unix/kqueue.c \
...@@ -390,7 +393,7 @@ test_run_tests_LDFLAGS += -lutil ...@@ -390,7 +393,7 @@ test_run_tests_LDFLAGS += -lutil
endif endif
if LINUX if LINUX
include_HEADERS += include/uv-linux.h uvinclude_HEADERS += include/uv/linux.h
libuv_la_CFLAGS += -D_GNU_SOURCE libuv_la_CFLAGS += -D_GNU_SOURCE
libuv_la_SOURCES += src/unix/linux-core.c \ libuv_la_SOURCES += src/unix/linux-core.c \
src/unix/linux-inotify.c \ src/unix/linux-inotify.c \
...@@ -417,7 +420,7 @@ libuv_la_SOURCES += src/unix/cygwin.c \ ...@@ -417,7 +420,7 @@ libuv_la_SOURCES += src/unix/cygwin.c \
endif endif
if NETBSD if NETBSD
include_HEADERS += include/uv-bsd.h uvinclude_HEADERS += include/uv/bsd.h
libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \ libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \
src/unix/kqueue.c \ src/unix/kqueue.c \
src/unix/netbsd.c \ src/unix/netbsd.c \
...@@ -426,7 +429,7 @@ test_run_tests_LDFLAGS += -lutil ...@@ -426,7 +429,7 @@ test_run_tests_LDFLAGS += -lutil
endif endif
if OPENBSD if OPENBSD
include_HEADERS += include/uv-bsd.h uvinclude_HEADERS += include/uv/bsd.h
libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \ libuv_la_SOURCES += src/unix/bsd-ifaddrs.c \
src/unix/kqueue.c \ src/unix/kqueue.c \
src/unix/openbsd.c \ src/unix/openbsd.c \
...@@ -435,14 +438,14 @@ test_run_tests_LDFLAGS += -lutil ...@@ -435,14 +438,14 @@ test_run_tests_LDFLAGS += -lutil
endif endif
if SUNOS 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_CFLAGS += -D__EXTENSIONS__ -D_XOPEN_SOURCE=500
libuv_la_SOURCES += src/unix/no-proctitle.c \ libuv_la_SOURCES += src/unix/no-proctitle.c \
src/unix/sunos.c src/unix/sunos.c
endif endif
if OS390 if OS390
include_HEADERS += include/pthread-barrier.h uvinclude_HEADERS += include/uv/pthread-barrier.h
libuv_la_CFLAGS += -D_UNIX03_THREADS \ libuv_la_CFLAGS += -D_UNIX03_THREADS \
-D_UNIX03_SOURCE \ -D_UNIX03_SOURCE \
-D_OPEN_SYS_IF_EXT=1 \ -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 ...@@ -169,6 +169,16 @@ $ make check
$ make install $ 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: To build with GYP, first run:
```bash ```bash
...@@ -322,6 +332,13 @@ describes the package in more detail. ...@@ -322,6 +332,13 @@ describes the package in more detail.
AIX support for filesystem events is not compiled when building with `gyp`. 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 ## Patches
See the [guidelines for contributing][]. See the [guidelines for contributing][].
......
...@@ -26,8 +26,8 @@ SPARSE_FLAGS=${SPARSE_FLAGS:-" ...@@ -26,8 +26,8 @@ SPARSE_FLAGS=${SPARSE_FLAGS:-"
"} "}
SOURCES=" SOURCES="
include/tree.h include/uv/tree.h
include/uv-unix.h include/uv/unix.h
include/uv.h include/uv.h
src/fs-poll.c src/fs-poll.c
src/inet.c src/inet.c
...@@ -113,6 +113,7 @@ test/test-homedir.c ...@@ -113,6 +113,7 @@ test/test-homedir.c
test/test-hrtime.c test/test-hrtime.c
test/test-idle.c test/test-idle.c
test/test-ip6-addr.c test/test-ip6-addr.c
test/test-ipc-heavy-traffic-deadlock-bug.c
test/test-ipc-send-recv.c test/test-ipc-send-recv.c
test/test-ipc.c test/test-ipc.c
test/test-loop-handles.c test/test-loop-handles.c
...@@ -195,7 +196,7 @@ OS400) ...@@ -195,7 +196,7 @@ OS400)
Darwin) Darwin)
SPARSE_FLAGS="$SPARSE_FLAGS -D__APPLE__=1" SPARSE_FLAGS="$SPARSE_FLAGS -D__APPLE__=1"
SOURCES="$SOURCES SOURCES="$SOURCES
include/uv-bsd.h include/uv/bsd.h
src/unix/darwin.c src/unix/darwin.c
src/unix/kqueue.c src/unix/kqueue.c
src/unix/fsevents.c" src/unix/fsevents.c"
...@@ -203,21 +204,21 @@ Darwin) ...@@ -203,21 +204,21 @@ Darwin)
DragonFly) DragonFly)
SPARSE_FLAGS="$SPARSE_FLAGS -D__DragonFly__=1" SPARSE_FLAGS="$SPARSE_FLAGS -D__DragonFly__=1"
SOURCES="$SOURCES SOURCES="$SOURCES
include/uv-bsd.h include/uv/bsd.h
src/unix/kqueue.c src/unix/kqueue.c
src/unix/freebsd.c" src/unix/freebsd.c"
;; ;;
FreeBSD) FreeBSD)
SPARSE_FLAGS="$SPARSE_FLAGS -D__FreeBSD__=1" SPARSE_FLAGS="$SPARSE_FLAGS -D__FreeBSD__=1"
SOURCES="$SOURCES SOURCES="$SOURCES
include/uv-bsd.h include/uv/bsd.h
src/unix/kqueue.c src/unix/kqueue.c
src/unix/freebsd.c" src/unix/freebsd.c"
;; ;;
Linux) Linux)
SPARSE_FLAGS="$SPARSE_FLAGS -D__linux__=1" SPARSE_FLAGS="$SPARSE_FLAGS -D__linux__=1"
SOURCES="$SOURCES SOURCES="$SOURCES
include/uv-linux.h include/uv/linux.h
src/unix/linux-inotify.c src/unix/linux-inotify.c
src/unix/linux-core.c src/unix/linux-core.c
src/unix/linux-syscalls.c src/unix/linux-syscalls.c
...@@ -226,21 +227,21 @@ Linux) ...@@ -226,21 +227,21 @@ Linux)
NetBSD) NetBSD)
SPARSE_FLAGS="$SPARSE_FLAGS -D__NetBSD__=1" SPARSE_FLAGS="$SPARSE_FLAGS -D__NetBSD__=1"
SOURCES="$SOURCES SOURCES="$SOURCES
include/uv-bsd.h include/uv/bsd.h
src/unix/kqueue.c src/unix/kqueue.c
src/unix/netbsd.c" src/unix/netbsd.c"
;; ;;
OpenBSD) OpenBSD)
SPARSE_FLAGS="$SPARSE_FLAGS -D__OpenBSD__=1" SPARSE_FLAGS="$SPARSE_FLAGS -D__OpenBSD__=1"
SOURCES="$SOURCES SOURCES="$SOURCES
include/uv-bsd.h include/uv/bsd.h
src/unix/kqueue.c src/unix/kqueue.c
src/unix/openbsd.c" src/unix/openbsd.c"
;; ;;
SunOS) SunOS)
SPARSE_FLAGS="$SPARSE_FLAGS -D__sun=1" SPARSE_FLAGS="$SPARSE_FLAGS -D__sun=1"
SOURCES="$SOURCES SOURCES="$SOURCES
include/uv-sunos.h include/uv/sunos.h
src/unix/sunos.c" src/unix/sunos.c"
;; ;;
esac esac
......
...@@ -134,7 +134,7 @@ ...@@ -134,7 +134,7 @@
}] }]
] ]
}], }],
['OS in "freebsd dragonflybsd linux openbsd solaris android"', { ['OS in "freebsd dragonflybsd linux openbsd solaris android aix"', {
'cflags': [ '-Wall' ], 'cflags': [ '-Wall' ],
'cflags_cc': [ '-fno-rtti', '-fno-exceptions' ], 'cflags_cc': [ '-fno-rtti', '-fno-exceptions' ],
'target_conditions': [ 'target_conditions': [
...@@ -162,6 +162,10 @@ ...@@ -162,6 +162,10 @@
'cflags': [ '-pthread' ], 'cflags': [ '-pthread' ],
'ldflags': [ '-pthread' ], 'ldflags': [ '-pthread' ],
}], }],
[ 'OS=="aix" and target_arch=="ppc64"', {
'cflags': [ '-maix64' ],
'ldflags': [ '-maix64' ],
}],
], ],
}], }],
['OS=="mac"', { ['OS=="mac"', {
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
AC_PREREQ(2.57) 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]) AC_CONFIG_MACRO_DIR([m4])
m4_include([m4/libuv-extra-automake-flags.m4]) m4_include([m4/libuv-extra-automake-flags.m4])
m4_include([m4/as_case.m4]) m4_include([m4/as_case.m4])
......
...@@ -45,21 +45,21 @@ extern "C" { ...@@ -45,21 +45,21 @@ extern "C" {
# define UV_EXTERN /* nothing */ # define UV_EXTERN /* nothing */
#endif #endif
#include "uv-errno.h" #include "uv/errno.h"
#include "uv-version.h" #include "uv/version.h"
#include <stddef.h> #include <stddef.h>
#include <stdio.h> #include <stdio.h>
#if defined(_MSC_VER) && _MSC_VER < 1600 #if defined(_MSC_VER) && _MSC_VER < 1600
# include "stdint-msvc2008.h" # include "uv/stdint-msvc2008.h"
#else #else
# include <stdint.h> # include <stdint.h>
#endif #endif
#if defined(_WIN32) #if defined(_WIN32)
# include "uv-win.h" # include "uv/win.h"
#else #else
# include "uv-unix.h" # include "uv/unix.h"
#endif #endif
/* Expand this list if necessary. */ /* Expand this list if necessary. */
...@@ -142,6 +142,7 @@ extern "C" { ...@@ -142,6 +142,7 @@ extern "C" {
XX(EHOSTDOWN, "host is down") \ XX(EHOSTDOWN, "host is down") \
XX(EREMOTEIO, "remote I/O error") \ XX(EREMOTEIO, "remote I/O error") \
XX(ENOTTY, "inappropriate ioctl for device") \ XX(ENOTTY, "inappropriate ioctl for device") \
XX(EFTYPE, "inappropriate file type or format") \
#define UV_HANDLE_TYPE_MAP(XX) \ #define UV_HANDLE_TYPE_MAP(XX) \
XX(ASYNC, async) \ XX(ASYNC, async) \
...@@ -503,7 +504,7 @@ UV_EXTERN int uv_try_write(uv_stream_t* handle, ...@@ -503,7 +504,7 @@ UV_EXTERN int uv_try_write(uv_stream_t* handle,
struct uv_write_s { struct uv_write_s {
UV_REQ_FIELDS UV_REQ_FIELDS
uv_write_cb cb; 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_stream_t* handle;
UV_WRITE_PRIVATE_FIELDS UV_WRITE_PRIVATE_FIELDS
}; };
...@@ -865,7 +866,13 @@ typedef enum { ...@@ -865,7 +866,13 @@ typedef enum {
* flags may be specified to create a duplex data stream. * flags may be specified to create a duplex data stream.
*/ */
UV_READABLE_PIPE = 0x10, 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; } uv_stdio_flags;
typedef struct uv_stdio_container_s { typedef struct uv_stdio_container_s {
...@@ -997,16 +1004,18 @@ UV_EXTERN int uv_queue_work(uv_loop_t* loop, ...@@ -997,16 +1004,18 @@ UV_EXTERN int uv_queue_work(uv_loop_t* loop,
UV_EXTERN int uv_cancel(uv_req_t* req); 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 { struct uv_cpu_info_s {
char* model; char* model;
int speed; int speed;
struct uv_cpu_times_s { struct uv_cpu_times_s cpu_times;
uint64_t user;
uint64_t nice;
uint64_t sys;
uint64_t idle;
uint64_t irq;
} cpu_times;
}; };
struct uv_interface_address_s { struct uv_interface_address_s {
...@@ -1132,6 +1141,7 @@ typedef enum { ...@@ -1132,6 +1141,7 @@ typedef enum {
UV_FS_READLINK, UV_FS_READLINK,
UV_FS_CHOWN, UV_FS_CHOWN,
UV_FS_FCHOWN, UV_FS_FCHOWN,
UV_FS_LCHOWN,
UV_FS_REALPATH, UV_FS_REALPATH,
UV_FS_COPYFILE UV_FS_COPYFILE
} uv_fs_type; } uv_fs_type;
...@@ -1336,6 +1346,12 @@ UV_EXTERN int uv_fs_fchown(uv_loop_t* loop, ...@@ -1336,6 +1346,12 @@ UV_EXTERN int uv_fs_fchown(uv_loop_t* loop,
uv_uid_t uid, uv_uid_t uid,
uv_gid_t gid, uv_gid_t gid,
uv_fs_cb cb); 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 { enum uv_fs_event {
......
...@@ -433,5 +433,11 @@ ...@@ -433,5 +433,11 @@
# define UV__ENOTTY (-4029) # define UV__ENOTTY (-4029)
#endif #endif
#if defined(EFTYPE) && !defined(_WIN32)
# define UV__EFTYPE UV__ERR(EFTYPE)
#else
# define UV__EFTYPE (-4028)
#endif
#endif /* UV_ERRNO_H_ */ #endif /* UV_ERRNO_H_ */
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#ifndef UV_MVS_H #ifndef UV_MVS_H
#define UV_MVS_H #define UV_MVS_H
#define UV_PLATFORM_SEM_T int #define UV_PLATFORM_SEM_T long
#define UV_PLATFORM_LOOP_FIELDS \ #define UV_PLATFORM_LOOP_FIELDS \
void* ep; \ void* ep; \
......
...@@ -42,32 +42,32 @@ ...@@ -42,32 +42,32 @@
#include <pthread.h> #include <pthread.h>
#include <signal.h> #include <signal.h>
#include "uv-threadpool.h" #include "uv/threadpool.h"
#if defined(__linux__) #if defined(__linux__)
# include "uv-linux.h" # include "uv/linux.h"
#elif defined (__MVS__) #elif defined (__MVS__)
# include "uv-os390.h" # include "uv/os390.h"
#elif defined(__PASE__) #elif defined(__PASE__)
# include "uv-posix.h" # include "uv/posix.h"
#elif defined(_AIX) #elif defined(_AIX)
# include "uv-aix.h" # include "uv/aix.h"
#elif defined(__sun) #elif defined(__sun)
# include "uv-sunos.h" # include "uv/sunos.h"
#elif defined(__APPLE__) #elif defined(__APPLE__)
# include "uv-darwin.h" # include "uv/darwin.h"
#elif defined(__DragonFly__) || \ #elif defined(__DragonFly__) || \
defined(__FreeBSD__) || \ defined(__FreeBSD__) || \
defined(__FreeBSD_kernel__) || \ defined(__FreeBSD_kernel__) || \
defined(__OpenBSD__) || \ defined(__OpenBSD__) || \
defined(__NetBSD__) defined(__NetBSD__)
# include "uv-bsd.h" # include "uv/bsd.h"
#elif defined(__CYGWIN__) || defined(__MSYS__) #elif defined(__CYGWIN__) || defined(__MSYS__)
# include "uv-posix.h" # include "uv/posix.h"
#endif #endif
#ifndef PTHREAD_BARRIER_SERIAL_THREAD #ifndef PTHREAD_BARRIER_SERIAL_THREAD
# include "pthread-barrier.h" # include "uv/pthread-barrier.h"
#endif #endif
#ifndef NI_MAXHOST #ifndef NI_MAXHOST
......
...@@ -31,8 +31,8 @@ ...@@ -31,8 +31,8 @@
*/ */
#define UV_VERSION_MAJOR 1 #define UV_VERSION_MAJOR 1
#define UV_VERSION_MINOR 20 #define UV_VERSION_MINOR 21
#define UV_VERSION_PATCH 1 #define UV_VERSION_PATCH 0
#define UV_VERSION_IS_RELEASE 1 #define UV_VERSION_IS_RELEASE 1
#define UV_VERSION_SUFFIX "" #define UV_VERSION_SUFFIX ""
......
...@@ -53,13 +53,13 @@ typedef struct pollfd { ...@@ -53,13 +53,13 @@ typedef struct pollfd {
#include <sys/stat.h> #include <sys/stat.h>
#if defined(_MSC_VER) && _MSC_VER < 1600 #if defined(_MSC_VER) && _MSC_VER < 1600
# include "stdint-msvc2008.h" # include "uv/stdint-msvc2008.h"
#else #else
# include <stdint.h> # include <stdint.h>
#endif #endif
#include "tree.h" #include "uv/tree.h"
#include "uv-threadpool.h" #include "uv/threadpool.h"
#define MAX_PIPENAME_LEN 256 #define MAX_PIPENAME_LEN 256
...@@ -86,8 +86,8 @@ typedef struct pollfd { ...@@ -86,8 +86,8 @@ typedef struct pollfd {
#define SIGKILL 9 #define SIGKILL 9
#define SIGWINCH 28 #define SIGWINCH 28
/* The CRT defines SIGABRT_COMPAT as 6, which equals SIGABRT on many */ /* The CRT defines SIGABRT_COMPAT as 6, which equals SIGABRT on many unix-like
/* unix-like platforms. However MinGW doesn't define it, so we do. */ * platforms. However MinGW doesn't define it, so we do. */
#ifndef SIGABRT_COMPAT #ifndef SIGABRT_COMPAT
# define SIGABRT_COMPAT 6 # define SIGABRT_COMPAT 6
#endif #endif
...@@ -244,7 +244,7 @@ typedef union { ...@@ -244,7 +244,7 @@ typedef union {
CRITICAL_SECTION waiters_count_lock; CRITICAL_SECTION waiters_count_lock;
HANDLE signal_event; HANDLE signal_event;
HANDLE broadcast_event; HANDLE broadcast_event;
} fallback; } unused_; /* TODO: retained for ABI compatibility; remove me in v2.x. */
} uv_cond_t; } uv_cond_t;
typedef union { typedef union {
...@@ -368,10 +368,10 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s); ...@@ -368,10 +368,10 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
} u; \ } u; \
struct uv_req_s* next_req; struct uv_req_s* next_req;
#define UV_WRITE_PRIVATE_FIELDS \ #define UV_WRITE_PRIVATE_FIELDS \
int ipc_header; \ int coalesced; \
uv_buf_t write_buffer; \ uv_buf_t write_buffer; \
HANDLE event_handle; \ HANDLE event_handle; \
HANDLE wait_handle; HANDLE wait_handle;
#define UV_CONNECT_PRIVATE_FIELDS \ #define UV_CONNECT_PRIVATE_FIELDS \
...@@ -459,16 +459,17 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s); ...@@ -459,16 +459,17 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
#define uv_pipe_connection_fields \ #define uv_pipe_connection_fields \
uv_timer_t* eof_timer; \ uv_timer_t* eof_timer; \
uv_write_t ipc_header_write_req; \ uv_write_t dummy; /* TODO: retained for ABI compat; remove this in v2.x. */ \
int ipc_pid; \ DWORD ipc_remote_pid; \
uint64_t remaining_ipc_rawdata_bytes; \ union { \
struct { \ uint32_t payload_remaining; \
void* queue[2]; \ uint64_t dummy; /* TODO: retained for ABI compat; remove this in v2.x. */ \
int queue_len; \ } ipc_data_frame; \
} pending_ipc_info; \ void* ipc_xfer_queue[2]; \
int ipc_xfer_queue_length; \
uv_write_t* non_overlapped_writes_tail; \ uv_write_t* non_overlapped_writes_tail; \
uv_mutex_t readfile_mutex; \ CRITICAL_SECTION readfile_thread_lock; \
volatile HANDLE readfile_thread; volatile HANDLE readfile_thread_handle;
#define UV_PIPE_PRIVATE_FIELDS \ #define UV_PIPE_PRIVATE_FIELDS \
HANDLE handle; \ HANDLE handle; \
...@@ -478,8 +479,8 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s); ...@@ -478,8 +479,8 @@ RB_HEAD(uv_timer_tree_s, uv_timer_s);
struct { uv_pipe_connection_fields } conn; \ struct { uv_pipe_connection_fields } conn; \
} pipe; } pipe;
/* TODO: put the parser states in an union - TTY handles are always */ /* TODO: put the parser states in an union - TTY handles are always half-duplex
/* half-duplex so read-state can safely overlap write-state. */ * so read-state can safely overlap write-state. */
#define UV_TTY_PRIVATE_FIELDS \ #define UV_TTY_PRIVATE_FIELDS \
HANDLE handle; \ HANDLE handle; \
union { \ union { \
......
...@@ -3,7 +3,7 @@ exec_prefix=${prefix} ...@@ -3,7 +3,7 @@ exec_prefix=${prefix}
libdir=@libdir@ libdir=@libdir@
includedir=@includedir@ includedir=@includedir@
Name: @PACKAGE_NAME@ Name: libuv
Version: @PACKAGE_VERSION@ Version: @PACKAGE_VERSION@
Description: multi-platform support library with a focus on asynchronous I/O. Description: multi-platform support library with a focus on asynchronous I/O.
URL: http://libuv.org/ URL: http://libuv.org/
......
dnl Macros to check the presence of generic (non-typed) symbols. 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 Copyright (c) 2006-2008 xine project
dnl dnl
dnl This program is free software; you can redistribute it and/or modify dnl This program is free software; you can redistribute it and/or modify
...@@ -316,4 +316,4 @@ AC_DEFUN([CC_ATTRIBUTE_ALIGNED], [ ...@@ -316,4 +316,4 @@ AC_DEFUN([CC_ATTRIBUTE_ALIGNED], [
AC_DEFINE_UNQUOTED([ATTRIBUTE_ALIGNED_MAX], [$cc_cv_attribute_aligned], AC_DEFINE_UNQUOTED([ATTRIBUTE_ALIGNED_MAX], [$cc_cv_attribute_aligned],
[Define the highest alignment supported]) [Define the highest alignment supported])
fi fi
]) ])
\ No newline at end of file
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
#include <string.h> #include <string.h>
#if defined(_MSC_VER) && _MSC_VER < 1600 #if defined(_MSC_VER) && _MSC_VER < 1600
# include "stdint-msvc2008.h" # include "uv/stdint-msvc2008.h"
#else #else
# include <stdint.h> # include <stdint.h>
#endif #endif
......
...@@ -23,7 +23,7 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ...@@ -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. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "android-ifaddrs.h" #include "uv/android-ifaddrs.h"
#include "uv-common.h" #include "uv-common.h"
#include <string.h> #include <string.h>
......
...@@ -174,8 +174,8 @@ void uv_close(uv_handle_t* handle, uv_close_cb close_cb) { ...@@ -174,8 +174,8 @@ void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
case UV_SIGNAL: case UV_SIGNAL:
uv__signal_close((uv_signal_t*) handle); uv__signal_close((uv_signal_t*) handle);
/* Signal handles may not be closed immediately. The signal code will */ /* Signal handles may not be closed immediately. The signal code will
/* itself close uv__make_close_pending whenever appropriate. */ * itself close uv__make_close_pending whenever appropriate. */
return; return;
default: default:
...@@ -927,6 +927,11 @@ int uv__io_active(const uv__io_t* w, unsigned int events) { ...@@ -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) { int uv_getrusage(uv_rusage_t* rusage) {
struct rusage usage; struct rusage usage;
......
...@@ -865,9 +865,11 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) { ...@@ -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 /* 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 this is a force clone then exit. Otherwise, fall through to try using
sendfile(). */ sendfile(). */
if ((errno != ENOTTY && errno != EOPNOTSUPP && errno != EXDEV) || if (errno != ENOTTY && errno != EOPNOTSUPP && errno != EXDEV) {
req->flags & UV_FS_COPYFILE_FICLONE_FORCE) { err = UV__ERR(errno);
err = -errno; goto out;
} else if (req->flags & UV_FS_COPYFILE_FICLONE_FORCE) {
err = UV_ENOTSUP;
goto out; goto out;
} }
} else { } else {
...@@ -927,7 +929,11 @@ out: ...@@ -927,7 +929,11 @@ out:
} }
} }
return result; if (result == 0)
return 0;
errno = UV__ERR(result);
return -1;
#endif #endif
} }
...@@ -1114,6 +1120,7 @@ static void uv__fs_work(struct uv__work* w) { ...@@ -1114,6 +1120,7 @@ static void uv__fs_work(struct uv__work* w) {
X(COPYFILE, uv__fs_copyfile(req)); X(COPYFILE, uv__fs_copyfile(req));
X(FCHMOD, fchmod(req->file, req->mode)); X(FCHMOD, fchmod(req->file, req->mode));
X(FCHOWN, fchown(req->file, req->uid, req->gid)); 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(FDATASYNC, uv__fs_fdatasync(req));
X(FSTAT, uv__fs_fstat(req->file, &req->statbuf)); X(FSTAT, uv__fs_fstat(req->file, &req->statbuf));
X(FSYNC, uv__fs_fsync(req)); X(FSYNC, uv__fs_fsync(req));
...@@ -1240,6 +1247,20 @@ int uv_fs_fchown(uv_loop_t* loop, ...@@ -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) { int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file file, uv_fs_cb cb) {
INIT(FDATASYNC); INIT(FDATASYNC);
req->file = file; req->file = file;
......
...@@ -185,6 +185,18 @@ struct uv__stream_queued_fds_s { ...@@ -185,6 +185,18 @@ struct uv__stream_queued_fds_s {
#define uv__nonblock uv__nonblock_fcntl #define uv__nonblock uv__nonblock_fcntl
#endif #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 */ /* core */
int uv__cloexec_ioctl(int fd, int set); int uv__cloexec_ioctl(int fd, int set);
int uv__cloexec_fcntl(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); ...@@ -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); 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 */ void uv__io_poll(uv_loop_t* loop, int timeout); /* in milliseconds or -1 */
int uv__io_fork(uv_loop_t* loop); int uv__io_fork(uv_loop_t* loop);
int uv__fd_exists(uv_loop_t* loop, int fd);
/* async */ /* async */
void uv__async_stop(uv_loop_t* loop); void uv__async_stop(uv_loop_t* loop);
......
...@@ -261,8 +261,8 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { ...@@ -261,8 +261,8 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
w = loop->watchers[fd]; w = loop->watchers[fd];
if (w == NULL) { if (w == NULL) {
/* File descriptor that we've stopped watching, disarm it. */ /* File descriptor that we've stopped watching, disarm it.
/* TODO batch up */ * TODO: batch up. */
struct kevent events[1]; struct kevent events[1];
EV_SET(events + 0, fd, ev->filter, EV_DELETE, 0, 0, 0); EV_SET(events + 0, fd, ev->filter, EV_DELETE, 0, 0, 0);
......
...@@ -51,7 +51,7 @@ ...@@ -51,7 +51,7 @@
#ifdef HAVE_IFADDRS_H #ifdef HAVE_IFADDRS_H
# if defined(__ANDROID__) # if defined(__ANDROID__)
# include "android-ifaddrs.h" # include "uv/android-ifaddrs.h"
# else # else
# include <ifaddrs.h> # include <ifaddrs.h>
# endif # endif
...@@ -388,7 +388,8 @@ void uv__io_poll(uv_loop_t* loop, int timeout) { ...@@ -388,7 +388,8 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
* free when we switch over to edge-triggered I/O. * free when we switch over to edge-triggered I/O.
*/ */
if (pe->events == POLLERR || pe->events == POLLHUP) 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) { if (pe->events != 0) {
/* Run signal watchers last. This also affects child process watchers /* Run signal watchers last. This also affects child process watchers
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
*/ */
#include "uv.h" #include "uv.h"
#include "tree.h" #include "uv/tree.h"
#include "internal.h" #include "internal.h"
#include <stdint.h> #include <stdint.h>
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
*/ */
#include "uv.h" #include "uv.h"
#include "tree.h" #include "uv/tree.h"
#include "internal.h" #include "internal.h"
#include "heap-inl.h" #include "heap-inl.h"
#include <stdlib.h> #include <stdlib.h>
......
...@@ -215,6 +215,7 @@ uv__os390_epoll* epoll_create1(int flags) { ...@@ -215,6 +215,7 @@ uv__os390_epoll* epoll_create1(int flags) {
maybe_resize(lst, 1); maybe_resize(lst, 1);
lst->items[lst->size - 1].fd = lst->msg_queue; lst->items[lst->size - 1].fd = lst->msg_queue;
lst->items[lst->size - 1].events = POLLIN; lst->items[lst->size - 1].events = POLLIN;
lst->items[lst->size - 1].revents = 0;
uv_once(&once, epoll_init); uv_once(&once, epoll_init);
uv_mutex_lock(&global_epoll_lock); uv_mutex_lock(&global_epoll_lock);
QUEUE_INSERT_TAIL(&global_epoll_queue, &lst->member); QUEUE_INSERT_TAIL(&global_epoll_queue, &lst->member);
...@@ -252,6 +253,7 @@ int epoll_ctl(uv__os390_epoll* lst, ...@@ -252,6 +253,7 @@ int epoll_ctl(uv__os390_epoll* lst,
} }
lst->items[fd].fd = fd; lst->items[fd].fd = fd;
lst->items[fd].events = event->events; lst->items[fd].events = event->events;
lst->items[fd].revents = 0;
} else if (op == EPOLL_CTL_MOD) { } else if (op == EPOLL_CTL_MOD) {
if (fd >= lst->size || lst->items[fd].fd == -1) { if (fd >= lst->size || lst->items[fd].fd == -1) {
uv_mutex_unlock(&global_epoll_lock); uv_mutex_unlock(&global_epoll_lock);
......
...@@ -134,6 +134,9 @@ void uv__pipe_close(uv_pipe_t* handle) { ...@@ -134,6 +134,9 @@ void uv__pipe_close(uv_pipe_t* handle) {
int uv_pipe_open(uv_pipe_t* handle, uv_file fd) { int uv_pipe_open(uv_pipe_t* handle, uv_file fd) {
int err; int err;
if (uv__fd_exists(handle->loop, fd))
return UV_EEXIST;
err = uv__nonblock(fd, 1); err = uv__nonblock(fd, 1);
if (err) if (err)
return err; return err;
......
...@@ -68,6 +68,9 @@ static void uv__poll_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) { ...@@ -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 uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) {
int err; int err;
if (uv__fd_exists(loop, fd))
return UV_EEXIST;
err = uv__io_check_fd(loop, fd); err = uv__io_check_fd(loop, fd);
if (err) if (err)
return err; return err;
......
...@@ -54,8 +54,7 @@ static void uv__signal_unregister_handler(int signum); ...@@ -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 uv_once_t uv__signal_global_init_guard = UV_ONCE_INIT;
static struct uv__signal_tree_s uv__signal_tree = static struct uv__signal_tree_s uv__signal_tree =
RB_INITIALIZER(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, RB_GENERATE_STATIC(uv__signal_tree_s,
uv_signal_s, tree_entry, uv_signal_s, tree_entry,
...@@ -64,7 +63,7 @@ RB_GENERATE_STATIC(uv__signal_tree_s, ...@@ -64,7 +63,7 @@ RB_GENERATE_STATIC(uv__signal_tree_s,
static void uv__signal_global_reinit(void); static void uv__signal_global_reinit(void);
static void uv__signal_global_init(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 /* pthread_atfork can register before and after handlers, one
* for each child. This only registers one for the child. That * for each child. This only registers one for the child. That
* state is both persistent and cumulative, so if we keep doing * state is both persistent and cumulative, so if we keep doing
...@@ -74,15 +73,11 @@ static void uv__signal_global_init(void) { ...@@ -74,15 +73,11 @@ static void uv__signal_global_init(void) {
if (pthread_atfork(NULL, NULL, &uv__signal_global_reinit)) if (pthread_atfork(NULL, NULL, &uv__signal_global_reinit))
abort(); abort();
if (uv__make_pipe(uv__signal_lock_pipefd, 0)) uv__signal_global_reinit();
abort();
if (uv__signal_unlock())
abort();
} }
static void uv__signal_global_reinit(void) { UV_DESTRUCTOR(static void uv__signal_global_fini(void)) {
/* We can only use signal-safe functions here. /* We can only use signal-safe functions here.
* That includes read/write and close, fortunately. * That includes read/write and close, fortunately.
* We do all of this directly here instead of resetting * We do all of this directly here instead of resetting
...@@ -90,11 +85,26 @@ static void uv__signal_global_reinit(void) { ...@@ -90,11 +85,26 @@ static void uv__signal_global_reinit(void) {
* uv__signal_global_once_init is only called from uv_loop_init * uv__signal_global_once_init is only called from uv_loop_init
* and this needs to function in existing loops. * and this needs to function in existing loops.
*/ */
uv__close(uv__signal_lock_pipefd[0]); if (uv__signal_lock_pipefd[0] != -1) {
uv__signal_lock_pipefd[0] = -1; uv__close(uv__signal_lock_pipefd[0]);
uv__close(uv__signal_lock_pipefd[1]); uv__signal_lock_pipefd[0] = -1;
uv__signal_lock_pipefd[1] = -1; }
uv__signal_global_init();
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) { ...@@ -103,7 +113,6 @@ void uv__signal_global_once_init(void) {
} }
static int uv__signal_lock(void) { static int uv__signal_lock(void) {
int r; int r;
char data; char data;
......
...@@ -1121,6 +1121,7 @@ static int uv__stream_recv_cmsg(uv_stream_t* stream, struct msghdr* msg) { ...@@ -1121,6 +1121,7 @@ static int uv__stream_recv_cmsg(uv_stream_t* stream, struct msghdr* msg) {
#ifdef __clang__ #ifdef __clang__
# pragma clang diagnostic push # pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wgnu-folding-constant" # pragma clang diagnostic ignored "-Wgnu-folding-constant"
# pragma clang diagnostic ignored "-Wvla-extension"
#endif #endif
static void uv__read(uv_stream_t* stream) { 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) { ...@@ -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); 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)) if (events & (POLLIN | POLLERR | POLLHUP))
uv__read(stream); uv__read(stream);
......
...@@ -263,6 +263,9 @@ int uv__tcp_connect(uv_connect_t* req, ...@@ -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 uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock) {
int err; int err;
if (uv__fd_exists(handle->loop, sock))
return UV_EEXIST;
err = uv__nonblock(sock, 1); err = uv__nonblock(sock, 1);
if (err) if (err)
return err; return err;
......
...@@ -423,87 +423,6 @@ int uv_sem_trywait(uv_sem_t* sem) { ...@@ -423,87 +423,6 @@ int uv_sem_trywait(uv_sem_t* sem) {
return UV_EINVAL; /* Satisfy the compiler. */ 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__)) */ #else /* !(defined(__APPLE__) && defined(__MACH__)) */
#ifdef __GLIBC__ #ifdef __GLIBC__
...@@ -517,18 +436,22 @@ int uv_sem_trywait(uv_sem_t* sem) { ...@@ -517,18 +436,22 @@ int uv_sem_trywait(uv_sem_t* sem) {
* a pointer to the actual struct we're using underneath. */ * a pointer to the actual struct we're using underneath. */
static uv_once_t glibc_version_check_once = UV_ONCE_INIT; 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) { static void glibc_version_check(void) {
const char* version = gnu_get_libc_version(); const char* version = gnu_get_libc_version();
glibc_needs_custom_semaphore = platform_needs_custom_semaphore =
version[0] == '2' && version[1] == '.' && version[0] == '2' && version[1] == '.' &&
atoi(version + 2) < 21; 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 #endif
...@@ -538,8 +461,9 @@ typedef struct uv_semaphore_s { ...@@ -538,8 +461,9 @@ typedef struct uv_semaphore_s {
unsigned int value; unsigned int value;
} uv_semaphore_t; } uv_semaphore_t;
#if defined(__GLIBC__) || platform_needs_custom_semaphore
STATIC_ASSERT(sizeof(uv_sem_t) >= sizeof(uv_semaphore_t*)); STATIC_ASSERT(sizeof(uv_sem_t) >= sizeof(uv_semaphore_t*));
#endif
static int uv__custom_sem_init(uv_sem_t* sem_, unsigned int value) { static int uv__custom_sem_init(uv_sem_t* sem_, unsigned int value) {
int err; int err;
...@@ -670,7 +594,7 @@ int uv_sem_init(uv_sem_t* sem, unsigned int value) { ...@@ -670,7 +594,7 @@ int uv_sem_init(uv_sem_t* sem, unsigned int value) {
uv_once(&glibc_version_check_once, glibc_version_check); uv_once(&glibc_version_check_once, glibc_version_check);
#endif #endif
if (glibc_needs_custom_semaphore) if (platform_needs_custom_semaphore)
return uv__custom_sem_init(sem, value); return uv__custom_sem_init(sem, value);
else else
return uv__sem_init(sem, value); return uv__sem_init(sem, value);
...@@ -678,7 +602,7 @@ int uv_sem_init(uv_sem_t* sem, unsigned int value) { ...@@ -678,7 +602,7 @@ int uv_sem_init(uv_sem_t* sem, unsigned int value) {
void uv_sem_destroy(uv_sem_t* sem) { void uv_sem_destroy(uv_sem_t* sem) {
if (glibc_needs_custom_semaphore) if (platform_needs_custom_semaphore)
uv__custom_sem_destroy(sem); uv__custom_sem_destroy(sem);
else else
uv__sem_destroy(sem); uv__sem_destroy(sem);
...@@ -686,7 +610,7 @@ void uv_sem_destroy(uv_sem_t* sem) { ...@@ -686,7 +610,7 @@ void uv_sem_destroy(uv_sem_t* sem) {
void uv_sem_post(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); uv__custom_sem_post(sem);
else else
uv__sem_post(sem); uv__sem_post(sem);
...@@ -694,7 +618,7 @@ void uv_sem_post(uv_sem_t* sem) { ...@@ -694,7 +618,7 @@ void uv_sem_post(uv_sem_t* sem) {
void uv_sem_wait(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); uv__custom_sem_wait(sem);
else else
uv__sem_wait(sem); uv__sem_wait(sem);
...@@ -702,7 +626,7 @@ void uv_sem_wait(uv_sem_t* sem) { ...@@ -702,7 +626,7 @@ void uv_sem_wait(uv_sem_t* sem) {
int uv_sem_trywait(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); return uv__custom_sem_trywait(sem);
else else
return uv__sem_trywait(sem); return uv__sem_trywait(sem);
......
...@@ -624,6 +624,9 @@ int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) { ...@@ -624,6 +624,9 @@ int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
if (handle->io_watcher.fd != -1) if (handle->io_watcher.fd != -1)
return UV_EBUSY; return UV_EBUSY;
if (uv__fd_exists(handle->loop, sock))
return UV_EEXIST;
err = uv__nonblock(sock, 1); err = uv__nonblock(sock, 1);
if (err) if (err)
return err; return err;
......
...@@ -32,13 +32,13 @@ ...@@ -32,13 +32,13 @@
#include <stddef.h> #include <stddef.h>
#if defined(_MSC_VER) && _MSC_VER < 1600 #if defined(_MSC_VER) && _MSC_VER < 1600
# include "stdint-msvc2008.h" # include "uv/stdint-msvc2008.h"
#else #else
# include <stdint.h> # include <stdint.h>
#endif #endif
#include "uv.h" #include "uv.h"
#include "tree.h" #include "uv/tree.h"
#include "queue.h" #include "queue.h"
#if EDOM > 0 #if EDOM > 0
......
...@@ -71,8 +71,8 @@ int uv_async_send(uv_async_t* handle) { ...@@ -71,8 +71,8 @@ int uv_async_send(uv_async_t* handle) {
return -1; return -1;
} }
/* The user should make sure never to call uv_async_send to a closing */ /* The user should make sure never to call uv_async_send to a closing or
/* or closed handle. */ * closed handle. */
assert(!(handle->flags & UV__HANDLE_CLOSING)); assert(!(handle->flags & UV__HANDLE_CLOSING));
if (!uv__atomic_exchange_set(&handle->async_sent)) { if (!uv__atomic_exchange_set(&handle->async_sent)) {
......
...@@ -29,10 +29,10 @@ ...@@ -29,10 +29,10 @@
/* Atomic set operation on char */ /* Atomic set operation on char */
#ifdef _MSC_VER /* MSVC */ #ifdef _MSC_VER /* MSVC */
/* _InterlockedOr8 is supported by MSVC on x32 and x64. It is slightly less */ /* _InterlockedOr8 is supported by MSVC on x32 and x64. It is slightly less
/* efficient than InterlockedExchange, but InterlockedExchange8 does not */ * efficient than InterlockedExchange, but InterlockedExchange8 does not exist,
/* exist, and interlocked operations on larger targets might require the */ * and interlocked operations on larger targets might require the target to be
/* target to be aligned. */ * aligned. */
#pragma intrinsic(_InterlockedOr8) #pragma intrinsic(_InterlockedOr8)
static char INLINE uv__atomic_exchange_set(char volatile* target) { static char INLINE uv__atomic_exchange_set(char volatile* target) {
......
...@@ -359,58 +359,7 @@ int uv_backend_timeout(const uv_loop_t* loop) { ...@@ -359,58 +359,7 @@ int uv_backend_timeout(const uv_loop_t* loop) {
} }
static void uv_poll(uv_loop_t* loop, DWORD timeout) { 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) {
BOOL success; BOOL success;
uv_req_t* req; uv_req_t* req;
OVERLAPPED_ENTRY overlappeds[128]; OVERLAPPED_ENTRY overlappeds[128];
...@@ -422,12 +371,12 @@ static void uv_poll_ex(uv_loop_t* loop, DWORD timeout) { ...@@ -422,12 +371,12 @@ static void uv_poll_ex(uv_loop_t* loop, DWORD timeout) {
timeout_time = loop->time + timeout; timeout_time = loop->time + timeout;
for (repeat = 0; ; repeat++) { for (repeat = 0; ; repeat++) {
success = pGetQueuedCompletionStatusEx(loop->iocp, success = GetQueuedCompletionStatusEx(loop->iocp,
overlappeds, overlappeds,
ARRAY_SIZE(overlappeds), ARRAY_SIZE(overlappeds),
&count, &count,
timeout, timeout,
FALSE); FALSE);
if (success) { if (success) {
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
...@@ -485,12 +434,6 @@ int uv_run(uv_loop_t *loop, uv_run_mode mode) { ...@@ -485,12 +434,6 @@ int uv_run(uv_loop_t *loop, uv_run_mode mode) {
DWORD timeout; DWORD timeout;
int r; int r;
int ran_pending; 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); r = uv__loop_alive(loop);
if (!r) if (!r)
...@@ -508,7 +451,7 @@ int uv_run(uv_loop_t *loop, uv_run_mode mode) { ...@@ -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) if ((mode == UV_RUN_ONCE && !ran_pending) || mode == UV_RUN_DEFAULT)
timeout = uv_backend_timeout(loop); timeout = uv_backend_timeout(loop);
(*poll)(loop, timeout); uv__poll(loop, timeout);
uv_check_invoke(loop); uv_check_invoke(loop);
uv_process_endgames(loop); uv_process_endgames(loop);
......
...@@ -46,8 +46,8 @@ void uv_fatal_error(const int errorno, const char* syscall) { ...@@ -46,8 +46,8 @@ void uv_fatal_error(const int errorno, const char* syscall) {
errmsg = "Unknown error"; errmsg = "Unknown error";
} }
/* FormatMessage messages include a newline character already, */ /* FormatMessage messages include a newline character already, so don't add
/* so don't add another. */ * another. */
if (syscall) { if (syscall) {
fprintf(stderr, "%s: (%d) %s", syscall, errorno, errmsg); fprintf(stderr, "%s: (%d) %s", syscall, errorno, errmsg);
} else { } else {
......
...@@ -326,12 +326,11 @@ INLINE static int fs__readlink_handle(HANDLE handle, char** target_ptr, ...@@ -326,12 +326,11 @@ INLINE static int fs__readlink_handle(HANDLE handle, char** target_ptr,
reparse_data->SymbolicLinkReparseBuffer.SubstituteNameLength / reparse_data->SymbolicLinkReparseBuffer.SubstituteNameLength /
sizeof(WCHAR); sizeof(WCHAR);
/* Real symlinks can contain pretty much everything, but the only thing */ /* Real symlinks can contain pretty much everything, but the only thing we
/* we really care about is undoing the implicit conversion to an NT */ * really care about is undoing the implicit conversion to an NT namespaced
/* namespaced path that CreateSymbolicLink will perform on absolute */ * path that CreateSymbolicLink will perform on absolute paths. If the path
/* paths. If the path is win32-namespaced then the user must have */ * is win32-namespaced then the user must have explicitly made it so, and
/* explicitly made it so, and we better just return the unmodified */ * we better just return the unmodified reparse data. */
/* reparse data. */
if (w_target_len >= 4 && if (w_target_len >= 4 &&
w_target[0] == L'\\' && w_target[0] == L'\\' &&
w_target[1] == L'?' && w_target[1] == L'?' &&
...@@ -352,8 +351,8 @@ INLINE static int fs__readlink_handle(HANDLE handle, char** target_ptr, ...@@ -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[5] == L'N' || w_target[5] == L'n') &&
(w_target[6] == L'C' || w_target[6] == L'c') && (w_target[6] == L'C' || w_target[6] == L'c') &&
w_target[7] == L'\\') { w_target[7] == L'\\') {
/* \??\UNC\<server>\<share>\ - make sure the final path looks like */ /* \??\UNC\<server>\<share>\ - make sure the final path looks like
/* \\<server>\<share>\ */ * \\<server>\<share>\ */
w_target += 6; w_target += 6;
w_target[0] = L'\\'; w_target[0] = L'\\';
w_target_len -= 6; w_target_len -= 6;
...@@ -368,11 +367,11 @@ INLINE static int fs__readlink_handle(HANDLE handle, char** target_ptr, ...@@ -368,11 +367,11 @@ INLINE static int fs__readlink_handle(HANDLE handle, char** target_ptr,
w_target_len = reparse_data->MountPointReparseBuffer.SubstituteNameLength / w_target_len = reparse_data->MountPointReparseBuffer.SubstituteNameLength /
sizeof(WCHAR); sizeof(WCHAR);
/* Only treat junctions that look like \??\<drive>:\ as symlink. */ /* Only treat junctions that look like \??\<drive>:\ as symlink. Junctions
/* Junctions can also be used as mount points, like \??\Volume{<guid>}, */ * can also be used as mount points, like \??\Volume{<guid>}, but that's
/* but that's confusing for programs since they wouldn't be able to */ * confusing for programs since they wouldn't be able to actually
/* actually understand such a path when returned by uv_readlink(). */ * understand such a path when returned by uv_readlink(). UNC paths are
/* UNC paths are never valid for junctions so we don't care about them. */ * never valid for junctions so we don't care about them. */
if (!(w_target_len >= 6 && if (!(w_target_len >= 6 &&
w_target[0] == L'\\' && w_target[0] == L'\\' &&
w_target[1] == L'?' && w_target[1] == L'?' &&
...@@ -409,8 +408,8 @@ void fs__open(uv_fs_t* req) { ...@@ -409,8 +408,8 @@ void fs__open(uv_fs_t* req) {
int fd, current_umask; int fd, current_umask;
int flags = req->fs.info.file_flags; int flags = req->fs.info.file_flags;
/* Obtain the active umask. umask() never fails and returns the previous */ /* Obtain the active umask. umask() never fails and returns the previous
/* umask. */ * umask. */
current_umask = umask(0); current_umask = umask(0);
umask(current_umask); umask(current_umask);
...@@ -530,8 +529,8 @@ void fs__open(uv_fs_t* req) { ...@@ -530,8 +529,8 @@ void fs__open(uv_fs_t* req) {
DWORD error = GetLastError(); DWORD error = GetLastError();
if (error == ERROR_FILE_EXISTS && (flags & UV_FS_O_CREAT) && if (error == ERROR_FILE_EXISTS && (flags & UV_FS_O_CREAT) &&
!(flags & UV_FS_O_EXCL)) { !(flags & UV_FS_O_EXCL)) {
/* Special case: when ERROR_FILE_EXISTS happens and UV_FS_O_CREAT was */ /* Special case: when ERROR_FILE_EXISTS happens and UV_FS_O_CREAT was
/* specified, it means the path referred to a directory. */ * specified, it means the path referred to a directory. */
SET_REQ_UV_ERROR(req, UV_EISDIR, error); SET_REQ_UV_ERROR(req, UV_EISDIR, error);
} else { } else {
SET_REQ_WIN32_ERROR(req, GetLastError()); SET_REQ_WIN32_ERROR(req, GetLastError());
...@@ -756,9 +755,9 @@ void fs__unlink(uv_fs_t* req) { ...@@ -756,9 +755,9 @@ void fs__unlink(uv_fs_t* req) {
} }
if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
/* Do not allow deletion of directories, unless it is a symlink. When */ /* Do not allow deletion of directories, unless it is a symlink. When the
/* the path refers to a non-symlink directory, report EPERM as mandated */ * path refers to a non-symlink directory, report EPERM as mandated by
/* by POSIX.1. */ * POSIX.1. */
/* Check if it is a reparse point. If it's not, it's a normal directory. */ /* Check if it is a reparse point. If it's not, it's a normal directory. */
if (!(info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { if (!(info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
...@@ -767,8 +766,8 @@ void fs__unlink(uv_fs_t* req) { ...@@ -767,8 +766,8 @@ void fs__unlink(uv_fs_t* req) {
return; return;
} }
/* Read the reparse point and check if it is a valid symlink. */ /* Read the reparse point and check if it is a valid symlink. If not, don't
/* If not, don't unlink. */ * unlink. */
if (fs__readlink_handle(handle, NULL, NULL) < 0) { if (fs__readlink_handle(handle, NULL, NULL) < 0) {
DWORD error = GetLastError(); DWORD error = GetLastError();
if (error == ERROR_SYMLINK_NOT_SUPPORTED) if (error == ERROR_SYMLINK_NOT_SUPPORTED)
...@@ -1490,6 +1489,7 @@ static void fs__chmod(uv_fs_t* req) { ...@@ -1490,6 +1489,7 @@ static void fs__chmod(uv_fs_t* req) {
static void fs__fchmod(uv_fs_t* req) { static void fs__fchmod(uv_fs_t* req) {
int fd = req->file.fd; int fd = req->file.fd;
int clear_archive_flag;
HANDLE handle; HANDLE handle;
NTSTATUS nt_status; NTSTATUS nt_status;
IO_STATUS_BLOCK io_status; IO_STATUS_BLOCK io_status;
...@@ -1497,7 +1497,11 @@ static void fs__fchmod(uv_fs_t* req) { ...@@ -1497,7 +1497,11 @@ static void fs__fchmod(uv_fs_t* req) {
VERIFY_FD(fd, 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, nt_status = pNtQueryInformationFile(handle,
&io_status, &io_status,
...@@ -1507,7 +1511,27 @@ static void fs__fchmod(uv_fs_t* req) { ...@@ -1507,7 +1511,27 @@ static void fs__fchmod(uv_fs_t* req) {
if (!NT_SUCCESS(nt_status)) { if (!NT_SUCCESS(nt_status)) {
SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(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) { if (req->fs.info.mode & _S_IWRITE) {
...@@ -1524,10 +1548,28 @@ static void fs__fchmod(uv_fs_t* req) { ...@@ -1524,10 +1548,28 @@ static void fs__fchmod(uv_fs_t* req) {
if (!NT_SUCCESS(nt_status)) { if (!NT_SUCCESS(nt_status)) {
SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(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); SET_REQ_SUCCESS(req);
fchmod_cleanup:
CloseHandle(handle);
} }
...@@ -1787,17 +1829,13 @@ static void fs__symlink(uv_fs_t* req) { ...@@ -1787,17 +1829,13 @@ static void fs__symlink(uv_fs_t* req) {
fs__create_junction(req, pathw, new_pathw); fs__create_junction(req, pathw, new_pathw);
return; return;
} }
if (!pCreateSymbolicLinkW) {
SET_REQ_UV_ERROR(req, UV_ENOSYS, ERROR_NOT_SUPPORTED);
return;
}
if (req->fs.info.file_flags & UV_FS_SYMLINK_DIR) if (req->fs.info.file_flags & UV_FS_SYMLINK_DIR)
flags = SYMBOLIC_LINK_FLAG_DIRECTORY | uv__file_symlink_usermode_flag; flags = SYMBOLIC_LINK_FLAG_DIRECTORY | uv__file_symlink_usermode_flag;
else else
flags = uv__file_symlink_usermode_flag; flags = uv__file_symlink_usermode_flag;
if (pCreateSymbolicLinkW(new_pathw, pathw, flags)) { if (CreateSymbolicLinkW(new_pathw, pathw, flags)) {
SET_REQ_RESULT(req, 0); SET_REQ_RESULT(req, 0);
return; return;
} }
...@@ -1854,7 +1892,7 @@ static size_t fs__realpath_handle(HANDLE handle, char** realpath_ptr) { ...@@ -1854,7 +1892,7 @@ static size_t fs__realpath_handle(HANDLE handle, char** realpath_ptr) {
WCHAR* w_realpath_ptr = NULL; WCHAR* w_realpath_ptr = NULL;
WCHAR* w_realpath_buf; 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) { if (w_realpath_len == 0) {
return -1; return -1;
} }
...@@ -1866,10 +1904,8 @@ static size_t fs__realpath_handle(HANDLE handle, char** realpath_ptr) { ...@@ -1866,10 +1904,8 @@ static size_t fs__realpath_handle(HANDLE handle, char** realpath_ptr) {
} }
w_realpath_ptr = w_realpath_buf; w_realpath_ptr = w_realpath_buf;
if (pGetFinalPathNameByHandleW(handle, if (GetFinalPathNameByHandleW(
w_realpath_ptr, handle, w_realpath_ptr, w_realpath_len, VOLUME_NAME_DOS) == 0) {
w_realpath_len,
VOLUME_NAME_DOS) == 0) {
uv__free(w_realpath_buf); uv__free(w_realpath_buf);
SetLastError(ERROR_INVALID_HANDLE); SetLastError(ERROR_INVALID_HANDLE);
return -1; return -1;
...@@ -1901,11 +1937,6 @@ static size_t fs__realpath_handle(HANDLE handle, char** realpath_ptr) { ...@@ -1901,11 +1937,6 @@ static size_t fs__realpath_handle(HANDLE handle, char** realpath_ptr) {
static void fs__realpath(uv_fs_t* req) { static void fs__realpath(uv_fs_t* req) {
HANDLE handle; HANDLE handle;
if (!pGetFinalPathNameByHandleW) {
SET_REQ_UV_ERROR(req, UV_ENOSYS, ERROR_NOT_SUPPORTED);
return;
}
handle = CreateFileW(req->file.pathw, handle = CreateFileW(req->file.pathw,
0, 0,
0, 0,
...@@ -1940,6 +1971,10 @@ static void fs__fchown(uv_fs_t* req) { ...@@ -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) { static void uv__fs_work(struct uv__work* w) {
uv_fs_t* req; uv_fs_t* req;
...@@ -1977,6 +2012,7 @@ static void uv__fs_work(struct uv__work* w) { ...@@ -1977,6 +2012,7 @@ static void uv__fs_work(struct uv__work* w) {
XX(REALPATH, realpath) XX(REALPATH, realpath)
XX(CHOWN, chown) XX(CHOWN, chown)
XX(FCHOWN, fchown); XX(FCHOWN, fchown);
XX(LCHOWN, lchown);
default: default:
assert(!"bad uv_fs_type"); 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, ...@@ -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 uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
int err; int err;
......
...@@ -71,8 +71,8 @@ int uv__getaddrinfo_translate_error(int sys_err) { ...@@ -71,8 +71,8 @@ int uv__getaddrinfo_translate_error(int sys_err) {
#endif #endif
/* adjust size value to be multiple of 4. Use to keep pointer aligned */ /* Adjust size value to be multiple of 4. Use to keep pointer aligned.
/* Do we need different versions of this for different architectures? */ * Do we need different versions of this for different architectures? */
#define ALIGNED_SIZE(X) ((((X) + 3) >> 2) << 2) #define ALIGNED_SIZE(X) ((((X) + 3) >> 2) << 2)
#ifndef NDIS_IF_MAX_STRING_SIZE #ifndef NDIS_IF_MAX_STRING_SIZE
...@@ -124,8 +124,7 @@ static void uv__getaddrinfo_done(struct uv__work* w, int status) { ...@@ -124,8 +124,7 @@ static void uv__getaddrinfo_done(struct uv__work* w, int status) {
} }
if (req->retcode == 0) { if (req->retcode == 0) {
/* convert addrinfoW to addrinfo */ /* Convert addrinfoW to addrinfo. First calculate required length. */
/* first calculate required length */
addrinfow_ptr = req->addrinfow; addrinfow_ptr = req->addrinfow;
while (addrinfow_ptr != NULL) { while (addrinfow_ptr != NULL) {
addrinfo_len += addrinfo_struct_len + addrinfo_len += addrinfo_struct_len +
...@@ -313,8 +312,8 @@ int uv_getaddrinfo(uv_loop_t* loop, ...@@ -313,8 +312,8 @@ int uv_getaddrinfo(uv_loop_t* loop,
/* save alloc_ptr now so we can free if error */ /* save alloc_ptr now so we can free if error */
req->alloc = (void*)alloc_ptr; req->alloc = (void*)alloc_ptr;
/* convert node string to UTF16 into allocated memory and save pointer in */ /* Convert node string to UTF16 into allocated memory and save pointer in the
/* the request. */ * request. */
if (node != NULL) { if (node != NULL) {
req->node = (WCHAR*)alloc_ptr; req->node = (WCHAR*)alloc_ptr;
if (MultiByteToWideChar(CP_UTF8, if (MultiByteToWideChar(CP_UTF8,
...@@ -331,8 +330,8 @@ int uv_getaddrinfo(uv_loop_t* loop, ...@@ -331,8 +330,8 @@ int uv_getaddrinfo(uv_loop_t* loop,
req->node = NULL; req->node = NULL;
} }
/* convert service string to UTF16 into allocated memory and save pointer */ /* Convert service string to UTF16 into allocated memory and save pointer in
/* in the req. */ * the req. */
if (service != NULL) { if (service != NULL) {
req->service = (WCHAR*)alloc_ptr; req->service = (WCHAR*)alloc_ptr;
if (MultiByteToWideChar(CP_UTF8, if (MultiByteToWideChar(CP_UTF8,
......
...@@ -164,10 +164,10 @@ INLINE static void uv_process_endgames(uv_loop_t* loop) { ...@@ -164,10 +164,10 @@ INLINE static void uv_process_endgames(uv_loop_t* loop) {
INLINE static HANDLE uv__get_osfhandle(int fd) INLINE static HANDLE uv__get_osfhandle(int fd)
{ {
/* _get_osfhandle() raises an assert in debug builds if the FD is invalid. */ /* _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 */ * But it also correctly checks the FD and returns INVALID_HANDLE_VALUE for
/* for invalid FDs in release builds (or if you let the assert continue). */ * invalid FDs in release builds (or if you let the assert continue). So this
/* So this wrapper function disables asserts when calling _get_osfhandle. */ * wrapper function disables asserts when calling _get_osfhandle. */
HANDLE handle; HANDLE handle;
UV_BEGIN_DISABLE_CRT_ASSERT(); UV_BEGIN_DISABLE_CRT_ASSERT();
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#include "uv.h" #include "uv.h"
#include "../uv-common.h" #include "../uv-common.h"
#include "tree.h" #include "uv/tree.h"
#include "winapi.h" #include "winapi.h"
#include "winsock.h" #include "winsock.h"
...@@ -99,7 +99,6 @@ extern UV_THREAD_LOCAL int uv__crt_assert_enabled; ...@@ -99,7 +99,6 @@ extern UV_THREAD_LOCAL int uv__crt_assert_enabled;
/* Only used by uv_pipe_t handles. */ /* Only used by uv_pipe_t handles. */
#define UV_HANDLE_NON_OVERLAPPED_PIPE 0x01000000 #define UV_HANDLE_NON_OVERLAPPED_PIPE 0x01000000
#define UV_HANDLE_PIPESERVER 0x02000000 #define UV_HANDLE_PIPESERVER 0x02000000
#define UV_HANDLE_PIPE_READ_CANCELABLE 0x04000000
/* Only used by uv_tty_t handles. */ /* Only used by uv_tty_t handles. */
#define UV_HANDLE_TTY_READABLE 0x01000000 #define UV_HANDLE_TTY_READABLE 0x01000000
...@@ -127,8 +126,9 @@ extern UV_THREAD_LOCAL int uv__crt_assert_enabled; ...@@ -127,8 +126,9 @@ extern UV_THREAD_LOCAL int uv__crt_assert_enabled;
typedef struct { typedef struct {
WSAPROTOCOL_INFOW socket_info; WSAPROTOCOL_INFOW socket_info;
int delayed_error; uint32_t delayed_error;
} uv__ipc_socket_info_ex; 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_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb);
int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client); 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, ...@@ -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_close(uv_loop_t* loop, uv_tcp_t* tcp);
void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle); 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 uv__tcp_xfer_export(uv_tcp_t* handle,
int tcp_connection); int pid,
uv__ipc_socket_xfer_info_t* xfer_info);
int uv_tcp_duplicate_socket(uv_tcp_t* handle, int pid, int uv__tcp_xfer_import(uv_tcp_t* tcp, uv__ipc_socket_xfer_info_t* xfer_info);
LPWSAPROTOCOL_INFOW protocol_info);
/* /*
...@@ -178,14 +177,14 @@ int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb); ...@@ -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_accept(uv_pipe_t* server, uv_stream_t* client);
int uv_pipe_read_start(uv_pipe_t* handle, uv_alloc_cb alloc_cb, int uv_pipe_read_start(uv_pipe_t* handle, uv_alloc_cb alloc_cb,
uv_read_cb read_cb); uv_read_cb read_cb);
int uv_pipe_write(uv_loop_t* loop, uv_write_t* req, uv_pipe_t* handle, void uv__pipe_read_stop(uv_pipe_t* handle);
const uv_buf_t bufs[], unsigned int nbufs, uv_write_cb cb); int uv__pipe_write(uv_loop_t* loop,
int uv_pipe_write2(uv_loop_t* loop, uv_write_t* req, uv_pipe_t* handle, uv_write_t* req,
const uv_buf_t bufs[], unsigned int nbufs, uv_stream_t* send_handle, uv_pipe_t* handle,
uv_write_cb cb); const uv_buf_t bufs[],
void uv__pipe_pause_read(uv_pipe_t* handle); size_t nbufs,
void uv__pipe_unpause_read(uv_pipe_t* handle); uv_stream_t* send_handle,
void uv__pipe_stop_read(uv_pipe_t* handle); uv_write_cb cb);
void uv_process_pipe_read_req(uv_loop_t* loop, uv_pipe_t* handle, void uv_process_pipe_read_req(uv_loop_t* loop, uv_pipe_t* handle,
uv_req_t* req); uv_req_t* req);
...@@ -332,7 +331,6 @@ void uv__fs_poll_endgame(uv_loop_t* loop, uv_fs_poll_t* handle); ...@@ -332,7 +331,6 @@ void uv__fs_poll_endgame(uv_loop_t* loop, uv_fs_poll_t* handle);
void uv__util_init(void); void uv__util_init(void);
uint64_t uv__hrtime(double scale); uint64_t uv__hrtime(double scale);
int uv_current_pid(void);
__declspec(noreturn) void uv_fatal_error(const int errorno, const char* syscall); __declspec(noreturn) void uv_fatal_error(const int errorno, const char* syscall);
int uv__getpwuid_r(uv_passwd_t* pwd); int uv__getpwuid_r(uv_passwd_t* pwd);
int uv__convert_utf16_to_utf8(const WCHAR* utf16, int utf16len, char** utf8); 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) { ...@@ -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_1 = handle->events;
handle->mask_events_2 = 0; handle->mask_events_2 = 0;
} else { } else {
/* Just wait until there's an unsubmitted req. */ /* Just wait until there's an unsubmitted req. This will happen almost
/* This will happen almost immediately as one of the 2 outstanding */ * immediately as one of the 2 outstanding requests is about to return.
/* requests is about to return. When this happens, */ * When this happens, uv__fast_poll_process_poll_req will be called, and
/* uv__fast_poll_process_poll_req will be called, and the pending */ * the pending events, if needed, will be processed in a subsequent
/* events, if needed, will be processed in a subsequent request. */ * request. */
return; return;
} }
/* Setting Exclusive to TRUE makes the other poll request return if there */ /* Setting Exclusive to TRUE makes the other poll request return if there is
/* is any. */ * any. */
afd_poll_info->Exclusive = TRUE; afd_poll_info->Exclusive = TRUE;
afd_poll_info->NumberOfHandles = 1; afd_poll_info->NumberOfHandles = 1;
afd_poll_info->Timeout.QuadPart = INT64_MAX; 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) { ...@@ -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); uv_want_endgame(loop, (uv_handle_t*) handle);
return 0; return 0;
} else { } else {
/* Cancel outstanding poll requests by executing another, unique poll */ /* Cancel outstanding poll requests by executing another, unique poll
/* request that forces the outstanding ones to return. */ * request that forces the outstanding ones to return. */
return uv__fast_poll_cancel_poll_req(loop, handle); 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, ...@@ -316,9 +316,8 @@ static SOCKET uv__fast_poll_get_peer_socket(uv_loop_t* loop,
return INVALID_SOCKET; return INVALID_SOCKET;
} }
/* If we didn't (try) to create a peer socket yet, try to make one. Don't */ /* If we didn't (try) to create a peer socket yet, try to make one. Don't try
/* try again if the peer socket creation failed earlier for the same */ * again if the peer socket creation failed earlier for the same protocol. */
/* protocol. */
peer_socket = loop->poll_peer_sockets[index]; peer_socket = loop->poll_peer_sockets[index];
if (peer_socket == 0) { if (peer_socket == 0) {
peer_socket = uv__fast_poll_create_peer_socket(loop->iocp, protocol_info); 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) { ...@@ -357,8 +356,8 @@ static DWORD WINAPI uv__slow_poll_thread_proc(void* arg) {
efds.fd_count = 0; efds.fd_count = 0;
} }
/* Make the select() time out after 3 minutes. If select() hangs because */ /* Make the select() time out after 3 minutes. If select() hangs because the
/* the user closed the socket, we will at least not hang indefinitely. */ * user closed the socket, we will at least not hang indefinitely. */
timeout.tv_sec = 3 * 60; timeout.tv_sec = 3 * 60;
timeout.tv_usec = 0; timeout.tv_usec = 0;
...@@ -522,10 +521,10 @@ int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle, ...@@ -522,10 +521,10 @@ int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle,
if (ioctlsocket(socket, FIONBIO, &yes) == SOCKET_ERROR) if (ioctlsocket(socket, FIONBIO, &yes) == SOCKET_ERROR)
return uv_translate_sys_error(WSAGetLastError()); return uv_translate_sys_error(WSAGetLastError());
/* Try to obtain a base handle for the socket. This increases this chances */ /* Try to obtain a base handle for the socket. This increases this chances that
/* that we find an AFD handle and are able to use the fast poll mechanism. */ * we find an AFD handle and are able to use the fast poll mechanism. This will
/* This will always fail on windows XP/2k3, since they don't support the */ * always fail on windows XP/2k3, since they don't support the. SIO_BASE_HANDLE
/* SIO_BASE_HANDLE ioctl. */ * ioctl. */
#ifndef NDEBUG #ifndef NDEBUG
base_socket = INVALID_SOCKET; base_socket = INVALID_SOCKET;
#endif #endif
...@@ -557,9 +556,9 @@ int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle, ...@@ -557,9 +556,9 @@ int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle,
return uv_translate_sys_error(WSAGetLastError()); return uv_translate_sys_error(WSAGetLastError());
} }
/* Get the peer socket that is needed to enable fast poll. If the returned */ /* 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 */ * value is NULL, the protocol is not implemented by MSAFD and we'll have to
/* to use slow mode. */ * use slow mode. */
peer_socket = uv__fast_poll_get_peer_socket(loop, &protocol_info); peer_socket = uv__fast_poll_get_peer_socket(loop, &protocol_info);
if (peer_socket != INVALID_SOCKET) { if (peer_socket != INVALID_SOCKET) {
......
...@@ -105,10 +105,9 @@ static int uv__create_stdio_pipe_pair(uv_loop_t* loop, ...@@ -105,10 +105,9 @@ static int uv__create_stdio_pipe_pair(uv_loop_t* loop,
int err; int err;
if (flags & UV_READABLE_PIPE) { if (flags & UV_READABLE_PIPE) {
/* The server needs inbound access too, otherwise CreateNamedPipe() */ /* The server needs inbound access too, otherwise CreateNamedPipe() won't
/* won't give us the FILE_READ_ATTRIBUTES permission. We need that to */ * give us the FILE_READ_ATTRIBUTES permission. We need that to probe the
/* probe the state of the write buffer when we're trying to shutdown */ * state of the write buffer when we're trying to shutdown the pipe. */
/* the pipe. */
server_access |= PIPE_ACCESS_OUTBOUND | PIPE_ACCESS_INBOUND; server_access |= PIPE_ACCESS_OUTBOUND | PIPE_ACCESS_INBOUND;
client_access |= GENERIC_READ | FILE_WRITE_ATTRIBUTES; client_access |= GENERIC_READ | FILE_WRITE_ATTRIBUTES;
} }
...@@ -131,12 +130,13 @@ static int uv__create_stdio_pipe_pair(uv_loop_t* loop, ...@@ -131,12 +130,13 @@ static int uv__create_stdio_pipe_pair(uv_loop_t* loop,
sa.lpSecurityDescriptor = NULL; sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE; sa.bInheritHandle = TRUE;
BOOL overlap = server_pipe->ipc || (flags & UV_OVERLAPPED_PIPE);
child_pipe = CreateFileA(pipe_name, child_pipe = CreateFileA(pipe_name,
client_access, client_access,
0, 0,
&sa, &sa,
OPEN_EXISTING, OPEN_EXISTING,
server_pipe->ipc ? FILE_FLAG_OVERLAPPED : 0, overlap ? FILE_FLAG_OVERLAPPED : 0,
NULL); NULL);
if (child_pipe == INVALID_HANDLE_VALUE) { if (child_pipe == INVALID_HANDLE_VALUE) {
err = GetLastError(); err = GetLastError();
...@@ -159,8 +159,8 @@ static int uv__create_stdio_pipe_pair(uv_loop_t* loop, ...@@ -159,8 +159,8 @@ static int uv__create_stdio_pipe_pair(uv_loop_t* loop,
} }
#endif #endif
/* Do a blocking ConnectNamedPipe. This should not block because we have */ /* Do a blocking ConnectNamedPipe. This should not block because we have both
/* both ends of the pipe created. */ * ends of the pipe created. */
if (!ConnectNamedPipe(server_pipe->handle, NULL)) { if (!ConnectNamedPipe(server_pipe->handle, NULL)) {
if (GetLastError() != ERROR_PIPE_CONNECTED) { if (GetLastError() != ERROR_PIPE_CONNECTED) {
err = GetLastError(); err = GetLastError();
...@@ -194,11 +194,11 @@ static int uv__duplicate_handle(uv_loop_t* loop, HANDLE handle, HANDLE* dup) { ...@@ -194,11 +194,11 @@ static int uv__duplicate_handle(uv_loop_t* loop, HANDLE handle, HANDLE* dup) {
HANDLE current_process; HANDLE current_process;
/* _get_osfhandle will sometimes return -2 in case of an error. This seems */ /* _get_osfhandle will sometimes return -2 in case of an error. This seems to
/* to happen when fd <= 2 and the process' corresponding stdio handle is */ * happen when fd <= 2 and the process' corresponding stdio handle is set to
/* set to NULL. Unfortunately DuplicateHandle will happily duplicate */ * NULL. Unfortunately DuplicateHandle will happily duplicate (HANDLE) -2, so
/* (HANDLE) -2, so this situation goes unnoticed until someone tries to */ * this situation goes unnoticed until someone tries to use the duplicate.
/* use the duplicate. Therefore we filter out known-invalid handles here. */ * Therefore we filter out known-invalid handles here. */
if (handle == INVALID_HANDLE_VALUE || if (handle == INVALID_HANDLE_VALUE ||
handle == NULL || handle == NULL ||
handle == (HANDLE) -2) { handle == (HANDLE) -2) {
...@@ -284,8 +284,8 @@ int uv__stdio_create(uv_loop_t* loop, ...@@ -284,8 +284,8 @@ int uv__stdio_create(uv_loop_t* loop,
return ERROR_OUTOFMEMORY; return ERROR_OUTOFMEMORY;
} }
/* Prepopulate the buffer with INVALID_HANDLE_VALUE handles so we can */ /* Prepopulate the buffer with INVALID_HANDLE_VALUE handles so we can clean
/* clean up on failure. */ * up on failure. */
CHILD_STDIO_COUNT(buffer) = count; CHILD_STDIO_COUNT(buffer) = count;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
CHILD_STDIO_CRT_FLAGS(buffer, i) = 0; CHILD_STDIO_CRT_FLAGS(buffer, i) = 0;
...@@ -303,12 +303,12 @@ int uv__stdio_create(uv_loop_t* loop, ...@@ -303,12 +303,12 @@ int uv__stdio_create(uv_loop_t* loop,
switch (fdopt.flags & (UV_IGNORE | UV_CREATE_PIPE | UV_INHERIT_FD | switch (fdopt.flags & (UV_IGNORE | UV_CREATE_PIPE | UV_INHERIT_FD |
UV_INHERIT_STREAM)) { UV_INHERIT_STREAM)) {
case UV_IGNORE: case UV_IGNORE:
/* Starting a process with no stdin/stout/stderr can confuse it. */ /* Starting a process with no stdin/stout/stderr can confuse it. So no
/* So no matter what the user specified, we make sure the first */ * matter what the user specified, we make sure the first three FDs are
/* three FDs are always open in their typical modes, e.g. stdin */ * always open in their typical modes, e. g. stdin be readable and
/* be readable and stdout/err should be writable. For FDs > 2, don't */ * stdout/err should be writable. For FDs > 2, don't do anything - all
/* do anything - all handles in the stdio buffer are initialized with */ * handles in the stdio buffer are initialized with.
/* INVALID_HANDLE_VALUE, which should be okay. */ * INVALID_HANDLE_VALUE, which should be okay. */
if (i <= 2) { if (i <= 2) {
DWORD access = (i == 0) ? FILE_GENERIC_READ : DWORD access = (i == 0) ? FILE_GENERIC_READ :
FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES; FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES;
...@@ -323,14 +323,14 @@ int uv__stdio_create(uv_loop_t* loop, ...@@ -323,14 +323,14 @@ int uv__stdio_create(uv_loop_t* loop,
break; break;
case UV_CREATE_PIPE: { case UV_CREATE_PIPE: {
/* Create a pair of two connected pipe ends; one end is turned into */ /* Create a pair of two connected pipe ends; one end is turned into an
/* an uv_pipe_t for use by the parent. The other one is given to */ * uv_pipe_t for use by the parent. The other one is given to the
/* the child. */ * child. */
uv_pipe_t* parent_pipe = (uv_pipe_t*) fdopt.data.stream; uv_pipe_t* parent_pipe = (uv_pipe_t*) fdopt.data.stream;
HANDLE child_pipe = INVALID_HANDLE_VALUE; HANDLE child_pipe = INVALID_HANDLE_VALUE;
/* Create a new, connected pipe pair. stdio[i].stream should point */ /* Create a new, connected pipe pair. stdio[i]. stream should point to
/* to an uninitialized, but not connected pipe handle. */ * an uninitialized, but not connected pipe handle. */
assert(fdopt.data.stream->type == UV_NAMED_PIPE); assert(fdopt.data.stream->type == UV_NAMED_PIPE);
assert(!(fdopt.data.stream->flags & UV_HANDLE_CONNECTION)); assert(!(fdopt.data.stream->flags & UV_HANDLE_CONNECTION));
assert(!(fdopt.data.stream->flags & UV_HANDLE_PIPESERVER)); assert(!(fdopt.data.stream->flags & UV_HANDLE_PIPESERVER));
...@@ -354,8 +354,8 @@ int uv__stdio_create(uv_loop_t* loop, ...@@ -354,8 +354,8 @@ int uv__stdio_create(uv_loop_t* loop,
/* Make an inheritable duplicate of the handle. */ /* Make an inheritable duplicate of the handle. */
err = uv__duplicate_fd(loop, fdopt.data.fd, &child_handle); err = uv__duplicate_fd(loop, fdopt.data.fd, &child_handle);
if (err) { if (err) {
/* If fdopt.data.fd is not valid and fd fd <= 2, then ignore the */ /* If fdopt. data. fd is not valid and fd <= 2, then ignore the
/* error. */ * error. */
if (fdopt.data.fd <= 2 && err == ERROR_INVALID_HANDLE) { if (fdopt.data.fd <= 2 && err == ERROR_INVALID_HANDLE) {
CHILD_STDIO_CRT_FLAGS(buffer, i) = 0; CHILD_STDIO_CRT_FLAGS(buffer, i) = 0;
CHILD_STDIO_HANDLE(buffer, i) = INVALID_HANDLE_VALUE; CHILD_STDIO_HANDLE(buffer, i) = INVALID_HANDLE_VALUE;
...@@ -418,8 +418,8 @@ int uv__stdio_create(uv_loop_t* loop, ...@@ -418,8 +418,8 @@ int uv__stdio_create(uv_loop_t* loop,
if (stream_handle == NULL || if (stream_handle == NULL ||
stream_handle == INVALID_HANDLE_VALUE) { stream_handle == INVALID_HANDLE_VALUE) {
/* The handle is already closed, or not yet created, or the */ /* The handle is already closed, or not yet created, or the stream
/* stream type is not supported. */ * type is not supported. */
err = ERROR_NOT_SUPPORTED; err = ERROR_NOT_SUPPORTED;
goto error; goto error;
} }
......
...@@ -360,8 +360,8 @@ static WCHAR* search_path(const WCHAR *file, ...@@ -360,8 +360,8 @@ static WCHAR* search_path(const WCHAR *file,
return NULL; return NULL;
} }
/* Find the start of the filename so we can split the directory from the */ /* Find the start of the filename so we can split the directory from the
/* name. */ * name. */
for (file_name_start = (WCHAR*)file + file_len; for (file_name_start = (WCHAR*)file + file_len;
file_name_start > file file_name_start > file
&& file_name_start[-1] != L'\\' && file_name_start[-1] != L'\\'
...@@ -556,8 +556,8 @@ int make_program_args(char** args, int verbatim_arguments, WCHAR** dst_ptr) { ...@@ -556,8 +556,8 @@ int make_program_args(char** args, int verbatim_arguments, WCHAR** dst_ptr) {
arg_count++; arg_count++;
} }
/* Adjust for potential quotes. Also assume the worst-case scenario */ /* Adjust for potential quotes. Also assume the worst-case scenario that
/* that every character needs escaping, so we need twice as much space. */ * every character needs escaping, so we need twice as much space. */
dst_len = dst_len * 2 + arg_count * 2; dst_len = dst_len * 2 + arg_count * 2;
/* Allocate buffer for the final command line. */ /* Allocate buffer for the final command line. */
...@@ -831,8 +831,13 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) { ...@@ -831,8 +831,13 @@ int make_program_env(char* env_block[], WCHAR** dst_ptr) {
*/ */
static WCHAR* find_path(WCHAR *env) { static WCHAR* find_path(WCHAR *env) {
for (; env != NULL && *env != 0; env += wcslen(env) + 1) { 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 &env[5];
}
} }
return NULL; return NULL;
...@@ -865,8 +870,8 @@ void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle) { ...@@ -865,8 +870,8 @@ void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle) {
assert(handle->exit_cb_pending); assert(handle->exit_cb_pending);
handle->exit_cb_pending = 0; handle->exit_cb_pending = 0;
/* If we're closing, don't call the exit callback. Just schedule a close */ /* If we're closing, don't call the exit callback. Just schedule a close
/* callback now. */ * callback now. */
if (handle->flags & UV__HANDLE_CLOSING) { if (handle->flags & UV__HANDLE_CLOSING) {
uv_want_endgame(loop, (uv_handle_t*) handle); uv_want_endgame(loop, (uv_handle_t*) handle);
return; return;
...@@ -878,14 +883,14 @@ void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle) { ...@@ -878,14 +883,14 @@ void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle) {
handle->wait_handle = INVALID_HANDLE_VALUE; handle->wait_handle = INVALID_HANDLE_VALUE;
} }
/* Set the handle to inactive: no callbacks will be made after the exit */ /* Set the handle to inactive: no callbacks will be made after the exit
/* callback.*/ * callback. */
uv__handle_stop(handle); uv__handle_stop(handle);
if (GetExitCodeProcess(handle->process_handle, &status)) { if (GetExitCodeProcess(handle->process_handle, &status)) {
exit_code = status; exit_code = status;
} else { } 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()); exit_code = uv_translate_sys_error(GetLastError());
} }
...@@ -900,8 +905,8 @@ void uv_process_close(uv_loop_t* loop, uv_process_t* handle) { ...@@ -900,8 +905,8 @@ void uv_process_close(uv_loop_t* loop, uv_process_t* handle) {
uv__handle_closing(handle); uv__handle_closing(handle);
if (handle->wait_handle != INVALID_HANDLE_VALUE) { if (handle->wait_handle != INVALID_HANDLE_VALUE) {
/* This blocks until either the wait was cancelled, or the callback has */ /* This blocks until either the wait was cancelled, or the callback has
/* completed. */ * completed. */
BOOL r = UnregisterWaitEx(handle->wait_handle, INVALID_HANDLE_VALUE); BOOL r = UnregisterWaitEx(handle->wait_handle, INVALID_HANDLE_VALUE);
if (!r) { if (!r) {
/* This should never happen, and if it happens, we can't recover... */ /* This should never happen, and if it happens, we can't recover... */
...@@ -1104,14 +1109,13 @@ int uv_spawn(uv_loop_t* loop, ...@@ -1104,14 +1109,13 @@ int uv_spawn(uv_loop_t* loop,
goto done; goto done;
} }
/* Spawn succeeded */ /* Spawn succeeded. Beyond this point, failure is reported asynchronously. */
/* Beyond this point, failure is reported asynchronously. */
process->process_handle = info.hProcess; process->process_handle = info.hProcess;
process->pid = info.dwProcessId; process->pid = info.dwProcessId;
/* If the process isn't spawned as detached, assign to the global job */ /* If the process isn't spawned as detached, assign to the global job object
/* object so windows will kill it when the parent process dies. */ * so windows will kill it when the parent process dies. */
if (!(options->flags & UV_PROCESS_DETACHED)) { if (!(options->flags & UV_PROCESS_DETACHED)) {
uv_once(&uv_global_job_handle_init_guard_, uv__init_global_job_handle); uv_once(&uv_global_job_handle_init_guard_, uv__init_global_job_handle);
...@@ -1138,7 +1142,8 @@ int uv_spawn(uv_loop_t* loop, ...@@ -1138,7 +1142,8 @@ int uv_spawn(uv_loop_t* loop,
if (fdopt->flags & UV_CREATE_PIPE && if (fdopt->flags & UV_CREATE_PIPE &&
fdopt->data.stream->type == UV_NAMED_PIPE && fdopt->data.stream->type == UV_NAMED_PIPE &&
((uv_pipe_t*) fdopt->data.stream)->ipc) { ((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, ...@@ -1154,8 +1159,8 @@ int uv_spawn(uv_loop_t* loop,
assert(!err); assert(!err);
/* Make the handle active. It will remain active until the exit callback */ /* Make the handle active. It will remain active until the exit callback is
/* is made or the handle is closed, whichever happens first. */ * made or the handle is closed, whichever happens first. */
uv__handle_start(process); uv__handle_start(process);
/* Cleanup, whether we succeeded or failed. */ /* Cleanup, whether we succeeded or failed. */
...@@ -1186,16 +1191,16 @@ static int uv__kill(HANDLE process_handle, int signum) { ...@@ -1186,16 +1191,16 @@ static int uv__kill(HANDLE process_handle, int signum) {
case SIGTERM: case SIGTERM:
case SIGKILL: case SIGKILL:
case SIGINT: { case SIGINT: {
/* Unconditionally terminate the process. On Windows, killed processes */ /* Unconditionally terminate the process. On Windows, killed processes
/* normally return 1. */ * normally return 1. */
DWORD status; DWORD status;
int err; int err;
if (TerminateProcess(process_handle, 1)) if (TerminateProcess(process_handle, 1))
return 0; return 0;
/* If the process already exited before TerminateProcess was called, */ /* If the process already exited before TerminateProcess was called,.
/* TerminateProcess will fail with ERROR_ACCESS_DENIED. */ * TerminateProcess will fail with ERROR_ACCESS_DENIED. */
err = GetLastError(); err = GetLastError();
if (err == ERROR_ACCESS_DENIED && if (err == ERROR_ACCESS_DENIED &&
GetExitCodeProcess(process_handle, &status) && GetExitCodeProcess(process_handle, &status) &&
......
...@@ -47,13 +47,13 @@ void uv_signals_init(void) { ...@@ -47,13 +47,13 @@ void uv_signals_init(void) {
static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2) { 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 */ /* Compare signums first so all watchers with the same signnum end up
/* adjacent. */ * adjacent. */
if (w1->signum < w2->signum) return -1; if (w1->signum < w2->signum) return -1;
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 */ /* Sort by loop pointer, so we can easily look up the first item after
/* { .signum = x, .loop = NULL } */ * { .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;
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) { ...@@ -118,10 +118,10 @@ static BOOL WINAPI uv__signal_control_handler(DWORD type) {
case CTRL_CLOSE_EVENT: case CTRL_CLOSE_EVENT:
if (uv__signal_dispatch(SIGHUP)) { if (uv__signal_dispatch(SIGHUP)) {
/* Windows will terminate the process after the control handler */ /* Windows will terminate the process after the control handler
/* returns. After that it will just terminate our process. Therefore */ * returns. After that it will just terminate our process. Therefore
/* block the signal handler so the main loop has some time to pick */ * block the signal handler so the main loop has some time to pick up
/* up the signal and do something for a few seconds. */ * the signal and do something for a few seconds. */
Sleep(INFINITE); Sleep(INFINITE);
return TRUE; return TRUE;
} }
...@@ -129,8 +129,8 @@ static BOOL WINAPI uv__signal_control_handler(DWORD type) { ...@@ -129,8 +129,8 @@ static BOOL WINAPI uv__signal_control_handler(DWORD type) {
case CTRL_LOGOFF_EVENT: case CTRL_LOGOFF_EVENT:
case CTRL_SHUTDOWN_EVENT: case CTRL_SHUTDOWN_EVENT:
/* These signals are only sent to services. Services have their own */ /* These signals are only sent to services. Services have their own
/* notification mechanism, so there's no point in handling these. */ * notification mechanism, so there's no point in handling these. */
default: default:
/* We don't handle these. */ /* We don't handle these. */
...@@ -193,10 +193,10 @@ int uv__signal_start(uv_signal_t* handle, ...@@ -193,10 +193,10 @@ int uv__signal_start(uv_signal_t* handle,
if (signum != SIGWINCH && (signum <= 0 || signum >= NSIG)) if (signum != SIGWINCH && (signum <= 0 || signum >= NSIG))
return UV_EINVAL; return UV_EINVAL;
/* Short circuit: if the signal watcher is already watching {signum} don't */ /* Short circuit: if the signal watcher is already watching {signum} don't go
/* go through the process of deregistering and registering the handler. */ * through the process of deregistering and registering the handler.
/* Additionally, this avoids pending signals getting lost in the (small) */ * Additionally, this avoids pending signals getting lost in the (small) time
/* time frame that handle->signum == 0. */ * frame that handle->signum == 0. */
if (signum == handle->signum) { if (signum == handle->signum) {
handle->signal_cb = signal_cb; handle->signal_cb = signal_cb;
return 0; return 0;
...@@ -237,9 +237,9 @@ void uv_process_signal_req(uv_loop_t* loop, uv_signal_t* handle, ...@@ -237,9 +237,9 @@ void uv_process_signal_req(uv_loop_t* loop, uv_signal_t* handle,
(volatile LONG*) &handle->pending_signum, 0); (volatile LONG*) &handle->pending_signum, 0);
assert(dispatched_signum != 0); assert(dispatched_signum != 0);
/* Check if the pending signal equals the signum that we are watching for. */ /* 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 */ * These can get out of sync when the handler is stopped and restarted while
/* while the signal_req is pending. */ * the signal_req is pending. */
if (dispatched_signum == handle->signum) if (dispatched_signum == handle->signum)
handle->signal_cb(handle, dispatched_signum); handle->signal_cb(handle, dispatched_signum);
......
...@@ -105,12 +105,10 @@ int uv_read_stop(uv_stream_t* handle) { ...@@ -105,12 +105,10 @@ int uv_read_stop(uv_stream_t* handle) {
err = 0; err = 0;
if (handle->type == UV_TTY) { if (handle->type == UV_TTY) {
err = uv_tty_read_stop((uv_tty_t*) handle); 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 { } else {
if (handle->type == UV_NAMED_PIPE) { handle->flags &= ~UV_HANDLE_READING;
uv__pipe_stop_read((uv_pipe_t*) handle);
} else {
handle->flags &= ~UV_HANDLE_READING;
}
DECREASE_ACTIVE_COUNT(handle->loop, handle); DECREASE_ACTIVE_COUNT(handle->loop, handle);
} }
...@@ -136,7 +134,8 @@ int uv_write(uv_write_t* req, ...@@ -136,7 +134,8 @@ int uv_write(uv_write_t* req,
err = uv_tcp_write(loop, req, (uv_tcp_t*) handle, bufs, nbufs, cb); err = uv_tcp_write(loop, req, (uv_tcp_t*) handle, bufs, nbufs, cb);
break; break;
case UV_NAMED_PIPE: 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; break;
case UV_TTY: case UV_TTY:
err = uv_tty_write(loop, req, (uv_tty_t*) handle, bufs, nbufs, cb); err = uv_tty_write(loop, req, (uv_tty_t*) handle, bufs, nbufs, cb);
...@@ -158,25 +157,18 @@ int uv_write2(uv_write_t* req, ...@@ -158,25 +157,18 @@ int uv_write2(uv_write_t* req,
uv_loop_t* loop = handle->loop; uv_loop_t* loop = handle->loop;
int err; int err;
if (!(handle->flags & UV_HANDLE_WRITABLE)) { if (send_handle == NULL) {
return UV_EPIPE; return uv_write(req, handle, bufs, nbufs, cb);
} }
err = ERROR_INVALID_PARAMETER; if (handle->type != UV_NAMED_PIPE || !((uv_pipe_t*) handle)->ipc) {
switch (handle->type) { return UV_EINVAL;
case UV_NAMED_PIPE: } else if (!(handle->flags & UV_HANDLE_WRITABLE)) {
err = uv_pipe_write2(loop, return UV_EPIPE;
req,
(uv_pipe_t*) handle,
bufs,
nbufs,
send_handle,
cb);
break;
default:
assert(0);
} }
err = uv__pipe_write(
loop, req, (uv_pipe_t*) handle, bufs, nbufs, send_handle, cb);
return uv_translate_sys_error(err); return uv_translate_sys_error(err);
} }
......
This diff is collapsed.
...@@ -26,17 +26,6 @@ ...@@ -26,17 +26,6 @@
#include "uv.h" #include "uv.h"
#include "internal.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 int uv_cond_condvar_init(uv_cond_t* cond);
static void uv_cond_condvar_destroy(uv_cond_t* cond); static void uv_cond_condvar_destroy(uv_cond_t* cond);
static void uv_cond_condvar_signal(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)) { ...@@ -69,8 +58,8 @@ static void uv__once_inner(uv_once_t* guard, void (*callback)(void)) {
guard->ran = 1; guard->ran = 1;
} else { } else {
/* We lost the race. Destroy the event we created and wait for the */ /* We lost the race. Destroy the event we created and wait for the existing
/* existing one to become signaled. */ * one to become signaled. */
CloseHandle(created_event); CloseHandle(created_event);
result = WaitForSingleObject(existing_event, INFINITE); result = WaitForSingleObject(existing_event, INFINITE);
assert(result == WAIT_OBJECT_0); assert(result == WAIT_OBJECT_0);
...@@ -377,220 +366,35 @@ int uv_sem_trywait(uv_sem_t* sem) { ...@@ -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) { int uv_cond_init(uv_cond_t* cond) {
uv__once_init(); InitializeConditionVariable(&cond->cond_var);
return 0;
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 */
} }
void uv_cond_destroy(uv_cond_t* cond) { void uv_cond_destroy(uv_cond_t* cond) {
if (HAVE_CONDVAR_API()) /* nothing to do */
uv_cond_condvar_destroy(cond); UV__UNUSED(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);
} }
void uv_cond_signal(uv_cond_t* cond) { void uv_cond_signal(uv_cond_t* cond) {
if (HAVE_CONDVAR_API()) WakeConditionVariable(&cond->cond_var);
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);
} }
void uv_cond_broadcast(uv_cond_t* cond) { void uv_cond_broadcast(uv_cond_t* cond) {
if (HAVE_CONDVAR_API()) WakeAllConditionVariable(&cond->cond_var);
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();
} }
void uv_cond_wait(uv_cond_t* cond, uv_mutex_t* mutex) { void uv_cond_wait(uv_cond_t* cond, uv_mutex_t* mutex) {
if (HAVE_CONDVAR_API()) if (!SleepConditionVariableCS(&cond->cond_var, mutex, INFINITE))
uv_cond_condvar_wait(cond, mutex); abort();
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));
} }
int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex, uint64_t timeout) {
static int uv_cond_condvar_timedwait(uv_cond_t* cond, if (SleepConditionVariableCS(&cond->cond_var, mutex, (DWORD)(timeout / 1e6)))
uv_mutex_t* mutex, uint64_t timeout) {
if (pSleepConditionVariableCS(&cond->cond_var, mutex, (DWORD)(timeout / 1e6)))
return 0; return 0;
if (GetLastError() != ERROR_TIMEOUT) if (GetLastError() != ERROR_TIMEOUT)
abort(); abort();
...@@ -598,15 +402,6 @@ static int uv_cond_condvar_timedwait(uv_cond_t* cond, ...@@ -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 uv_barrier_init(uv_barrier_t* barrier, unsigned int count) {
int err; int err;
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
#include "uv.h" #include "uv.h"
#include "internal.h" #include "internal.h"
#include "tree.h" #include "uv/tree.h"
#include "handle-inl.h" #include "handle-inl.h"
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -34,21 +34,6 @@ sNtQueryVolumeInformationFile pNtQueryVolumeInformationFile; ...@@ -34,21 +34,6 @@ sNtQueryVolumeInformationFile pNtQueryVolumeInformationFile;
sNtQueryDirectoryFile pNtQueryDirectoryFile; sNtQueryDirectoryFile pNtQueryDirectoryFile;
sNtQuerySystemInformation pNtQuerySystemInformation; 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 */ /* Powrprof.dll function pointer */
sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotification; sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotification;
...@@ -58,7 +43,6 @@ sSetWinEventHook pSetWinEventHook; ...@@ -58,7 +43,6 @@ sSetWinEventHook pSetWinEventHook;
void uv_winapi_init(void) { void uv_winapi_init(void) {
HMODULE ntdll_module; HMODULE ntdll_module;
HMODULE kernel32_module;
HMODULE powrprof_module; HMODULE powrprof_module;
HMODULE user32_module; HMODULE user32_module;
...@@ -114,46 +98,6 @@ void uv_winapi_init(void) { ...@@ -114,46 +98,6 @@ void uv_winapi_init(void) {
uv_fatal_error(GetLastError(), "GetProcAddress"); 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"); powrprof_module = LoadLibraryA("powrprof.dll");
if (powrprof_module != NULL) { if (powrprof_module != NULL) {
pPowerRegisterSuspendResumeNotification = (sPowerRegisterSuspendResumeNotification) pPowerRegisterSuspendResumeNotification = (sPowerRegisterSuspendResumeNotification)
......
This diff is collapsed.
...@@ -256,8 +256,8 @@ int uv_ntstatus_to_winsock_error(NTSTATUS status) { ...@@ -256,8 +256,8 @@ int uv_ntstatus_to_winsock_error(NTSTATUS status) {
default: default:
if ((status & (FACILITY_NTWIN32 << 16)) == (FACILITY_NTWIN32 << 16) && if ((status & (FACILITY_NTWIN32 << 16)) == (FACILITY_NTWIN32 << 16) &&
(status & (ERROR_SEVERITY_ERROR | ERROR_SEVERITY_WARNING))) { (status & (ERROR_SEVERITY_ERROR | ERROR_SEVERITY_WARNING))) {
/* It's a windows error that has been previously mapped to an */ /* It's a windows error that has been previously mapped to an ntstatus
/* ntstatus code. */ * code. */
return (DWORD) (status & 0xffff); return (DWORD) (status & 0xffff);
} else { } else {
/* The default fallback for unmappable ntstatus codes. */ /* The default fallback for unmappable ntstatus codes. */
...@@ -519,8 +519,8 @@ int WSAAPI uv_msafd_poll(SOCKET socket, AFD_POLL_INFO* info_in, ...@@ -519,8 +519,8 @@ int WSAAPI uv_msafd_poll(SOCKET socket, AFD_POLL_INFO* info_in,
sizeof *info_out); sizeof *info_out);
if (overlapped == NULL) { if (overlapped == NULL) {
/* If this is a blocking operation, wait for the event to become */ /* If this is a blocking operation, wait for the event to become signaled,
/* signaled, and then grab the real status from the io status block. */ * and then grab the real status from the io status block. */
if (status == STATUS_PENDING) { if (status == STATUS_PENDING) {
DWORD r = WaitForSingleObject(event, INFINITE); DWORD r = WaitForSingleObject(event, INFINITE);
......
This diff is collapsed.
...@@ -211,6 +211,8 @@ if sys.platform != 'win32': ...@@ -211,6 +211,8 @@ if sys.platform != 'win32':
if sys.platform.startswith('linux'): if sys.platform.startswith('linux'):
_add_library('dl') _add_library('dl')
_add_library('rt') _add_library('rt')
_define_macro('_GNU_SOURCE', 1)
_define_macro('_POSIX_C_SOURCE', '200112')
elif sys.platform == 'darwin': elif sys.platform == 'darwin':
_define_macro('_DARWIN_USE_64_BIT_INODE', 1) _define_macro('_DARWIN_USE_64_BIT_INODE', 1)
_define_macro('_DARWIN_UNLIMITED_SELECT', 1) _define_macro('_DARWIN_UNLIMITED_SELECT', 1)
...@@ -230,6 +232,7 @@ elif WIN: ...@@ -230,6 +232,7 @@ elif WIN:
_define_macro('_CRT_NONSTDC_NO_DEPRECATE', 1) _define_macro('_CRT_NONSTDC_NO_DEPRECATE', 1)
_define_macro('_CRT_SECURE_NO_WARNINGS', 1) _define_macro('_CRT_SECURE_NO_WARNINGS', 1)
_define_macro('_WIN32_WINNT', '0x0600') _define_macro('_WIN32_WINNT', '0x0600')
_define_macro('WIN32_LEAN_AND_MEAN', 1)
_add_library('advapi32') _add_library('advapi32')
_add_library('iphlpapi') _add_library('iphlpapi')
_add_library('psapi') _add_library('psapi')
......
...@@ -151,8 +151,9 @@ class loop(AbstractLoop): ...@@ -151,8 +151,9 @@ class loop(AbstractLoop):
self._signal_idle = ffi.new("uv_timer_t*") self._signal_idle = ffi.new("uv_timer_t*")
libuv.uv_timer_init(self._ptr, self._signal_idle) libuv.uv_timer_init(self._ptr, self._signal_idle)
self._signal_idle.data = self._handle_to_self 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, libuv.uv_timer_start(self._signal_idle,
ffi.cast('void(*)(uv_timer_t*)', libuv.python_check_callback), sig_cb,
300, 300,
300) 300)
libuv.uv_unref(self._signal_idle) 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