Alien-uv

 view release on metacpan or  search on metacpan

MANIFEST  view on Meta::CPAN

libuv/docs/code/onchange/main.c
libuv/docs/code/pipe-echo-server/main.c
libuv/docs/code/plugin/hello.c
libuv/docs/code/plugin/main.c
libuv/docs/code/plugin/plugin.h
libuv/docs/code/proc-streams/main.c
libuv/docs/code/proc-streams/test.c
libuv/docs/code/progress/main.c
libuv/docs/code/queue-cancel/main.c
libuv/docs/code/queue-work/main.c
libuv/docs/code/ref-timer/main.c
libuv/docs/code/signal/main.c
libuv/docs/code/spawn/main.c
libuv/docs/code/tcp-echo-server/main.c
libuv/docs/code/thread-create/main.c
libuv/docs/code/tty-gravity/main.c
libuv/docs/code/tty/main.c
libuv/docs/code/udp-dhcp/main.c
libuv/docs/code/uvcat/main.c
libuv/docs/code/uvstop/main.c
libuv/docs/code/uvtee/main.c

MANIFEST  view on Meta::CPAN

libuv/docs/src/static/diagrams.key/preview-micro.jpg
libuv/docs/src/static/diagrams.key/preview-web.jpg
libuv/docs/src/static/diagrams.key/preview.jpg
libuv/docs/src/static/favicon.ico
libuv/docs/src/static/logo.png
libuv/docs/src/static/loop_iteration.png
libuv/docs/src/stream.rst
libuv/docs/src/tcp.rst
libuv/docs/src/threading.rst
libuv/docs/src/threadpool.rst
libuv/docs/src/timer.rst
libuv/docs/src/tty.rst
libuv/docs/src/udp.rst
libuv/docs/src/upgrading.rst
libuv/docs/src/version.rst
libuv/gyp_uv.py
libuv/img/banner.png
libuv/img/logos.svg
libuv/include/uv.h
libuv/include/uv/aix.h
libuv/include/uv/android-ifaddrs.h

MANIFEST  view on Meta::CPAN

libuv/samples/socks5-proxy/util.c
libuv/src/fs-poll.c
libuv/src/heap-inl.h
libuv/src/idna.c
libuv/src/idna.h
libuv/src/inet.c
libuv/src/queue.h
libuv/src/strscpy.c
libuv/src/strscpy.h
libuv/src/threadpool.c
libuv/src/timer.c
libuv/src/unix/aix-common.c
libuv/src/unix/aix.c
libuv/src/unix/android-ifaddrs.c
libuv/src/unix/async.c
libuv/src/unix/atomic-ops.h
libuv/src/unix/bsd-ifaddrs.c
libuv/src/unix/bsd-proctitle.c
libuv/src/unix/core.c
libuv/src/unix/cygwin.c
libuv/src/unix/darwin-proctitle.c

MANIFEST  view on Meta::CPAN

libuv/src/win/winsock.c
libuv/src/win/winsock.h
libuv/SUPPORTED_PLATFORMS.md
libuv/test/benchmark-async-pummel.c
libuv/test/benchmark-async.c
libuv/test/benchmark-fs-stat.c
libuv/test/benchmark-getaddrinfo.c
libuv/test/benchmark-list.h
libuv/test/benchmark-loop-count.c
libuv/test/benchmark-million-async.c
libuv/test/benchmark-million-timers.c
libuv/test/benchmark-multi-accept.c
libuv/test/benchmark-ping-pongs.c
libuv/test/benchmark-pound.c
libuv/test/benchmark-pump.c
libuv/test/benchmark-sizes.c
libuv/test/benchmark-spawn.c
libuv/test/benchmark-tcp-write-batch.c
libuv/test/benchmark-thread.c
libuv/test/benchmark-udp-pummel.c
libuv/test/blackhole-server.c

MANIFEST  view on Meta::CPAN

libuv/test/test-tcp-unexpected-read.c
libuv/test/test-tcp-write-after-connect.c
libuv/test/test-tcp-write-fail.c
libuv/test/test-tcp-write-queue-order.c
libuv/test/test-tcp-write-to-half-open-connection.c
libuv/test/test-tcp-writealot.c
libuv/test/test-thread-equal.c
libuv/test/test-thread.c
libuv/test/test-threadpool-cancel.c
libuv/test/test-threadpool.c
libuv/test/test-timer-again.c
libuv/test/test-timer-from-check.c
libuv/test/test-timer.c
libuv/test/test-tmpdir.c
libuv/test/test-tty-duplicate-key.c
libuv/test/test-tty.c
libuv/test/test-udp-alloc-cb-fail.c
libuv/test/test-udp-bind.c
libuv/test/test-udp-connect.c
libuv/test/test-udp-create-socket-early.c
libuv/test/test-udp-dgram-too-big.c
libuv/test/test-udp-ipv6.c
libuv/test/test-udp-multicast-interface.c

libuv/CMakeLists.txt  view on Meta::CPAN

  list(APPEND uv_cflags -Wall -Wextra -Wstrict-prototypes)
  list(APPEND uv_cflags -Wno-unused-parameter)
endif()

set(uv_sources
    src/fs-poll.c
    src/idna.c
    src/inet.c
    src/strscpy.c
    src/threadpool.c
    src/timer.c
    src/uv-common.c
    src/uv-data-getter-setters.c
    src/version.c)

set(uv_test_sources
    test/blackhole-server.c
    test/echo-server.c
    test/run-tests.c
    test/runner.c
    test/test-active.c

libuv/CMakeLists.txt  view on Meta::CPAN

    test/test-tcp-unexpected-read.c
    test/test-tcp-write-after-connect.c
    test/test-tcp-write-fail.c
    test/test-tcp-write-queue-order.c
    test/test-tcp-write-to-half-open-connection.c
    test/test-tcp-writealot.c
    test/test-thread-equal.c
    test/test-thread.c
    test/test-threadpool-cancel.c
    test/test-threadpool.c
    test/test-timer-again.c
    test/test-timer-from-check.c
    test/test-timer.c
    test/test-tmpdir.c
    test/test-tty-duplicate-key.c
    test/test-tty.c
    test/test-udp-alloc-cb-fail.c
    test/test-udp-bind.c
    test/test-udp-connect.c
    test/test-udp-create-socket-early.c
    test/test-udp-dgram-too-big.c
    test/test-udp-ipv6.c
    test/test-udp-multicast-interface.c

libuv/ChangeLog  view on Meta::CPAN

2018.07.11, Version 1.22.0 (Stable), 8568f78a777d79d35eb7d6994617267b9fb33967

Changes since version 1.21.0:

* unix: remove checksparse.sh (Ben Noordhuis)

* win: fix mingw build error (Ben Noordhuis)

* win: fix -Wunused-function warnings in thread.c (Ben Noordhuis)

* unix,win: merge timers implementation (Ben Noordhuis)

* win: fix pointer type in pipe.c (Ben Noordhuis)

* win: fixing build for older MSVC compilers (Michael Fero)

* zos: clear poll events on every iteration (jBarz)

* zos: write-protect message queue (jBarz)

* zos: use correct pointer type in strnlen (jBarz)

libuv/ChangeLog  view on Meta::CPAN

* doc: mark IBM i as Tier 3 support (Jesse Gorzinski)

* win,build: correct C2059 errors (Michael Fero)

* zos: fix timeout for condition variable (jBarz)

* win: CREATE_NO_WINDOW when stdio is not inherited (Nick Logan)

* build: fix commmon.gypi comment (Ryuichi KAWAMATA)

* doc: document uv_timer_start() on an active timer (Vladimír Čunát)

* doc: add note about handle movability (Bartosz Sosnowski)

* doc: fix syntax error in loop documentation (Bartosz Sosnowski)

* osx,stream: retry sending handle on EMSGSIZE error (Santiago Gimeno)

* unix: delay fs req register until after validation (cjihrig)

* test: add tests for bad inputs (Joyee Cheung)

libuv/ChangeLog  view on Meta::CPAN

* unix: add missing semicolon (jBarz)

* win, test: fix double close in test runner (Bartosz Sosnowski)

* doc: update supported windows version baseline (Ben Noordhuis)

* test,zos: skip chown root test (jBarz)

* test,zos: use gid=-1 to test spawn_setgid_fails (jBarz)

* zos: fix hr timer resolution (jBarz)

* android: fix blocking recvmsg due to netlink bug (Jacob Segal)

* zos: read more accurate rss info from RSM (jBarz)

* win: allow bound/connected socket in uv_tcp_open() (Maciej Szeptuch
  (Neverous))

* doc: differentiate SmartOS and SunOS support (cjihrig)

libuv/ChangeLog  view on Meta::CPAN

* sunos: filter out non-IPv4/IPv6 interfaces (Sebastian Wiedenroth)

* sunos: fix cmpxchgi and cmpxchgl type error (Sai Ke WANG)

* unix: reset signal disposition before execve() (Ben Noordhuis)

* unix: reset signal mask before execve() (Ben Noordhuis)

* unix: fix POLLIN assertion on server read (jBarz)

* zos: use stckf builtin for high-res timer (jBarz)

* win,udp: implements uv_udp_try_send (Barnabas Gema)

* win,udp: return UV_EINVAL instead of aborting (Romain Caire)

* freebsd: replace kvm with sysctl (Robert Ayrapetyan)

* aix: fix un-initialized pointer field in fs handle (Gireesh Punathil)

* win,build: support building with VS2017 (Refael Ackermann)

libuv/ChangeLog  view on Meta::CPAN

* unix: filter getifaddrs results consistently (Brad King)

* unix: factor out getifaddrs result filter (Brad King)

* unix: factor out reusable BSD ifaddrs impl (Brad King)

* unix: use union to follow strict aliasing rules (jBarz)

* unix: simplify async watcher dispatch logic (Ben Noordhuis)

* samples: update timer callback prototype (Ben Noordhuis)

* unix: make loops and watchers usable after fork() (Jason Madden)

* win: free uv__loops once empty (cjihrig)

* tools: add make_dist_html.py script (Ben Noordhuis)

* win,sunos: stop handle on uv_fs_event_start() err (cjihrig)

* unix,windows: refactor request init logic (Ben Noordhuis)

libuv/ChangeLog  view on Meta::CPAN

* win: ensure 32-bit printf precision (Matej Knopp)

* darwin: handle EINTR in /dev/tty workaround (Ben Noordhuis)

* test: fix OOB buffer access (Saúl Ibarra Corretgé)

* test: don't close CRT fd handed off to uv_pipe_t (Saúl Ibarra Corretgé)

* test: fix android build error. (sunjin.lee)

* win: evaluate timers when system wakes up (Bartosz Sosnowski)

* doc: add supported platforms description (Saúl Ibarra Corretgé)

* win: fix lstat reparse point without link data (Jason Ginchereau)

* unix,win: make on_alloc_cb failures more resilient (Saúl Ibarra Corretgé)

* zos: add support for new platform (John Barboza)

* test: make tcp_close_while_connecting more resilient (Saúl Ibarra Corretgé)

libuv/ChangeLog  view on Meta::CPAN

* win, test: fix fs_event_watch_dir_recursive (Bartosz Sosnowski)

* doc: add description of uv_handle_type (Vit Gottwald)

* build: use -pthreads for tests with autotools (Julien Gilli)

* win: fix leaky fs request buffer (Jason Ginchereau)

* doc: note buffer lifetime requirements in uv_write (Vladimír Čunát)

* doc: add reference to uv_update_time on uv_timer_start (Alex Hultman)

* win: fix winapi function pointer typedef syntax (Brad King)

* test: fix tcp_close_while_connecting CI failures (Ben Noordhuis)

* test: make threadpool_cancel_single deterministic (Ben Noordhuis)

* test: make threadpool saturation reliable (Ben Noordhuis)

* unix: don't malloc in uv_thread_create() (Ben Noordhuis)

libuv/ChangeLog  view on Meta::CPAN

* doc: fix typo (Devchandra Meetei Leishangthem)

* doc: fix uv-unix.h location (Sakthipriyan Vairamani)

* unix: fix error check when closing process pipe fd (Ben Noordhuis)

* test,freebsd: fix ipc_listen_xx_write tests (Santiago Gimeno)

* win: fix unsavory rwlock fallback implementation (Bert Belder)

* doc: clarify repeat timer behavior (Eli Skeggs)


2015.08.28, Version 1.7.3 (Stable), 93877b11c8b86e0a6befcda83a54555c1e36e4f0

Changes since version 1.7.2:

* threadpool: fix thread starvation bug (Ben Noordhuis)


2015.08.25, Version 1.7.2 (Stable), 4d13a013fcfa72311f0102751fdc7951873f466c

libuv/ChangeLog  view on Meta::CPAN

* build: compile -D_GNU_SOURCE on linux (Ben Noordhuis)

* build: use -fvisibility=hidden in autotools build (Ben Noordhuis)

* fs, pipe: no trailing terminator in exact sized buffers (Andrius Bentkus)

* style: rename buf to buffer and len to size for consistency (Andrius Bentkus)

* test: fix test-spawn on MinGW32 (Luis Martinez de Bartolome)

* win, pipe: fix assertion when destroying timer (Andrius Bentkus)

* win, unix: add pipe_peername implementation (Andrius Bentkus)


2015.01.29, Version 0.10.33 (Stable), 7a2253d33ad8215a26c1b34f1952aee7242dd687

Changes since version 0.10.32:

* linux: fix epoll_pwait() regression with < 2.6.19 (Ben Noordhuis)

libuv/ChangeLog  view on Meta::CPAN


* linux: try epoll_pwait if epoll_wait is missing (Michael Hudson-Doyle)

* windows: map ERROR_INVALID_DRIVE to UV_ENOENT (Saúl Ibarra Corretgé)


2014.09.18, Version 1.0.0-rc1 (Unstable), 0c28bbf7b42882853d1799ab96ff68b07f7f8d49

Changes since version 0.11.29:

* windows: improve timer precision (Alexis Campailla)

* build, gyp: set xcode flags (Recep ASLANTAS)

* ignore: include m4 files which are created manually (Recep ASLANTAS)

* build: add m4 for feature/flag-testing (Recep ASLANTAS)

* ignore: ignore Xcode project and workspace files (Recep ASLANTAS)

* unix: fix warnings about dollar symbol usage in identifiers (Recep ASLANTAS)

libuv/ChangeLog  view on Meta::CPAN

* test: add test for closing and recreating default loop (Saúl Ibarra Corretgé)

* windows: properly close the default loop (Saúl Ibarra Corretgé)

* version: add ability to specify a version suffix (Saúl Ibarra Corretgé)

* doc: add API documentation (Saúl Ibarra Corretgé)

* test: don't close connection on write error (Trevor Norris)

* windows: further simplify the code for timers (Saúl Ibarra Corretgé)

* gyp: remove UNLIMITED_SELECT from dependent define (Fedor Indutny)

* darwin: allocate enough space for select() hack (Fedor Indutny)

* unix, windows: don't allow a NULL callback on timers (Saúl Ibarra Corretgé)

* windows: simplify code in uv_timer_again (Saúl Ibarra Corretgé)

* test: use less requests on tcp-write-queue-order (Saúl Ibarra Corretgé)

* unix: stop child process watcher after last one exits (Saúl Ibarra Corretgé)

* unix: simplify how process handle queue is managed (Saúl Ibarra Corretgé)

* windows: remove duplicated field (mattn)

* core: add a reserved field to uv_handle_t and uv_req_t (Saúl Ibarra Corretgé)

libuv/ChangeLog  view on Meta::CPAN

* windows: always initialize uv_process_t (Alex Crichton)

* include: expose libuv version in header files (Saúl Ibarra Corretgé)

* fs: vectored IO API for filesystem read/write (Benjamin Saunders)

* windows: freeze in uv_tcp_endgame (Alexis Campailla)

* sunos: handle rearm errors (Fedor Indutny)

* unix: use a heap for timers (Ben Noordhuis)

* linux: always deregister closing fds from epoll (Geoffry Song)

* linux: include grp.h for setgroups() (William Light)

* unix, windows: add uv_loop_init and uv_loop_close (Saúl Ibarra Corretgé)

* unix, windows: add uv_getrusage() function (Oleg Efimov)

* win: minor error handle fix to uv_pipe_write_impl (Rasmus Pedersen)

libuv/ChangeLog  view on Meta::CPAN

* libuv: add more getaddrinfo errors (Steven Kabbes)

* unix: fix accept() EMFILE error handling (Ben Noordhuis)

* linux: fix up SO_REUSEPORT back-port (Ben Noordhuis)

* fsevents: fix subfolder check (Fedor Indutny)

* fsevents: fix invalid memory access (huxingyi)

* windows/timer: fix uv_hrtime discontinuity (Bert Belder)

* unix: fix various memory leaks and undef behavior (Fedor Indutny)

* unix, windows: always update loop time (Saúl Ibarra Corretgé)

* windows: translate system errors in uv_spawn (Alexis Campailla)

* windows: uv_spawn code refactor (Alexis Campailla)

* unix, windows: detect errors in uv_ip4/6_addr (Yorkie)

libuv/ChangeLog  view on Meta::CPAN

* test: open stdout fd in write-only mode (Ben Noordhuis)

* windows: uv_spawn shouldn't reject reparse points (Bert Belder)

* windows: use WSAGetLastError(), not errno (Ben Noordhuis)

* build: darwin: disable -fstrict-aliasing warnings (Ben Noordhuis)

* test: fix signed/unsigned compiler warning (Ben Noordhuis)

* test: add 'start timer from check handle' test (Ben Noordhuis)

* build: `all` now builds static and dynamic lib (Ben Noordhuis)

* unix, windows: add extra fields to uv_stat_t (Saúl Ibarra Corretgé)

* build: add install target to the makefile (Navaneeth Kedaram Nambiathan)

* build: switch to autotools (Ben Noordhuis)

* build: use AM_PROG_AR conditionally (Ben Noordhuis)

libuv/ChangeLog  view on Meta::CPAN

  use of c-style comments (Bert Belder)

* darwin: use uv_fs_sendfile() use the sendfile api correctly (Wynn Wilkes)

* windows: call idle handles on every loop iteration, something the unix
  implementation already did (Bert Belder)

* test: update the idle-starvation test to verify that idle handles are called
  in every loop iteration (Bert Belder)

* unix, windows: ensure that uv_run() in RUN_ONCE mode calls timers that expire
  after blocking (Ben Noordhuis)


2013.05.29, Version 0.10.9 (Stable), a195f9ace23d92345baf57582678bfc3017e6632

Changes since version 0.10.8:

* unix: fix stream refcounting buglet (Ben Noordhuis)

* unix: remove erroneous asserts (Ben Noordhuis)

libuv/ChangeLog  view on Meta::CPAN


* linux: don't use fopen() in uv_resident_set_memory() (Ben Noordhuis)


2013.04.24, Version 0.10.5 (Stable), 6595a7732c52eb4f8e57c88655f72997a8567a67

Changes since version 0.10.4:

* unix: silence STATIC_ASSERT compiler warnings (Ben Noordhuis)

* windows: make timers handle large timeouts (Miroslav Bajtoš)

* windows: remove superfluous assert statement (Bert Belder)

* unix: silence STATIC_ASSERT compiler warnings (Ben Noordhuis)

* linux: don't use fopen() in uv_resident_set_memory() (Ben Noordhuis)


2013.04.12, Version 0.10.4 (Stable), 85827e26403ac6dfa331af8ec9916ea7e27bd833

libuv/ChangeLog  view on Meta::CPAN

* include: bump UV_VERSION_MINOR (Ben Noordhuis)

* unix: improve uv_guess_handle() implementation (Ben Noordhuis)

* stream: run try_select only for pipes and ttys (Fedor Indutny)

Changes since Node.js v0.10.1:

* build: rename OS to PLATFORM (Ben Noordhuis)

* unix: make uv_timer_init() initialize repeat (Brian Mazza)

* unix: make timers handle large timeouts (Ben Noordhuis)

* build: add OBJC makefile var (Ben Noordhuis)

* Add `uv_version()` and `uv_version_string()` APIs (Bert Belder)

libuv/Makefile.am  view on Meta::CPAN

libuv_la_LDFLAGS = -no-undefined -version-info 1:0:0
libuv_la_SOURCES = src/fs-poll.c \
                   src/heap-inl.h \
                   src/idna.c \
                   src/idna.h \
                   src/inet.c \
                   src/queue.h \
                   src/strscpy.c \
                   src/strscpy.h \
                   src/threadpool.c \
                   src/timer.c \
                   src/uv-data-getter-setters.c \
                   src/uv-common.c \
                   src/uv-common.h \
                   src/version.c

if SUNOS
# Can't be turned into a CC_CHECK_CFLAGS in configure.ac, it makes compilers
# on other platforms complain that the argument is unused during compilation.
libuv_la_CFLAGS += -pthreads
endif

libuv/Makefile.am  view on Meta::CPAN

                         test/test-tcp-write-to-half-open-connection.c \
                         test/test-tcp-write-after-connect.c \
                         test/test-tcp-writealot.c \
                         test/test-tcp-write-fail.c \
                         test/test-tcp-try-write.c \
                         test/test-tcp-write-queue-order.c \
                         test/test-thread-equal.c \
                         test/test-thread.c \
                         test/test-threadpool-cancel.c \
                         test/test-threadpool.c \
                         test/test-timer-again.c \
                         test/test-timer-from-check.c \
                         test/test-timer.c \
                         test/test-tmpdir.c \
                         test/test-tty-duplicate-key.c \
                         test/test-tty.c \
                         test/test-udp-alloc-cb-fail.c \
                         test/test-udp-bind.c \
                         test/test-udp-connect.c \
                         test/test-udp-create-socket-early.c \
                         test/test-udp-dgram-too-big.c \
                         test/test-udp-ipv6.c \
                         test/test-udp-multicast-interface.c \

libuv/docs/code/ref-timer/main.c  view on Meta::CPAN

#include <stdio.h>

#include <uv.h>

uv_loop_t *loop;
uv_timer_t gc_req;
uv_timer_t fake_job_req;

void gc(uv_timer_t *handle) {
    fprintf(stderr, "Freeing unused objects\n");
}

void fake_job(uv_timer_t *handle) {
    fprintf(stdout, "Fake job done\n");
}

int main() {
    loop = uv_default_loop();

    uv_timer_init(loop, &gc_req);
    uv_unref((uv_handle_t*) &gc_req);

    uv_timer_start(&gc_req, gc, 0, 2000);

    // could actually be a TCP download or something
    uv_timer_init(loop, &fake_job_req);
    uv_timer_start(&fake_job_req, fake_job, 9000, 0);
    return uv_run(loop, UV_RUN_DEFAULT);
}

libuv/docs/code/tty-gravity/main.c  view on Meta::CPAN

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <uv.h>

uv_loop_t *loop;
uv_tty_t tty;
uv_timer_t tick;
uv_write_t write_req;
int width, height;
int pos = 0;
char *message = "  Hello TTY  ";

void update(uv_timer_t *req) {
    char data[500];

    uv_buf_t buf;
    buf.base = data;
    buf.len = sprintf(data, "\033[2J\033[H\033[%dB\033[%luC\033[42;37m%s",
                            pos,
                            (unsigned long) (width-strlen(message))/2,
                            message);
    uv_write(&write_req, (uv_stream_t*) &tty, &buf, 1, NULL);

    pos++;
    if (pos > height) {
        uv_tty_reset_mode();
        uv_timer_stop(&tick);
    }
}

int main() {
    loop = uv_default_loop();

    uv_tty_init(loop, &tty, STDOUT_FILENO, 0);
    uv_tty_set_mode(&tty, 0);
    
    if (uv_tty_get_winsize(&tty, &width, &height)) {
        fprintf(stderr, "Could not get TTY information\n");
        uv_tty_reset_mode();
        return 1;
    }

    fprintf(stderr, "Width %d, height %d\n", width, height);
    uv_timer_init(loop, &tick);
    uv_timer_start(&tick, update, 200, 200);
    return uv_run(loop, UV_RUN_DEFAULT);
}

libuv/docs/code/uvwget/main.c  view on Meta::CPAN

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <uv.h>
#include <curl/curl.h>

uv_loop_t *loop;
CURLM *curl_handle;
uv_timer_t timeout;

typedef struct curl_context_s {
    uv_poll_t poll_handle;
    curl_socket_t sockfd;
} curl_context_t;

curl_context_t *create_curl_context(curl_socket_t sockfd) {
    curl_context_t *context;

    context = (curl_context_t*) malloc(sizeof *context);

libuv/docs/code/uvwget/main.c  view on Meta::CPAN

            break;

        default:
            fprintf(stderr, "CURLMSG default\n");
            abort();
        }
    }
}

void curl_perform(uv_poll_t *req, int status, int events) {
    uv_timer_stop(&timeout);
    int running_handles;
    int flags = 0;
    if (status < 0)                      flags = CURL_CSELECT_ERR;
    if (!status && events & UV_READABLE) flags |= CURL_CSELECT_IN;
    if (!status && events & UV_WRITABLE) flags |= CURL_CSELECT_OUT;

    curl_context_t *context;

    context = (curl_context_t*)req;

    curl_multi_socket_action(curl_handle, context->sockfd, flags, &running_handles);
    check_multi_info();   
}

void on_timeout(uv_timer_t *req) {
    int running_handles;
    curl_multi_socket_action(curl_handle, CURL_SOCKET_TIMEOUT, 0, &running_handles);
    check_multi_info();
}

void start_timeout(CURLM *multi, long timeout_ms, void *userp) {
    if (timeout_ms <= 0)
        timeout_ms = 1; /* 0 means directly call socket_action, but we'll do it in a bit */
    uv_timer_start(&timeout, on_timeout, timeout_ms, 0);
}

int handle_socket(CURL *easy, curl_socket_t s, int action, void *userp, void *socketp) {
    curl_context_t *curl_context;
    if (action == CURL_POLL_IN || action == CURL_POLL_OUT) {
        if (socketp) {
            curl_context = (curl_context_t*) socketp;
        }
        else {
            curl_context = create_curl_context(s);

libuv/docs/code/uvwget/main.c  view on Meta::CPAN

    loop = uv_default_loop();

    if (argc <= 1)
        return 0;

    if (curl_global_init(CURL_GLOBAL_ALL)) {
        fprintf(stderr, "Could not init cURL\n");
        return 1;
    }

    uv_timer_init(loop, &timeout);

    curl_handle = curl_multi_init();
    curl_multi_setopt(curl_handle, CURLMOPT_SOCKETFUNCTION, handle_socket);
    curl_multi_setopt(curl_handle, CURLMOPT_TIMERFUNCTION, start_timeout);

    while (argc-- > 1) {
        add_download(argv[argc], argc);
    }

    uv_run(loop, UV_RUN_DEFAULT);

libuv/docs/src/api.rst  view on Meta::CPAN

=================

.. toctree::
   :maxdepth: 1

   errors
   version
   loop
   handle
   request
   timer
   prepare
   check
   idle
   async
   poll
   signal
   process
   stream
   tcp
   pipe

libuv/docs/src/design.rst  view on Meta::CPAN

    :align: center


#. The loop concept of 'now' is updated. The event loop caches the current time at the start of
   the event loop tick in order to reduce the number of time-related system calls.

#. If the loop is *alive*  an iteration is started, otherwise the loop will exit immediately. So,
   when is a loop considered to be *alive*? If a loop has active and ref'd handles, active
   requests or closing handles it's considered to be *alive*.

#. Due timers are run. All active timers scheduled for a time before the loop's concept of *now*
   get their callbacks called.

#. Pending callbacks are called. All I/O callbacks are called right after polling for I/O, for the
   most part. There are cases, however, in which calling such a callback is deferred for the next
   loop iteration. If the previous iteration deferred any I/O callback it will be run at this point.

#. Idle handle callbacks are called. Despite the unfortunate name, idle handles are run on every
   loop iteration, if they are active.

#. Prepare handle callbacks are called. Prepare handles get their callbacks called right before
   the loop will block for I/O.

#. Poll timeout is calculated. Before blocking for I/O the loop calculates for how long it should
   block. These are the rules when calculating the timeout:

        * If the loop was run with the ``UV_RUN_NOWAIT`` flag, the timeout is 0.
        * If the loop is going to be stopped (:c:func:`uv_stop` was called), the timeout is 0.
        * If there are no active handles or requests, the timeout is 0.
        * If there are any idle handles active, the timeout is 0.
        * If there are any handles pending to be closed, the timeout is 0.
        * If none of the above cases matches, the timeout of the closest timer is taken, or
          if there are no active timers, infinity.

#. The loop blocks for I/O. At this point the loop will block for I/O for the duration calculated
   in the previous step. All I/O related handles that were monitoring a given file descriptor
   for a read or write operation get their callbacks called at this point.

#. Check handle callbacks are called. Check handles get their callbacks called right after the
   loop has blocked for I/O. Check handles are essentially the counterpart of prepare handles.

#. Close callbacks are called. If a handle was closed by calling :c:func:`uv_close` it will
   get the close callback called.

#. Special case in case the loop was run with ``UV_RUN_ONCE``, as it implies forward progress.
   It's possible that no I/O callbacks were fired after blocking for I/O, but some time has passed
   so there might be timers which are due, those timers get their callbacks called.

#. Iteration ends. If the loop was run with ``UV_RUN_NOWAIT`` or ``UV_RUN_ONCE`` modes the
   iteration ends and :c:func:`uv_run` will return. If the loop was run with ``UV_RUN_DEFAULT``
   it will continue from the start if it's still *alive*, otherwise it will also end.


.. important::
    libuv uses a thread pool to make asynchronous file I/O operations possible, but
    network I/O is **always** performed in a single thread, each loop's thread.

libuv/docs/src/guide/basics.rst  view on Meta::CPAN

Basics of libuv
===============

libuv enforces an **asynchronous**, **event-driven** style of programming.  Its
core job is to provide an event loop and callback based notifications of I/O
and other activities.  libuv offers core utilities like timers, non-blocking
networking support, asynchronous file system access, child processes and more.

Event loops
-----------

In event-driven programming, an application expresses interest in certain events
and respond to them when they occur. The responsibility of gathering events
from the operating system or monitoring other sources of events is handled by
libuv, and the user can register callbacks to be invoked when an event occurs.
The event-loop usually keeps running *forever*. In pseudocode:

libuv/docs/src/guide/basics.rst  view on Meta::CPAN


    while there are still events to process:
        e = get the next event
        if there is a callback associated with e:
            call the callback

Some examples of events are:

* File is ready for writing
* A socket has data ready to be read
* A timer has timed out

This event loop is encapsulated by ``uv_run()`` -- the end-all function when using
libuv.

The most common activity of systems programs is to deal with input and output,
rather than a lot of number-crunching. The problem with using conventional
input/output functions (``read``, ``fprintf``, etc.) is that they are
**blocking**. The actual write to a hard disk or reading from a network, takes
a disproportionately long time compared to the speed of the processor. The
functions don't return until the task is done, so that your program is doing

libuv/docs/src/guide/basics.rst  view on Meta::CPAN


You can use the ``uv_strerror(int)`` and ``uv_err_name(int)`` functions
to get a ``const char *`` describing the error or the error name respectively.

I/O read callbacks (such as for files and sockets) are passed a parameter ``nread``. If ``nread`` is less than 0, there was an error (UV_EOF is the end of file error, which you may want to handle differently).

Handles and Requests
--------------------

libuv works by the user expressing interest in particular events. This is
usually done by creating a **handle** to an I/O device, timer or process.
Handles are opaque structs named as ``uv_TYPE_t`` where type signifies what the
handle is used for. 

.. rubric:: libuv watchers
.. literalinclude:: ../../../include/uv.h
    :lines: 197-230

Handles represent long-lived objects. Async operations on such handles are
identified using **requests**. A request is short-lived (usually used across
only one callback) and usually indicates one I/O operation on a handle.

libuv/docs/src/guide/basics.rst  view on Meta::CPAN


Handles are setup by a corresponding::

    uv_TYPE_init(uv_loop_t *, uv_TYPE_t *)

function.

Callbacks are functions which are called by libuv whenever an event the watcher
is interested in has taken place. Application specific logic will usually be
implemented in the callback. For example, an IO watcher's callback will receive
the data read from a file, a timer callback will be triggered on timeout and so
on.

Idling
++++++

Here is an example of using an idle handle. The callback is called once on
every turn of the event loop. A use case for idle handles is discussed in
:doc:`utilities`. Let us use an idle watcher to look at the watcher life cycle
and see how ``uv_run()`` will now block because a watcher is present. The idle
watcher is stopped when the count is reached and ``uv_run()`` exits since no

libuv/docs/src/guide/eventloops.rst  view on Meta::CPAN

``uv_run()`` where all the control flow occurs.

.. rubric:: src/unix/core.c - uv_run
.. literalinclude:: ../../../src/unix/core.c
    :linenos:
    :lines: 304-324
    :emphasize-lines: 10,19,21

``stop_flag`` is set by ``uv_stop()``. Now all libuv callbacks are invoked
within the event loop, which is why invoking ``uv_stop()`` in them will still
lead to this iteration of the loop occurring. First libuv updates timers, then
runs pending timer, idle and prepare callbacks, and invokes any pending I/O
callbacks. If you were to call ``uv_stop()`` in any of them, ``stop_flag``
would be set. This causes ``uv_backend_timeout()`` to return ``0``, which is
why the loop does not block on I/O. If on the other hand, you called
``uv_stop()`` in one of the check handlers, I/O has already finished and is not
affected.

``uv_stop()`` is useful to shutdown a loop when a result has been computed or
there is an error, without having to ensure that all handlers are stopped one
by one.

libuv/docs/src/guide/utilities.rst  view on Meta::CPAN

=========

This chapter catalogues tools and techniques which are useful for common tasks.
The `libev man page`_ already covers some patterns which can be adopted to
libuv through simple API changes. It also covers parts of the libuv API that
don't require entire chapters dedicated to them.

Timers
------

Timers invoke the callback after a certain time has elapsed since the timer was
started. libuv timers can also be set to invoke at regular intervals instead of
just once.

Simple use is to init a watcher and start it with a ``timeout``, and optional ``repeat``.
Timers can be stopped at any time.

.. code-block:: c

    uv_timer_t timer_req;

    uv_timer_init(loop, &timer_req);
    uv_timer_start(&timer_req, callback, 5000, 2000);

will start a repeating timer, which first starts 5 seconds (the ``timeout``) after the execution
of ``uv_timer_start``, then repeats every 2 seconds (the ``repeat``). Use:

.. code-block:: c

    uv_timer_stop(&timer_req);

to stop the timer. This can be used safely from within the callback as well.

The repeat interval can be modified at any time with::

    uv_timer_set_repeat(uv_timer_t *timer, int64_t repeat);

which will take effect **when possible**. If this function is called from
a timer callback, it means:

* If the timer was non-repeating, the timer has already been stopped. Use
  ``uv_timer_start`` again.
* If the timer is repeating, the next timeout has already been scheduled, so
  the old repeat interval will be used once more before the timer switches to
  the new interval.

The utility function::

    int uv_timer_again(uv_timer_t *)

applies **only to repeating timers** and is equivalent to stopping the timer
and then starting it with both initial ``timeout`` and ``repeat`` set to the
old ``repeat`` value. If the timer hasn't been started it fails (error code
``UV_EINVAL``) and returns -1.

An actual timer example is in the :ref:`reference count section
<reference-count>`.

.. _reference-count:

Event loop reference count
--------------------------

The event loop only runs as long as there are active handles. This system
works by having every handle increase the reference count of the event loop
when it is started and decreasing the reference count when stopped. It is also
possible to manually change the reference count of handles using::

    void uv_ref(uv_handle_t*);
    void uv_unref(uv_handle_t*);

These functions can be used to allow a loop to exit even when a watcher is
active or to use custom objects to keep the loop alive.

The latter can be used with interval timers. You might have a garbage collector
which runs every X seconds, or your network service might send a heartbeat to
others periodically, but you don't want to have to stop them along all clean
exit paths or error scenarios. Or you want the program to exit when all your
other watchers are done. In that case just unref the timer immediately after
creation so that if it is the only watcher running then ``uv_run`` will still
exit.

This is also used in node.js where some libuv methods are being bubbled up to
the JS API. A ``uv_handle_t`` (the superclass of all watchers) is created per
JS object and can be ref/unrefed.

.. rubric:: ref-timer/main.c
.. literalinclude:: ../../code/ref-timer/main.c
    :linenos:
    :lines: 5-8, 17-
    :emphasize-lines: 9

We initialize the garbage collector timer, then immediately ``unref`` it.
Observe how after 9 seconds, when the fake job is done, the program
automatically exits, even though the garbage collector is still running.

Idler pattern
-------------

The callbacks of idle handles are invoked once per event loop. The idle
callback can be used to perform some very low priority activity. For example,
you could dispatch a summary of the daily application performance to the
developers for analysis during periods of idleness, or use the application's

libuv/docs/src/guide/utilities.rst  view on Meta::CPAN

.. rubric:: uvwget/main.c - Adding urls
.. literalinclude:: ../../code/uvwget/main.c
    :linenos:
    :lines: 39-56
    :emphasize-lines: 13-14

We let libcurl directly write the data to a file, but much more is possible if
you so desire.

``start_timeout`` will be called immediately the first time by libcurl, so
things are set in motion. This simply starts a libuv `timer <Timers>`_ which
drives ``curl_multi_socket_action`` with ``CURL_SOCKET_TIMEOUT`` whenever it
times out. ``curl_multi_socket_action`` is what drives libcurl, and what we
call whenever sockets change state. But before we go into that, we need to poll
on sockets whenever ``handle_socket`` is called.

.. rubric:: uvwget/main.c - Setting up polling
.. literalinclude:: ../../code/uvwget/main.c
    :linenos:
    :lines: 102-140
    :emphasize-lines: 9,11,15,21,24

libuv/docs/src/guide/utilities.rst  view on Meta::CPAN

whenever the socket is ready for reading or writing. Calling ``uv_poll_start``
multiple times on the same handle is acceptable, it will just update the events
mask with the new value. ``curl_perform`` is the crux of this program.

.. rubric:: uvwget/main.c - Driving libcurl.
.. literalinclude:: ../../code/uvwget/main.c
    :linenos:
    :lines: 81-95
    :emphasize-lines: 2,6-7,12

The first thing we do is to stop the timer, since there has been some progress
in the interval. Then depending on what event triggered the callback, we set
the correct flags. Then we call ``curl_multi_socket_action`` with the socket
that progressed and the flags informing about what events happened. At this
point libcurl does all of its internal tasks in small increments, and will
attempt to return as fast as possible, which is exactly what an evented program
wants in its main thread. libcurl keeps queueing messages into its own queue
about transfer progress. In our case we are only interested in transfers that
are completed. So we extract these messages, and clean up handles whose
transfers are done.

libuv/docs/src/handle.rst  view on Meta::CPAN

    Returns non-zero if the handle is active, zero if it's inactive. What
    "active" means depends on the type of handle:

    - A uv_async_t handle is always active and cannot be deactivated, except
      by closing it with uv_close().

    - A uv_pipe_t, uv_tcp_t, uv_udp_t, etc. handle - basically any handle that
      deals with i/o - is active when it is doing something that involves i/o,
      like reading, writing, connecting, accepting new connections, etc.

    - A uv_check_t, uv_idle_t, uv_timer_t, etc. handle is active when it has
      been started with a call to uv_check_start(), uv_idle_start(), etc.

    Rule of thumb: if a handle of type `uv_foo_t` has a `uv_foo_start()`
    function, then it's active from the moment that function is called.
    Likewise, `uv_foo_stop()` deactivates the handle again.

.. c:function:: int uv_is_closing(const uv_handle_t* handle)

    Returns non-zero if the handle is closing or closed, zero otherwise.

libuv/docs/src/handle.rst  view on Meta::CPAN

    .. versionadded:: 1.19.0

.. _refcount:

Reference counting
------------------

The libuv event loop (if run in the default mode) will run until there are no
active `and` referenced handles left. The user can force the loop to exit early
by unreferencing handles which are active, for example by calling :c:func:`uv_unref`
after calling :c:func:`uv_timer_start`.

A handle can be referenced or unreferenced, the refcounting scheme doesn't use
a counter, so both operations are idempotent.

All handles are referenced when active by default, see :c:func:`uv_is_active`
for a more detailed explanation on what being `active` involves.

libuv/docs/src/timer.rst  view on Meta::CPAN


.. _timer:

:c:type:`uv_timer_t` --- Timer handle
=====================================

Timer handles are used to schedule callbacks to be called in the future.


Data types
----------

.. c:type:: uv_timer_t

    Timer handle type.

.. c:type:: void (*uv_timer_cb)(uv_timer_t* handle)

    Type definition for callback passed to :c:func:`uv_timer_start`.


Public members
^^^^^^^^^^^^^^

N/A

.. seealso:: The :c:type:`uv_handle_t` members also apply.


API
---

.. c:function:: int uv_timer_init(uv_loop_t* loop, uv_timer_t* handle)

    Initialize the handle.

.. c:function:: int uv_timer_start(uv_timer_t* handle, uv_timer_cb cb, uint64_t timeout, uint64_t repeat)

    Start the timer. `timeout` and `repeat` are in milliseconds.

    If `timeout` is zero, the callback fires on the next event loop iteration.
    If `repeat` is non-zero, the callback fires first after `timeout`
    milliseconds and then repeatedly after `repeat` milliseconds.

    .. note::
        Does not update the event loop's concept of "now". See :c:func:`uv_update_time` for more information.

        If the timer is already active, it is simply updated.

.. c:function:: int uv_timer_stop(uv_timer_t* handle)

    Stop the timer, the callback will not be called anymore.

.. c:function:: int uv_timer_again(uv_timer_t* handle)

    Stop the timer, and if it is repeating restart it using the repeat value
    as the timeout. If the timer has never been started before it returns
    UV_EINVAL.

.. c:function:: void uv_timer_set_repeat(uv_timer_t* handle, uint64_t repeat)

    Set the repeat interval value in milliseconds. The timer will be scheduled
    to run on the given interval, regardless of the callback execution
    duration, and will follow normal timer semantics in the case of a
    time-slice overrun.

    For example, if a 50ms repeating timer first runs for 17ms, it will be
    scheduled to run again 33ms later. If other tasks consume more than the
    33ms following the first timer callback, then the callback will run as soon
    as possible.

    .. note::
        If the repeat value is set from a timer callback it does not immediately take effect.
        If the timer was non-repeating before, it will have been stopped. If it was repeating,
        then the old repeat value will have been used to schedule the next timeout.

.. c:function:: uint64_t uv_timer_get_repeat(const uv_timer_t* handle)

    Get the timer repeat value.

.. seealso:: The :c:type:`uv_handle_t` API functions also apply.

libuv/include/uv.h  view on Meta::CPAN

  XX(FS_EVENT, fs_event)                                                      \
  XX(FS_POLL, fs_poll)                                                        \
  XX(HANDLE, handle)                                                          \
  XX(IDLE, idle)                                                              \
  XX(NAMED_PIPE, pipe)                                                        \
  XX(POLL, poll)                                                              \
  XX(PREPARE, prepare)                                                        \
  XX(PROCESS, process)                                                        \
  XX(STREAM, stream)                                                          \
  XX(TCP, tcp)                                                                \
  XX(TIMER, timer)                                                            \
  XX(TTY, tty)                                                                \
  XX(UDP, udp)                                                                \
  XX(SIGNAL, signal)                                                          \

#define UV_REQ_TYPE_MAP(XX)                                                   \
  XX(REQ, req)                                                                \
  XX(CONNECT, connect)                                                        \
  XX(WRITE, write)                                                            \
  XX(SHUTDOWN, shutdown)                                                      \
  XX(UDP_SEND, udp_send)                                                      \

libuv/include/uv.h  view on Meta::CPAN

/* Handle types. */
typedef struct uv_loop_s uv_loop_t;
typedef struct uv_handle_s uv_handle_t;
typedef struct uv_dir_s uv_dir_t;
typedef struct uv_stream_s uv_stream_t;
typedef struct uv_tcp_s uv_tcp_t;
typedef struct uv_udp_s uv_udp_t;
typedef struct uv_pipe_s uv_pipe_t;
typedef struct uv_tty_s uv_tty_t;
typedef struct uv_poll_s uv_poll_t;
typedef struct uv_timer_s uv_timer_t;
typedef struct uv_prepare_s uv_prepare_t;
typedef struct uv_check_s uv_check_t;
typedef struct uv_idle_s uv_idle_t;
typedef struct uv_async_s uv_async_t;
typedef struct uv_process_s uv_process_t;
typedef struct uv_fs_event_s uv_fs_event_t;
typedef struct uv_fs_poll_s uv_fs_poll_t;
typedef struct uv_signal_s uv_signal_t;

/* Request types. */

libuv/include/uv.h  view on Meta::CPAN

                            uv_buf_t* buf);
typedef void (*uv_read_cb)(uv_stream_t* stream,
                           ssize_t nread,
                           const uv_buf_t* buf);
typedef void (*uv_write_cb)(uv_write_t* req, int status);
typedef void (*uv_connect_cb)(uv_connect_t* req, int status);
typedef void (*uv_shutdown_cb)(uv_shutdown_t* req, int status);
typedef void (*uv_connection_cb)(uv_stream_t* server, int status);
typedef void (*uv_close_cb)(uv_handle_t* handle);
typedef void (*uv_poll_cb)(uv_poll_t* handle, int status, int events);
typedef void (*uv_timer_cb)(uv_timer_t* handle);
typedef void (*uv_async_cb)(uv_async_t* handle);
typedef void (*uv_prepare_cb)(uv_prepare_t* handle);
typedef void (*uv_check_cb)(uv_check_t* handle);
typedef void (*uv_idle_cb)(uv_idle_t* handle);
typedef void (*uv_exit_cb)(uv_process_t*, int64_t exit_status, int term_signal);
typedef void (*uv_walk_cb)(uv_handle_t* handle, void* arg);
typedef void (*uv_fs_cb)(uv_fs_t* req);
typedef void (*uv_work_cb)(uv_work_t* req);
typedef void (*uv_after_work_cb)(uv_work_t* req, int status);
typedef void (*uv_getaddrinfo_cb)(uv_getaddrinfo_t* req,

libuv/include/uv.h  view on Meta::CPAN

  UV_ASYNC_PRIVATE_FIELDS
};

UV_EXTERN int uv_async_init(uv_loop_t*,
                            uv_async_t* async,
                            uv_async_cb async_cb);
UV_EXTERN int uv_async_send(uv_async_t* async);


/*
 * uv_timer_t is a subclass of uv_handle_t.
 *
 * Used to get woken up at a specified time in the future.
 */
struct uv_timer_s {
  UV_HANDLE_FIELDS
  UV_TIMER_PRIVATE_FIELDS
};

UV_EXTERN int uv_timer_init(uv_loop_t*, uv_timer_t* handle);
UV_EXTERN int uv_timer_start(uv_timer_t* handle,
                             uv_timer_cb cb,
                             uint64_t timeout,
                             uint64_t repeat);
UV_EXTERN int uv_timer_stop(uv_timer_t* handle);
UV_EXTERN int uv_timer_again(uv_timer_t* handle);
UV_EXTERN void uv_timer_set_repeat(uv_timer_t* handle, uint64_t repeat);
UV_EXTERN uint64_t uv_timer_get_repeat(const uv_timer_t* handle);


/*
 * uv_getaddrinfo_t is a subclass of uv_req_t.
 *
 * Request object for uv_getaddrinfo.
 */
struct uv_getaddrinfo_s {
  UV_REQ_FIELDS
  /* read-only */

libuv/include/uv/unix.h  view on Meta::CPAN

  void* prepare_handles[2];                                                   \
  void* check_handles[2];                                                     \
  void* idle_handles[2];                                                      \
  void* async_handles[2];                                                     \
  void (*async_unused)(void);  /* TODO(bnoordhuis) Remove in libuv v2. */     \
  uv__io_t async_io_watcher;                                                  \
  int async_wfd;                                                              \
  struct {                                                                    \
    void* min;                                                                \
    unsigned int nelts;                                                       \
  } timer_heap;                                                               \
  uint64_t timer_counter;                                                     \
  uint64_t time;                                                              \
  int signal_pipefd[2];                                                       \
  uv__io_t signal_io_watcher;                                                 \
  uv_signal_t child_watcher;                                                  \
  int emfile_fd;                                                              \
  UV_PLATFORM_LOOP_FIELDS                                                     \

#define UV_REQ_TYPE_PRIVATE /* empty */

#define UV_REQ_PRIVATE_FIELDS  /* empty */

libuv/include/uv/unix.h  view on Meta::CPAN

#define UV_IDLE_PRIVATE_FIELDS                                                \
  uv_idle_cb idle_cb;                                                         \
  void* queue[2];                                                             \

#define UV_ASYNC_PRIVATE_FIELDS                                               \
  uv_async_cb async_cb;                                                       \
  void* queue[2];                                                             \
  int pending;                                                                \

#define UV_TIMER_PRIVATE_FIELDS                                               \
  uv_timer_cb timer_cb;                                                       \
  void* heap_node[3];                                                         \
  uint64_t timeout;                                                           \
  uint64_t repeat;                                                            \
  uint64_t start_id;

#define UV_GETADDRINFO_PRIVATE_FIELDS                                         \
  struct uv__work work_req;                                                   \
  uv_getaddrinfo_cb cb;                                                       \
  struct addrinfo* hints;                                                     \
  char* hostname;                                                             \

libuv/include/uv/win.h  view on Meta::CPAN

    /* The loop's I/O completion port */                                      \
  HANDLE iocp;                                                                \
  /* The current time according to the event loop. in msecs. */               \
  uint64_t time;                                                              \
  /* Tail of a single-linked circular queue of pending reqs. If the queue */  \
  /* is empty, tail_ is NULL. If there is only one item, */                   \
  /* tail_->next_req == tail_ */                                              \
  uv_req_t* pending_reqs_tail;                                                \
  /* Head of a single-linked list of closed handles */                        \
  uv_handle_t* endgame_handles;                                               \
  /* TODO(bnoordhuis) Stop heap-allocating |timer_heap| in libuv v2.x. */     \
  void* timer_heap;                                                           \
    /* Lists of active loop (prepare / check / idle) watchers */              \
  uv_prepare_t* prepare_handles;                                              \
  uv_check_t* check_handles;                                                  \
  uv_idle_t* idle_handles;                                                    \
  /* This pointer will refer to the prepare/check/idle handle whose */        \
  /* callback is scheduled to be called next. This is needed to allow */      \
  /* safe removal from one of the lists above while that list being */        \
  /* iterated over. */                                                        \
  uv_prepare_t* next_prepare_handle;                                          \
  uv_check_t* next_check_handle;                                              \
  uv_idle_t* next_idle_handle;                                                \
  /* This handle holds the peer sockets for the fast variant of uv_poll_t */  \
  SOCKET poll_peer_sockets[UV_MSAFD_PROVIDER_COUNT];                          \
  /* Counter to keep track of active tcp streams */                           \
  unsigned int active_tcp_streams;                                            \
  /* Counter to keep track of active udp streams */                           \
  unsigned int active_udp_streams;                                            \
  /* Counter to started timer */                                              \
  uint64_t timer_counter;                                                     \
  /* Threadpool */                                                            \
  void* wq[2];                                                                \
  uv_mutex_t wq_mutex;                                                        \
  uv_async_t wq_async;

#define UV_REQ_TYPE_PRIVATE                                                   \
  /* TODO: remove the req suffix */                                           \
  UV_ACCEPT,                                                                  \
  UV_FS_EVENT_REQ,                                                            \
  UV_POLL_REQ,                                                                \

libuv/include/uv/win.h  view on Meta::CPAN

  uv_alloc_cb alloc_cb;                                                       \
  LPFN_WSARECV func_wsarecv;                                                  \
  LPFN_WSARECVFROM func_wsarecvfrom;

#define uv_pipe_server_fields                                                 \
  int pending_instances;                                                      \
  uv_pipe_accept_t* accept_reqs;                                              \
  uv_pipe_accept_t* pending_accepts;

#define uv_pipe_connection_fields                                             \
  uv_timer_t* eof_timer;                                                      \
  uv_write_t dummy; /* TODO: retained for ABI compat; remove this in v2.x. */ \
  DWORD ipc_remote_pid;                                                       \
  union {                                                                     \
    uint32_t payload_remaining;                                               \
    uint64_t dummy; /* TODO: retained for ABI compat; remove this in v2.x. */ \
  } ipc_data_frame;                                                           \
  void* ipc_xfer_queue[2];                                                    \
  int ipc_xfer_queue_length;                                                  \
  uv_write_t* non_overlapped_writes_tail;                                     \
  CRITICAL_SECTION readfile_thread_lock;                                      \

libuv/include/uv/win.h  view on Meta::CPAN

  unsigned char mask_events_1;                                                \
  unsigned char mask_events_2;                                                \
  unsigned char events;

#define UV_TIMER_PRIVATE_FIELDS                                               \
  void* heap_node[3];                                                         \
  int unused;                                                                 \
  uint64_t timeout;                                                           \
  uint64_t repeat;                                                            \
  uint64_t start_id;                                                          \
  uv_timer_cb timer_cb;

#define UV_ASYNC_PRIVATE_FIELDS                                               \
  struct uv_req_s async_req;                                                  \
  uv_async_cb async_cb;                                                       \
  /* char to avoid alignment issues */                                        \
  char volatile async_sent;

#define UV_PREPARE_PRIVATE_FIELDS                                             \
  uv_prepare_t* prepare_prev;                                                 \
  uv_prepare_t* prepare_next;                                                 \

libuv/samples/socks5-proxy/client.c  view on Meta::CPAN

static int do_req_start(client_ctx *cx);
static int do_req_parse(client_ctx *cx);
static int do_req_lookup(client_ctx *cx);
static int do_req_connect_start(client_ctx *cx);
static int do_req_connect(client_ctx *cx);
static int do_proxy_start(client_ctx *cx);
static int do_proxy(client_ctx *cx);
static int do_kill(client_ctx *cx);
static int do_almost_dead(client_ctx *cx);
static int conn_cycle(const char *who, conn *a, conn *b);
static void conn_timer_reset(conn *c);
static void conn_timer_expire(uv_timer_t *handle);
static void conn_getaddrinfo(conn *c, const char *hostname);
static void conn_getaddrinfo_done(uv_getaddrinfo_t *req,
                                  int status,
                                  struct addrinfo *ai);
static int conn_connect(conn *c);
static void conn_connect_done(uv_connect_t *req, int status);
static void conn_read(conn *c);
static void conn_read_done(uv_stream_t *handle,
                           ssize_t nread,
                           const uv_buf_t *buf);

libuv/samples/socks5-proxy/client.c  view on Meta::CPAN

  cx->sx = sx;
  cx->state = s_handshake;
  s5_init(&cx->parser);

  incoming = &cx->incoming;
  incoming->client = cx;
  incoming->result = 0;
  incoming->rdstate = c_stop;
  incoming->wrstate = c_stop;
  incoming->idle_timeout = sx->idle_timeout;
  CHECK(0 == uv_timer_init(sx->loop, &incoming->timer_handle));

  outgoing = &cx->outgoing;
  outgoing->client = cx;
  outgoing->result = 0;
  outgoing->rdstate = c_stop;
  outgoing->wrstate = c_stop;
  outgoing->idle_timeout = sx->idle_timeout;
  CHECK(0 == uv_tcp_init(cx->sx->loop, &outgoing->handle.tcp));
  CHECK(0 == uv_timer_init(cx->sx->loop, &outgoing->timer_handle));

  /* Wait for the initial packet. */
  conn_read(incoming);
}

/* This is the core state machine that drives the client <-> upstream proxy.
 * We move through the initial handshake and authentication steps first and
 * end up (if all goes well) in the proxy state where we're just proxying
 * data between the client and upstream.
 */

libuv/samples/socks5-proxy/client.c  view on Meta::CPAN

      conn_read(b);
    } else if (b->rdstate == c_done) {
      conn_write(a, b->t.buf, b->result);
      b->rdstate = c_stop;  /* Triggers the call to conn_read() above. */
    }
  }

  return 0;
}

static void conn_timer_reset(conn *c) {
  CHECK(0 == uv_timer_start(&c->timer_handle,
                            conn_timer_expire,
                            c->idle_timeout,
                            0));
}

static void conn_timer_expire(uv_timer_t *handle) {
  conn *c;

  c = CONTAINER_OF(handle, conn, timer_handle);
  c->result = UV_ETIMEDOUT;
  do_next(c->client);
}

static void conn_getaddrinfo(conn *c, const char *hostname) {
  struct addrinfo hints;

  memset(&hints, 0, sizeof(hints));
  hints.ai_family = AF_UNSPEC;
  hints.ai_socktype = SOCK_STREAM;
  hints.ai_protocol = IPPROTO_TCP;
  CHECK(0 == uv_getaddrinfo(c->client->sx->loop,
                            &c->t.addrinfo_req,
                            conn_getaddrinfo_done,
                            hostname,
                            NULL,
                            &hints));
  conn_timer_reset(c);
}

static void conn_getaddrinfo_done(uv_getaddrinfo_t *req,
                                  int status,
                                  struct addrinfo *ai) {
  conn *c;

  c = CONTAINER_OF(req, conn, t.addrinfo_req);
  c->result = status;

libuv/samples/socks5-proxy/client.c  view on Meta::CPAN

  }

  uv_freeaddrinfo(ai);
  do_next(c->client);
}

/* Assumes that c->t.sa contains a valid AF_INET or AF_INET6 address. */
static int conn_connect(conn *c) {
  ASSERT(c->t.addr.sa_family == AF_INET ||
         c->t.addr.sa_family == AF_INET6);
  conn_timer_reset(c);
  return uv_tcp_connect(&c->t.connect_req,
                        &c->handle.tcp,
                        &c->t.addr,
                        conn_connect_done);
}

static void conn_connect_done(uv_connect_t *req, int status) {
  conn *c;

  if (status == UV_ECANCELED) {

libuv/samples/socks5-proxy/client.c  view on Meta::CPAN


  c = CONTAINER_OF(req, conn, t.connect_req);
  c->result = status;
  do_next(c->client);
}

static void conn_read(conn *c) {
  ASSERT(c->rdstate == c_stop);
  CHECK(0 == uv_read_start(&c->handle.stream, conn_alloc, conn_read_done));
  c->rdstate = c_busy;
  conn_timer_reset(c);
}

static void conn_read_done(uv_stream_t *handle,
                           ssize_t nread,
                           const uv_buf_t *buf) {
  conn *c;

  c = CONTAINER_OF(handle, conn, handle);
  ASSERT(c->t.buf == buf->base);
  ASSERT(c->rdstate == c_busy);

libuv/samples/socks5-proxy/client.c  view on Meta::CPAN

   * memory.
   */
  buf.base = (char *) data;
  buf.len = len;

  CHECK(0 == uv_write(&c->write_req,
                      &c->handle.stream,
                      &buf,
                      1,
                      conn_write_done));
  conn_timer_reset(c);
}

static void conn_write_done(uv_write_t *req, int status) {
  conn *c;

  if (status == UV_ECANCELED) {
    return;  /* Handle has been closed. */
  }

  c = CONTAINER_OF(req, conn, write_req);

libuv/samples/socks5-proxy/client.c  view on Meta::CPAN

  c->wrstate = c_done;
  c->result = status;
  do_next(c->client);
}

static void conn_close(conn *c) {
  ASSERT(c->rdstate != c_dead);
  ASSERT(c->wrstate != c_dead);
  c->rdstate = c_dead;
  c->wrstate = c_dead;
  c->timer_handle.data = c;
  c->handle.handle.data = c;
  uv_close(&c->handle.handle, conn_close_done);
  uv_close((uv_handle_t *) &c->timer_handle, conn_close_done);
}

static void conn_close_done(uv_handle_t *handle) {
  conn *c;

  c = handle->data;
  do_next(c->client);
}

libuv/samples/socks5-proxy/defs.h  view on Meta::CPAN

  unsigned char wrstate;
  unsigned int idle_timeout;
  struct client_ctx *client;  /* Backlink to owning client context. */
  ssize_t result;
  union {
    uv_handle_t handle;
    uv_stream_t stream;
    uv_tcp_t tcp;
    uv_udp_t udp;
  } handle;
  uv_timer_t timer_handle;  /* For detecting timeouts. */
  uv_write_t write_req;
  /* We only need one of these at a time so make them share memory. */
  union {
    uv_getaddrinfo_t addrinfo_req;
    uv_connect_t connect_req;
    uv_req_t req;
    struct sockaddr_in6 addr6;
    struct sockaddr_in addr4;
    struct sockaddr addr;
    char buf[2048];  /* Scratch space. Used to read data into. */

libuv/src/fs-poll.c  view on Meta::CPAN

#include <stdlib.h>
#include <string.h>

struct poll_ctx {
  uv_fs_poll_t* parent_handle;
  int busy_polling;
  unsigned int interval;
  uint64_t start_time;
  uv_loop_t* loop;
  uv_fs_poll_cb poll_cb;
  uv_timer_t timer_handle;
  uv_fs_t fs_req; /* TODO(bnoordhuis) mark fs_req internal */
  uv_stat_t statbuf;
  struct poll_ctx* previous; /* context from previous start()..stop() period */
  char path[1]; /* variable length */
};

static int statbuf_eq(const uv_stat_t* a, const uv_stat_t* b);
static void poll_cb(uv_fs_t* req);
static void timer_cb(uv_timer_t* timer);
static void timer_close_cb(uv_handle_t* handle);

static uv_stat_t zero_statbuf;


int uv_fs_poll_init(uv_loop_t* loop, uv_fs_poll_t* handle) {
  uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_POLL);
  handle->poll_ctx = NULL;
  return 0;
}

libuv/src/fs-poll.c  view on Meta::CPAN

  if (ctx == NULL)
    return UV_ENOMEM;

  ctx->loop = loop;
  ctx->poll_cb = cb;
  ctx->interval = interval ? interval : 1;
  ctx->start_time = uv_now(loop);
  ctx->parent_handle = handle;
  memcpy(ctx->path, path, len + 1);

  err = uv_timer_init(loop, &ctx->timer_handle);
  if (err < 0)
    goto error;

  ctx->timer_handle.flags |= UV_HANDLE_INTERNAL;
  uv__handle_unref(&ctx->timer_handle);

  err = uv_fs_stat(loop, &ctx->fs_req, ctx->path, poll_cb);
  if (err < 0)
    goto error;

  if (handle->poll_ctx != NULL)
    ctx->previous = handle->poll_ctx;
  handle->poll_ctx = ctx;
  uv__handle_start(handle);

libuv/src/fs-poll.c  view on Meta::CPAN

int uv_fs_poll_stop(uv_fs_poll_t* handle) {
  struct poll_ctx* ctx;

  if (!uv_is_active((uv_handle_t*)handle))
    return 0;

  ctx = handle->poll_ctx;
  assert(ctx != NULL);
  assert(ctx->parent_handle == handle);

  /* Close the timer if it's active. If it's inactive, there's a stat request
   * in progress and poll_cb will take care of the cleanup.
   */
  if (uv_is_active((uv_handle_t*)&ctx->timer_handle))
    uv_close((uv_handle_t*)&ctx->timer_handle, timer_close_cb);

  uv__handle_stop(handle);

  return 0;
}


int uv_fs_poll_getpath(uv_fs_poll_t* handle, char* buffer, size_t* size) {
  struct poll_ctx* ctx;
  size_t required_len;

libuv/src/fs-poll.c  view on Meta::CPAN



void uv__fs_poll_close(uv_fs_poll_t* handle) {
  uv_fs_poll_stop(handle);

  if (handle->poll_ctx == NULL)
    uv__make_close_pending((uv_handle_t*)handle);
}


static void timer_cb(uv_timer_t* timer) {
  struct poll_ctx* ctx;

  ctx = container_of(timer, struct poll_ctx, timer_handle);
  assert(ctx->parent_handle != NULL);
  assert(ctx->parent_handle->poll_ctx == ctx);
  ctx->start_time = uv_now(ctx->loop);

  if (uv_fs_stat(ctx->loop, &ctx->fs_req, ctx->path, poll_cb))
    abort();
}


static void poll_cb(uv_fs_t* req) {

libuv/src/fs-poll.c  view on Meta::CPAN

    if (ctx->busy_polling < 0 || !statbuf_eq(&ctx->statbuf, statbuf))
      ctx->poll_cb(ctx->parent_handle, 0, &ctx->statbuf, statbuf);

  ctx->statbuf = *statbuf;
  ctx->busy_polling = 1;

out:
  uv_fs_req_cleanup(req);

  if (!uv_is_active((uv_handle_t*)handle) || uv__is_closing(handle)) {
    uv_close((uv_handle_t*)&ctx->timer_handle, timer_close_cb);
    return;
  }

  /* Reschedule timer, subtract the delay from doing the stat(). */
  interval = ctx->interval;
  interval -= (uv_now(ctx->loop) - ctx->start_time) % interval;

  if (uv_timer_start(&ctx->timer_handle, timer_cb, interval, 0))
    abort();
}


static void timer_close_cb(uv_handle_t* timer) {
  struct poll_ctx* ctx;
  struct poll_ctx* it;
  struct poll_ctx* last;
  uv_fs_poll_t* handle;

  ctx = container_of(timer, struct poll_ctx, timer_handle);
  handle = ctx->parent_handle;
  if (ctx == handle->poll_ctx) {
    handle->poll_ctx = ctx->previous;
    if (handle->poll_ctx == NULL)
      uv__make_close_pending((uv_handle_t*)handle);
  } else {
    for (last = handle->poll_ctx, it = last->previous;
         it != ctx;
         last = it, it = it->previous) {
      assert(last->previous != NULL);

libuv/src/timer.c  view on Meta::CPAN

 */

#include "uv.h"
#include "uv-common.h"
#include "heap-inl.h"

#include <assert.h>
#include <limits.h>


static struct heap *timer_heap(const uv_loop_t* loop) {
#ifdef _WIN32
  return (struct heap*) loop->timer_heap;
#else
  return (struct heap*) &loop->timer_heap;
#endif
}


static int timer_less_than(const struct heap_node* ha,
                           const struct heap_node* hb) {
  const uv_timer_t* a;
  const uv_timer_t* b;

  a = container_of(ha, uv_timer_t, heap_node);
  b = container_of(hb, uv_timer_t, heap_node);

  if (a->timeout < b->timeout)
    return 1;
  if (b->timeout < a->timeout)
    return 0;

  /* Compare start_id when both have the same timeout. start_id is
   * allocated with loop->timer_counter in uv_timer_start().
   */
  if (a->start_id < b->start_id)
    return 1;
  if (b->start_id < a->start_id)
    return 0;

  return 0;
}


int uv_timer_init(uv_loop_t* loop, uv_timer_t* handle) {
  uv__handle_init(loop, (uv_handle_t*)handle, UV_TIMER);
  handle->timer_cb = NULL;
  handle->repeat = 0;
  return 0;
}


int uv_timer_start(uv_timer_t* handle,
                   uv_timer_cb cb,
                   uint64_t timeout,
                   uint64_t repeat) {
  uint64_t clamped_timeout;

  if (cb == NULL)
    return UV_EINVAL;

  if (uv__is_active(handle))
    uv_timer_stop(handle);

  clamped_timeout = handle->loop->time + timeout;
  if (clamped_timeout < timeout)
    clamped_timeout = (uint64_t) -1;

  handle->timer_cb = cb;
  handle->timeout = clamped_timeout;
  handle->repeat = repeat;
  /* start_id is the second index to be compared in uv__timer_cmp() */
  handle->start_id = handle->loop->timer_counter++;

  heap_insert(timer_heap(handle->loop),
              (struct heap_node*) &handle->heap_node,
              timer_less_than);
  uv__handle_start(handle);

  return 0;
}


int uv_timer_stop(uv_timer_t* handle) {
  if (!uv__is_active(handle))
    return 0;

  heap_remove(timer_heap(handle->loop),
              (struct heap_node*) &handle->heap_node,
              timer_less_than);
  uv__handle_stop(handle);

  return 0;
}


int uv_timer_again(uv_timer_t* handle) {
  if (handle->timer_cb == NULL)
    return UV_EINVAL;

  if (handle->repeat) {
    uv_timer_stop(handle);
    uv_timer_start(handle, handle->timer_cb, handle->repeat, handle->repeat);
  }

  return 0;
}


void uv_timer_set_repeat(uv_timer_t* handle, uint64_t repeat) {
  handle->repeat = repeat;
}


uint64_t uv_timer_get_repeat(const uv_timer_t* handle) {
  return handle->repeat;
}


int uv__next_timeout(const uv_loop_t* loop) {
  const struct heap_node* heap_node;
  const uv_timer_t* handle;
  uint64_t diff;

  heap_node = heap_min(timer_heap(loop));
  if (heap_node == NULL)
    return -1; /* block indefinitely */

  handle = container_of(heap_node, uv_timer_t, heap_node);
  if (handle->timeout <= loop->time)
    return 0;

  diff = handle->timeout - loop->time;
  if (diff > INT_MAX)
    diff = INT_MAX;

  return (int) diff;
}


void uv__run_timers(uv_loop_t* loop) {
  struct heap_node* heap_node;
  uv_timer_t* handle;

  for (;;) {
    heap_node = heap_min(timer_heap(loop));
    if (heap_node == NULL)
      break;

    handle = container_of(heap_node, uv_timer_t, heap_node);
    if (handle->timeout > loop->time)
      break;

    uv_timer_stop(handle);
    uv_timer_again(handle);
    handle->timer_cb(handle);
  }
}


void uv__timer_close(uv_timer_t* handle) {
  uv_timer_stop(handle);
}

libuv/src/unix/core.c  view on Meta::CPAN


  case UV_IDLE:
    uv__idle_close((uv_idle_t*)handle);
    break;

  case UV_ASYNC:
    uv__async_close((uv_async_t*)handle);
    break;

  case UV_TIMER:
    uv__timer_close((uv_timer_t*)handle);
    break;

  case UV_PROCESS:
    uv__process_close((uv_process_t*)handle);
    break;

  case UV_FS_EVENT:
    uv__fs_event_close((uv_fs_event_t*)handle);
    break;

libuv/src/unix/core.c  view on Meta::CPAN

  int timeout;
  int r;
  int ran_pending;

  r = uv__loop_alive(loop);
  if (!r)
    uv__update_time(loop);

  while (r != 0 && loop->stop_flag == 0) {
    uv__update_time(loop);
    uv__run_timers(loop);
    ran_pending = uv__run_pending(loop);
    uv__run_idle(loop);
    uv__run_prepare(loop);

    timeout = 0;
    if ((mode == UV_RUN_ONCE && !ran_pending) || mode == UV_RUN_DEFAULT)
      timeout = uv_backend_timeout(loop);

    uv__io_poll(loop, timeout);
    uv__run_check(loop);
    uv__run_closing_handles(loop);

    if (mode == UV_RUN_ONCE) {
      /* UV_RUN_ONCE implies forward progress: at least one callback must have
       * been invoked when it returns. uv__io_poll() can return without doing
       * I/O (meaning: no callbacks) when its timeout expires - which means we
       * have pending timers that satisfy the forward progress constraint.
       *
       * UV_RUN_NOWAIT makes no guarantees about progress so it's omitted from
       * the check.
       */
      uv__update_time(loop);
      uv__run_timers(loop);
    }

    r = uv__loop_alive(loop);
    if (mode == UV_RUN_ONCE || mode == UV_RUN_NOWAIT)
      break;
  }

  /* The if statement lets gcc compile it to a conditional store. Avoids
   * dirtying a cache line.
   */

libuv/src/unix/loop.c  view on Meta::CPAN


int uv_loop_init(uv_loop_t* loop) {
  void* saved_data;
  int err;


  saved_data = loop->data;
  memset(loop, 0, sizeof(*loop));
  loop->data = saved_data;

  heap_init((struct heap*) &loop->timer_heap);
  QUEUE_INIT(&loop->wq);
  QUEUE_INIT(&loop->idle_handles);
  QUEUE_INIT(&loop->async_handles);
  QUEUE_INIT(&loop->check_handles);
  QUEUE_INIT(&loop->prepare_handles);
  QUEUE_INIT(&loop->handle_queue);

  loop->active_handles = 0;
  loop->active_reqs.count = 0;
  loop->nfds = 0;

libuv/src/unix/loop.c  view on Meta::CPAN


  loop->closing_handles = NULL;
  uv__update_time(loop);
  loop->async_io_watcher.fd = -1;
  loop->async_wfd = -1;
  loop->signal_pipefd[0] = -1;
  loop->signal_pipefd[1] = -1;
  loop->backend_fd = -1;
  loop->emfile_fd = -1;

  loop->timer_counter = 0;
  loop->stop_flag = 0;

  err = uv__platform_loop_init(loop);
  if (err)
    return err;

  uv__signal_global_once_init();
  err = uv_signal_init(loop, &loop->child_watcher);
  if (err)
    goto fail_signal_init;

libuv/src/unix/sunos.c  view on Meta::CPAN

      if (w == &loop->signal_io_watcher)
        have_signals = 1;
      else
        w->cb(loop, w, pe->portev_events);

      nevents++;

      if (w != loop->watchers[fd])
        continue;  /* Disabled by callback. */

      /* Events Ports operates in oneshot mode, rearm timer on next run. */
      if (w->pevents != 0 && QUEUE_EMPTY(&w->watcher_queue))
        QUEUE_INSERT_TAIL(&loop->watcher_queue, &w->watcher_queue);
    }

    if (have_signals != 0)
      loop->signal_io_watcher.cb(loop, &loop->signal_io_watcher, POLLIN);

    loop->watchers[loop->nwatchers] = NULL;
    loop->watchers[loop->nwatchers + 1] = NULL;

libuv/src/uv-common.h  view on Meta::CPAN


size_t uv__count_bufs(const uv_buf_t bufs[], unsigned int nbufs);

int uv__socket_sockopt(uv_handle_t* handle, int optname, int* value);

void uv__fs_scandir_cleanup(uv_fs_t* req);
void uv__fs_readdir_cleanup(uv_fs_t* req);
uv_dirent_type_t uv__fs_get_dirent_type(uv__dirent_t* dent);

int uv__next_timeout(const uv_loop_t* loop);
void uv__run_timers(uv_loop_t* loop);
void uv__timer_close(uv_timer_t* handle);

#define uv__has_active_reqs(loop)                                             \
  ((loop)->active_reqs.count > 0)

#define uv__req_register(loop, req)                                           \
  do {                                                                        \
    (loop)->active_reqs.count++;                                              \
  }                                                                           \
  while (0)

libuv/src/win/core.c  view on Meta::CPAN


  /* Initialize utilities */
  uv__util_init();

  /* Initialize system wakeup detection */
  uv__init_detect_system_wakeup();
}


int uv_loop_init(uv_loop_t* loop) {
  struct heap* timer_heap;
  int err;

  /* Initialize libuv itself first */
  uv__once_init();

  /* Create an I/O completion port */
  loop->iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1);
  if (loop->iocp == NULL)
    return uv_translate_sys_error(GetLastError());

libuv/src/win/core.c  view on Meta::CPAN


  QUEUE_INIT(&loop->wq);
  QUEUE_INIT(&loop->handle_queue);
  loop->active_reqs.count = 0;
  loop->active_handles = 0;

  loop->pending_reqs_tail = NULL;

  loop->endgame_handles = NULL;

  loop->timer_heap = timer_heap = uv__malloc(sizeof(*timer_heap));
  if (timer_heap == NULL) {
    err = UV_ENOMEM;
    goto fail_timers_alloc;
  }

  heap_init(timer_heap);

  loop->check_handles = NULL;
  loop->prepare_handles = NULL;
  loop->idle_handles = NULL;

  loop->next_prepare_handle = NULL;
  loop->next_check_handle = NULL;
  loop->next_idle_handle = NULL;

  memset(&loop->poll_peer_sockets, 0, sizeof loop->poll_peer_sockets);

  loop->active_tcp_streams = 0;
  loop->active_udp_streams = 0;

  loop->timer_counter = 0;
  loop->stop_flag = 0;

  err = uv_mutex_init(&loop->wq_mutex);
  if (err)
    goto fail_mutex_init;

  err = uv_async_init(loop, &loop->wq_async, uv__work_done);
  if (err)
    goto fail_async_init;

libuv/src/win/core.c  view on Meta::CPAN

  err = uv__loops_add(loop);
  if (err)
    goto fail_async_init;

  return 0;

fail_async_init:
  uv_mutex_destroy(&loop->wq_mutex);

fail_mutex_init:
  uv__free(timer_heap);
  loop->timer_heap = NULL;

fail_timers_alloc:
  CloseHandle(loop->iocp);
  loop->iocp = INVALID_HANDLE_VALUE;

  return err;
}


void uv_update_time(uv_loop_t* loop) {
  uint64_t new_time = uv__hrtime(1000);
  assert(new_time >= loop->time);

libuv/src/win/core.c  view on Meta::CPAN

    if (sock != 0 && sock != INVALID_SOCKET)
      closesocket(sock);
  }

  uv_mutex_lock(&loop->wq_mutex);
  assert(QUEUE_EMPTY(&loop->wq) && "thread pool work queue not empty!");
  assert(!uv__has_active_reqs(loop));
  uv_mutex_unlock(&loop->wq_mutex);
  uv_mutex_destroy(&loop->wq_mutex);

  uv__free(loop->timer_heap);
  loop->timer_heap = NULL;

  CloseHandle(loop->iocp);
}


int uv__loop_configure(uv_loop_t* loop, uv_loop_option option, va_list ap) {
  return UV_ENOSYS;
}


libuv/src/win/core.c  view on Meta::CPAN

  DWORD timeout;
  int r;
  int ran_pending;

  r = uv__loop_alive(loop);
  if (!r)
    uv_update_time(loop);

  while (r != 0 && loop->stop_flag == 0) {
    uv_update_time(loop);
    uv__run_timers(loop);

    ran_pending = uv_process_reqs(loop);
    uv_idle_invoke(loop);
    uv_prepare_invoke(loop);

    timeout = 0;
    if ((mode == UV_RUN_ONCE && !ran_pending) || mode == UV_RUN_DEFAULT)
      timeout = uv_backend_timeout(loop);

    if (pGetQueuedCompletionStatusEx)

libuv/src/win/core.c  view on Meta::CPAN

      uv__poll_wine(loop, timeout);


    uv_check_invoke(loop);
    uv_process_endgames(loop);

    if (mode == UV_RUN_ONCE) {
      /* UV_RUN_ONCE implies forward progress: at least one callback must have
       * been invoked when it returns. uv__io_poll() can return without doing
       * I/O (meaning: no callbacks) when its timeout expires - which means we
       * have pending timers that satisfy the forward progress constraint.
       *
       * UV_RUN_NOWAIT makes no guarantees about progress so it's omitted from
       * the check.
       */
      uv__run_timers(loop);
    }

    r = uv__loop_alive(loop);
    if (mode == UV_RUN_ONCE || mode == UV_RUN_NOWAIT)
      break;
  }

  /* The if statement lets the compiler compile it to a conditional store.
   * Avoids dirtying a cache line.
   */

libuv/src/win/handle-inl.h  view on Meta::CPAN


      case UV_UDP:
        uv_udp_endgame(loop, (uv_udp_t*) handle);
        break;

      case UV_POLL:
        uv_poll_endgame(loop, (uv_poll_t*) handle);
        break;

      case UV_TIMER:
        uv__timer_close((uv_timer_t*) handle);
        uv__handle_close(handle);
        break;

      case UV_PREPARE:
      case UV_CHECK:
      case UV_IDLE:
        uv_loop_watcher_endgame(loop, handle);
        break;

      case UV_ASYNC:

libuv/src/win/handle.c  view on Meta::CPAN


    case UV_UDP:
      uv_udp_close(loop, (uv_udp_t*) handle);
      return;

    case UV_POLL:
      uv_poll_close(loop, (uv_poll_t*) handle);
      return;

    case UV_TIMER:
      uv_timer_stop((uv_timer_t*)handle);
      uv__handle_closing(handle);
      uv_want_endgame(loop, handle);
      return;

    case UV_PREPARE:
      uv_prepare_stop((uv_prepare_t*)handle);
      uv__handle_closing(handle);
      uv_want_endgame(loop, handle);
      return;

libuv/src/win/pipe.c  view on Meta::CPAN

STATIC_ASSERT(sizeof(uv__ipc_frame_header_t) == 16);
STATIC_ASSERT(sizeof(uv__ipc_socket_xfer_info_t) == 632);

/* Coalesced write request. */
typedef struct {
  uv_write_t req;       /* Internal heap-allocated write request. */
  uv_write_t* user_req; /* Pointer to user-specified uv_write_t. */
} uv__coalesced_write_t;


static void eof_timer_init(uv_pipe_t* pipe);
static void eof_timer_start(uv_pipe_t* pipe);
static void eof_timer_stop(uv_pipe_t* pipe);
static void eof_timer_cb(uv_timer_t* timer);
static void eof_timer_destroy(uv_pipe_t* pipe);
static void eof_timer_close_cb(uv_handle_t* handle);


static void uv_unique_pipe_name(char* ptr, char* name, size_t size) {
  snprintf(name, size, "\\\\?\\pipe\\uv\\%p-%lu", ptr, GetCurrentProcessId());
}


int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) {
  uv_stream_init(loop, (uv_stream_t*)handle, UV_NAMED_PIPE);

libuv/src/win/pipe.c  view on Meta::CPAN

  handle->ipc = ipc;
  handle->pipe.conn.non_overlapped_writes_tail = NULL;

  return 0;
}


static void uv_pipe_connection_init(uv_pipe_t* handle) {
  uv_connection_init((uv_stream_t*) handle);
  handle->read_req.data = handle;
  handle->pipe.conn.eof_timer = NULL;
  assert(!(handle->flags & UV_HANDLE_PIPESERVER));
  if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) {
    handle->pipe.conn.readfile_thread_handle = NULL;
    InitializeCriticalSection(&handle->pipe.conn.readfile_thread_lock);
  }
}


static HANDLE open_named_pipe(const WCHAR* name, DWORD* duplex_flags) {
  HANDLE pipeHandle;

libuv/src/win/pipe.c  view on Meta::CPAN

      if (pipeHandle != INVALID_HANDLE_VALUE) {
        CloseHandle(pipeHandle);
        handle->pipe.serv.accept_reqs[i].pipeHandle = INVALID_HANDLE_VALUE;
      }
    }
    handle->handle = INVALID_HANDLE_VALUE;
  }

  if (handle->flags & UV_HANDLE_CONNECTION) {
    handle->flags &= ~UV_HANDLE_WRITABLE;
    eof_timer_destroy(handle);
  }

  if ((handle->flags & UV_HANDLE_CONNECTION)
      && handle->handle != INVALID_HANDLE_VALUE)
    close_pipe(handle);
}


void uv_pipe_close(uv_loop_t* loop, uv_pipe_t* handle) {
  if (handle->flags & UV_HANDLE_READING) {

libuv/src/win/pipe.c  view on Meta::CPAN

        if (!RegisterWaitForSingleObject(&req->wait_handle,
            req->u.io.overlapped.hEvent, post_completion_read_wait, (void*) req,
            INFINITE, WT_EXECUTEINWAITTHREAD)) {
          SET_REQ_ERROR(req, GetLastError());
          goto error;
        }
      }
    }
  }

  /* Start the eof timer if there is one */
  eof_timer_start(handle);
  handle->flags |= UV_HANDLE_READ_PENDING;
  handle->reqs_pending++;
  return;

error:
  uv_insert_pending_req(loop, (uv_req_t*)req);
  handle->flags |= UV_HANDLE_READ_PENDING;
  handle->reqs_pending++;
}

libuv/src/win/pipe.c  view on Meta::CPAN

  } else {
    /* Non-IPC pipe write: put data on the wire directly. */
    assert(send_handle == NULL);
    return uv__pipe_write_data(loop, req, handle, bufs, nbufs, cb, 0);
  }
}


static void uv_pipe_read_eof(uv_loop_t* loop, uv_pipe_t* handle,
    uv_buf_t buf) {
  /* If there is an eof timer running, we don't need it any more, so discard
   * it. */
  eof_timer_destroy(handle);

  handle->flags &= ~UV_HANDLE_READABLE;
  uv_read_stop((uv_stream_t*) handle);

  handle->read_cb((uv_stream_t*) handle, UV_EOF, &buf);
}


static void uv_pipe_read_error(uv_loop_t* loop, uv_pipe_t* handle, int error,
    uv_buf_t buf) {
  /* If there is an eof timer running, we don't need it any more, so discard
   * it. */
  eof_timer_destroy(handle);

  uv_read_stop((uv_stream_t*) handle);

  handle->read_cb((uv_stream_t*)handle, uv_translate_sys_error(error), &buf);
}


static void uv_pipe_read_error_or_eof(uv_loop_t* loop, uv_pipe_t* handle,
    int error, uv_buf_t buf) {
  if (error == ERROR_BROKEN_PIPE) {

libuv/src/win/pipe.c  view on Meta::CPAN

}


void uv_process_pipe_read_req(uv_loop_t* loop,
                              uv_pipe_t* handle,
                              uv_req_t* req) {
  assert(handle->type == UV_NAMED_PIPE);

  handle->flags &= ~(UV_HANDLE_READ_PENDING | UV_HANDLE_CANCELLATION_PENDING);
  DECREASE_PENDING_REQ_COUNT(handle);
  eof_timer_stop(handle);

  /* At this point, we're done with bookkeeping. If the user has stopped
   * reading the pipe in the meantime, there is nothing left to do, since there
   * is no callback that we can call. */
  if (!(handle->flags & UV_HANDLE_READING))
    return;

  if (!REQ_SUCCESS(req)) {
    /* An error occurred doing the zero-read. */
    DWORD err = GET_REQ_ERROR(req);

libuv/src/win/pipe.c  view on Meta::CPAN

}


void uv_process_pipe_shutdown_req(uv_loop_t* loop, uv_pipe_t* handle,
    uv_shutdown_t* req) {
  assert(handle->type == UV_NAMED_PIPE);

  UNREGISTER_HANDLE_REQ(loop, handle, req);

  if (handle->flags & UV_HANDLE_READABLE) {
    /* Initialize and optionally start the eof timer. Only do this if the pipe
     * is readable and we haven't seen EOF come in ourselves. */
    eof_timer_init(handle);

    /* If reading start the timer right now. Otherwise uv_pipe_queue_read will
     * start it. */
    if (handle->flags & UV_HANDLE_READ_PENDING) {
      eof_timer_start(handle);
    }

  } else {
    /* This pipe is not readable. We can just close it to let the other end
     * know that we're done writing. */
    close_pipe(handle);
  }

  if (req->cb) {
    req->cb(req, 0);
  }

  DECREASE_PENDING_REQ_COUNT(handle);
}


static void eof_timer_init(uv_pipe_t* pipe) {
  int r;

  assert(pipe->pipe.conn.eof_timer == NULL);
  assert(pipe->flags & UV_HANDLE_CONNECTION);

  pipe->pipe.conn.eof_timer = (uv_timer_t*) uv__malloc(sizeof *pipe->pipe.conn.eof_timer);

  r = uv_timer_init(pipe->loop, pipe->pipe.conn.eof_timer);
  assert(r == 0); /* timers can't fail */
  pipe->pipe.conn.eof_timer->data = pipe;
  uv_unref((uv_handle_t*) pipe->pipe.conn.eof_timer);
}


static void eof_timer_start(uv_pipe_t* pipe) {
  assert(pipe->flags & UV_HANDLE_CONNECTION);

  if (pipe->pipe.conn.eof_timer != NULL) {
    uv_timer_start(pipe->pipe.conn.eof_timer, eof_timer_cb, eof_timeout, 0);
  }
}


static void eof_timer_stop(uv_pipe_t* pipe) {
  assert(pipe->flags & UV_HANDLE_CONNECTION);

  if (pipe->pipe.conn.eof_timer != NULL) {
    uv_timer_stop(pipe->pipe.conn.eof_timer);
  }
}


static void eof_timer_cb(uv_timer_t* timer) {
  uv_pipe_t* pipe = (uv_pipe_t*) timer->data;
  uv_loop_t* loop = timer->loop;

  assert(pipe->type == UV_NAMED_PIPE);

  /* This should always be true, since we start the timer only in
   * uv_pipe_queue_read after successfully calling ReadFile, or in
   * uv_process_pipe_shutdown_req if a read is pending, and we always
   * immediately stop the timer in uv_process_pipe_read_req. */
  assert(pipe->flags & UV_HANDLE_READ_PENDING);

  /* If there are many packets coming off the iocp then the timer callback may
   * be called before the read request is coming off the queue. Therefore we
   * check here if the read request has completed but will be processed later.
   */
  if ((pipe->flags & UV_HANDLE_READ_PENDING) &&
      HasOverlappedIoCompleted(&pipe->read_req.u.io.overlapped)) {
    return;
  }

  /* Force both ends off the pipe. */
  close_pipe(pipe);

libuv/src/win/pipe.c  view on Meta::CPAN

  /* Stop reading, so the pending read that is going to fail will not be
   * reported to the user. */
  uv_read_stop((uv_stream_t*) pipe);

  /* Report the eof and update flags. This will get reported even if the user
   * stopped reading in the meantime. TODO: is that okay? */
  uv_pipe_read_eof(loop, pipe, uv_null_buf_);
}


static void eof_timer_destroy(uv_pipe_t* pipe) {
  assert(pipe->flags & UV_HANDLE_CONNECTION);

  if (pipe->pipe.conn.eof_timer) {
    uv_close((uv_handle_t*) pipe->pipe.conn.eof_timer, eof_timer_close_cb);
    pipe->pipe.conn.eof_timer = NULL;
  }
}


static void eof_timer_close_cb(uv_handle_t* handle) {
  assert(handle->type == UV_TIMER);
  uv__free(handle);
}


int uv_pipe_open(uv_pipe_t* pipe, uv_file file) {
  HANDLE os_handle = uv__get_osfhandle(file);
  NTSTATUS nt_status;
  IO_STATUS_BLOCK io_status;
  FILE_ACCESS_INFORMATION access;

libuv/src/win/util.c  view on Meta::CPAN


/*
 * One-time initialization code for functionality defined in util.c.
 */
void uv__util_init(void) {
  LARGE_INTEGER perf_frequency;

  /* Initialize process title access mutex. */
  InitializeCriticalSection(&process_title_lock);

  /* Retrieve high-resolution timer frequency
   * and precompute its reciprocal.
   */
  if (QueryPerformanceFrequency(&perf_frequency)) {
    hrtime_interval_ = 1.0 / perf_frequency.QuadPart;
  } else {
    hrtime_interval_= 0;
  }
}




( run in 0.920 second using v1.01-cache-2.11-cpan-49f99fa48dc )