summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/libuv/test/test-poll.c
diff options
context:
space:
mode:
author Miodrag Milanovic <mmicko@gmail.com>2016-10-07 14:14:08 +0200
committer Miodrag Milanovic <mmicko@gmail.com>2016-10-07 14:14:08 +0200
commit85f4741fcf642f52ac4fa56f0aff1728727c901b (patch)
treeda8cca02913839152d2eb04c0e85a83018bcaed3 /3rdparty/libuv/test/test-poll.c
parentff01b716711b97c2fcaa709ea97f7650f106aa10 (diff)
Remove libuv library (nw)
Diffstat (limited to '3rdparty/libuv/test/test-poll.c')
-rw-r--r--3rdparty/libuv/test/test-poll.c598
1 files changed, 0 insertions, 598 deletions
diff --git a/3rdparty/libuv/test/test-poll.c b/3rdparty/libuv/test/test-poll.c
deleted file mode 100644
index bfb75af1335..00000000000
--- a/3rdparty/libuv/test/test-poll.c
+++ /dev/null
@@ -1,598 +0,0 @@
-/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#include <errno.h>
-
-#ifdef _WIN32
-# include <fcntl.h>
-#else
-# include <sys/socket.h>
-# include <unistd.h>
-#endif
-
-#include "uv.h"
-#include "task.h"
-
-
-#define NUM_CLIENTS 5
-#define TRANSFER_BYTES (1 << 16)
-
-#undef MIN
-#define MIN(a, b) (((a) < (b)) ? (a) : (b));
-
-
-typedef enum {
- UNIDIRECTIONAL,
- DUPLEX
-} test_mode_t;
-
-typedef struct connection_context_s {
- uv_poll_t poll_handle;
- uv_timer_t timer_handle;
- uv_os_sock_t sock;
- size_t read, sent;
- int is_server_connection;
- int open_handles;
- int got_fin, sent_fin, got_disconnect;
- unsigned int events, delayed_events;
-} connection_context_t;
-
-typedef struct server_context_s {
- uv_poll_t poll_handle;
- uv_os_sock_t sock;
- int connections;
-} server_context_t;
-
-
-static void delay_timer_cb(uv_timer_t* timer);
-
-
-static test_mode_t test_mode = DUPLEX;
-
-static int closed_connections = 0;
-
-static int valid_writable_wakeups = 0;
-static int spurious_writable_wakeups = 0;
-
-static int disconnects = 0;
-
-
-static int got_eagain(void) {
-#ifdef _WIN32
- return WSAGetLastError() == WSAEWOULDBLOCK;
-#else
- return errno == EAGAIN
- || errno == EINPROGRESS
-#ifdef EWOULDBLOCK
- || errno == EWOULDBLOCK;
-#endif
- ;
-#endif
-}
-
-
-static uv_os_sock_t create_bound_socket (struct sockaddr_in bind_addr) {
- uv_os_sock_t sock;
- int r;
-
- sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
-#ifdef _WIN32
- ASSERT(sock != INVALID_SOCKET);
-#else
- ASSERT(sock >= 0);
-#endif
-
-#ifndef _WIN32
- {
- /* Allow reuse of the port. */
- int yes = 1;
- r = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof yes);
- ASSERT(r == 0);
- }
-#endif
-
- r = bind(sock, (const struct sockaddr*) &bind_addr, sizeof bind_addr);
- ASSERT(r == 0);
-
- return sock;
-}
-
-
-static void close_socket(uv_os_sock_t sock) {
- int r;
-#ifdef _WIN32
- r = closesocket(sock);
-#else
- r = close(sock);
-#endif
- ASSERT(r == 0);
-}
-
-
-static connection_context_t* create_connection_context(
- uv_os_sock_t sock, int is_server_connection) {
- int r;
- connection_context_t* context;
-
- context = (connection_context_t*) malloc(sizeof *context);
- ASSERT(context != NULL);
-
- context->sock = sock;
- context->is_server_connection = is_server_connection;
- context->read = 0;
- context->sent = 0;
- context->open_handles = 0;
- context->events = 0;
- context->delayed_events = 0;
- context->got_fin = 0;
- context->sent_fin = 0;
- context->got_disconnect = 0;
-
- r = uv_poll_init_socket(uv_default_loop(), &context->poll_handle, sock);
- context->open_handles++;
- context->poll_handle.data = context;
- ASSERT(r == 0);
-
- r = uv_timer_init(uv_default_loop(), &context->timer_handle);
- context->open_handles++;
- context->timer_handle.data = context;
- ASSERT(r == 0);
-
- return context;
-}
-
-
-static void connection_close_cb(uv_handle_t* handle) {
- connection_context_t* context = (connection_context_t*) handle->data;
-
- if (--context->open_handles == 0) {
- if (test_mode == DUPLEX || context->is_server_connection) {
- ASSERT(context->read == TRANSFER_BYTES);
- } else {
- ASSERT(context->read == 0);
- }
-
- if (test_mode == DUPLEX || !context->is_server_connection) {
- ASSERT(context->sent == TRANSFER_BYTES);
- } else {
- ASSERT(context->sent == 0);
- }
-
- closed_connections++;
-
- free(context);
- }
-}
-
-
-static void destroy_connection_context(connection_context_t* context) {
- uv_close((uv_handle_t*) &context->poll_handle, connection_close_cb);
- uv_close((uv_handle_t*) &context->timer_handle, connection_close_cb);
-}
-
-
-static void connection_poll_cb(uv_poll_t* handle, int status, int events) {
- connection_context_t* context = (connection_context_t*) handle->data;
- unsigned int new_events;
- int r;
-
- ASSERT(status == 0);
- ASSERT(events & context->events);
- ASSERT(!(events & ~context->events));
-
- new_events = context->events;
-
- if (events & UV_READABLE) {
- int action = rand() % 7;
-
- switch (action) {
- case 0:
- case 1: {
- /* Read a couple of bytes. */
- static char buffer[74];
- r = recv(context->sock, buffer, sizeof buffer, 0);
- ASSERT(r >= 0);
-
- if (r > 0) {
- context->read += r;
- } else {
- /* Got FIN. */
- context->got_fin = 1;
- new_events &= ~UV_READABLE;
- }
-
- break;
- }
-
- case 2:
- case 3: {
- /* Read until EAGAIN. */
- static char buffer[931];
- r = recv(context->sock, buffer, sizeof buffer, 0);
- ASSERT(r >= 0);
-
- while (r > 0) {
- context->read += r;
- r = recv(context->sock, buffer, sizeof buffer, 0);
- }
-
- if (r == 0) {
- /* Got FIN. */
- context->got_fin = 1;
- new_events &= ~UV_READABLE;
- } else {
- ASSERT(got_eagain());
- }
-
- break;
- }
-
- case 4:
- /* Ignore. */
- break;
-
- case 5:
- /* Stop reading for a while. Restart in timer callback. */
- new_events &= ~UV_READABLE;
- if (!uv_is_active((uv_handle_t*) &context->timer_handle)) {
- context->delayed_events = UV_READABLE;
- uv_timer_start(&context->timer_handle, delay_timer_cb, 10, 0);
- } else {
- context->delayed_events |= UV_READABLE;
- }
- break;
-
- case 6:
- /* Fudge with the event mask. */
- uv_poll_start(&context->poll_handle, UV_WRITABLE, connection_poll_cb);
- uv_poll_start(&context->poll_handle, UV_READABLE, connection_poll_cb);
- context->events = UV_READABLE;
- break;
-
- default:
- ASSERT(0);
- }
- }
-
- if (events & UV_WRITABLE) {
- if (context->sent < TRANSFER_BYTES &&
- !(test_mode == UNIDIRECTIONAL && context->is_server_connection)) {
- /* We have to send more bytes. */
- int action = rand() % 7;
-
- switch (action) {
- case 0:
- case 1: {
- /* Send a couple of bytes. */
- static char buffer[103];
-
- int send_bytes = MIN(TRANSFER_BYTES - context->sent, sizeof buffer);
- ASSERT(send_bytes > 0);
-
- r = send(context->sock, buffer, send_bytes, 0);
-
- if (r < 0) {
- ASSERT(got_eagain());
- spurious_writable_wakeups++;
- break;
- }
-
- ASSERT(r > 0);
- context->sent += r;
- valid_writable_wakeups++;
- break;
- }
-
- case 2:
- case 3: {
- /* Send until EAGAIN. */
- static char buffer[1234];
-
- int send_bytes = MIN(TRANSFER_BYTES - context->sent, sizeof buffer);
- ASSERT(send_bytes > 0);
-
- r = send(context->sock, buffer, send_bytes, 0);
-
- if (r < 0) {
- ASSERT(got_eagain());
- spurious_writable_wakeups++;
- break;
- }
-
- ASSERT(r > 0);
- valid_writable_wakeups++;
- context->sent += r;
-
- while (context->sent < TRANSFER_BYTES) {
- send_bytes = MIN(TRANSFER_BYTES - context->sent, sizeof buffer);
- ASSERT(send_bytes > 0);
-
- r = send(context->sock, buffer, send_bytes, 0);
-
- if (r <= 0) break;
- context->sent += r;
- }
- ASSERT(r > 0 || got_eagain());
- break;
- }
-
- case 4:
- /* Ignore. */
- break;
-
- case 5:
- /* Stop sending for a while. Restart in timer callback. */
- new_events &= ~UV_WRITABLE;
- if (!uv_is_active((uv_handle_t*) &context->timer_handle)) {
- context->delayed_events = UV_WRITABLE;
- uv_timer_start(&context->timer_handle, delay_timer_cb, 100, 0);
- } else {
- context->delayed_events |= UV_WRITABLE;
- }
- break;
-
- case 6:
- /* Fudge with the event mask. */
- uv_poll_start(&context->poll_handle,
- UV_READABLE,
- connection_poll_cb);
- uv_poll_start(&context->poll_handle,
- UV_WRITABLE,
- connection_poll_cb);
- context->events = UV_WRITABLE;
- break;
-
- default:
- ASSERT(0);
- }
-
- } else {
- /* Nothing more to write. Send FIN. */
- int r;
-#ifdef _WIN32
- r = shutdown(context->sock, SD_SEND);
-#else
- r = shutdown(context->sock, SHUT_WR);
-#endif
- ASSERT(r == 0);
- context->sent_fin = 1;
- new_events &= ~UV_WRITABLE;
- }
- }
-
- if (events & UV_DISCONNECT) {
- context->got_disconnect = 1;
- ++disconnects;
- new_events &= ~UV_DISCONNECT;
- }
-
- if (context->got_fin && context->sent_fin && context->got_disconnect) {
- /* Sent and received FIN. Close and destroy context. */
- close_socket(context->sock);
- destroy_connection_context(context);
- context->events = 0;
-
- } else if (new_events != context->events) {
- /* Poll mask changed. Call uv_poll_start again. */
- context->events = new_events;
- uv_poll_start(handle, new_events, connection_poll_cb);
- }
-
- /* Assert that uv_is_active works correctly for poll handles. */
- if (context->events != 0) {
- ASSERT(1 == uv_is_active((uv_handle_t*) handle));
- } else {
- ASSERT(0 == uv_is_active((uv_handle_t*) handle));
- }
-}
-
-
-static void delay_timer_cb(uv_timer_t* timer) {
- connection_context_t* context = (connection_context_t*) timer->data;
- int r;
-
- /* Timer should auto stop. */
- ASSERT(0 == uv_is_active((uv_handle_t*) timer));
-
- /* Add the requested events to the poll mask. */
- ASSERT(context->delayed_events != 0);
- context->events |= context->delayed_events;
- context->delayed_events = 0;
-
- r = uv_poll_start(&context->poll_handle,
- context->events,
- connection_poll_cb);
- ASSERT(r == 0);
-}
-
-
-static server_context_t* create_server_context(
- uv_os_sock_t sock) {
- int r;
- server_context_t* context;
-
- context = (server_context_t*) malloc(sizeof *context);
- ASSERT(context != NULL);
-
- context->sock = sock;
- context->connections = 0;
-
- r = uv_poll_init_socket(uv_default_loop(), &context->poll_handle, sock);
- context->poll_handle.data = context;
- ASSERT(r == 0);
-
- return context;
-}
-
-
-static void server_close_cb(uv_handle_t* handle) {
- server_context_t* context = (server_context_t*) handle->data;
- free(context);
-}
-
-
-static void destroy_server_context(server_context_t* context) {
- uv_close((uv_handle_t*) &context->poll_handle, server_close_cb);
-}
-
-
-static void server_poll_cb(uv_poll_t* handle, int status, int events) {
- server_context_t* server_context = (server_context_t*)
- handle->data;
- connection_context_t* connection_context;
- struct sockaddr_in addr;
- socklen_t addr_len;
- uv_os_sock_t sock;
- int r;
-
- addr_len = sizeof addr;
- sock = accept(server_context->sock, (struct sockaddr*) &addr, &addr_len);
-#ifdef _WIN32
- ASSERT(sock != INVALID_SOCKET);
-#else
- ASSERT(sock >= 0);
-#endif
-
- connection_context = create_connection_context(sock, 1);
- connection_context->events = UV_READABLE | UV_WRITABLE | UV_DISCONNECT;
- r = uv_poll_start(&connection_context->poll_handle,
- UV_READABLE | UV_WRITABLE | UV_DISCONNECT,
- connection_poll_cb);
- ASSERT(r == 0);
-
- if (++server_context->connections == NUM_CLIENTS) {
- close_socket(server_context->sock);
- destroy_server_context(server_context);
- }
-}
-
-
-static void start_server(void) {
- server_context_t* context;
- struct sockaddr_in addr;
- uv_os_sock_t sock;
- int r;
-
- ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
- sock = create_bound_socket(addr);
- context = create_server_context(sock);
-
- r = listen(sock, 100);
- ASSERT(r == 0);
-
- r = uv_poll_start(&context->poll_handle, UV_READABLE, server_poll_cb);
- ASSERT(r == 0);
-}
-
-
-static void start_client(void) {
- uv_os_sock_t sock;
- connection_context_t* context;
- struct sockaddr_in server_addr;
- struct sockaddr_in addr;
- int r;
-
- ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &server_addr));
- ASSERT(0 == uv_ip4_addr("0.0.0.0", 0, &addr));
-
- sock = create_bound_socket(addr);
- context = create_connection_context(sock, 0);
-
- context->events = UV_READABLE | UV_WRITABLE | UV_DISCONNECT;
- r = uv_poll_start(&context->poll_handle,
- UV_READABLE | UV_WRITABLE | UV_DISCONNECT,
- connection_poll_cb);
- ASSERT(r == 0);
-
- r = connect(sock, (struct sockaddr*) &server_addr, sizeof server_addr);
- ASSERT(r == 0 || got_eagain());
-}
-
-
-static void start_poll_test(void) {
- int i, r;
-
-#ifdef _WIN32
- {
- struct WSAData wsa_data;
- int r = WSAStartup(MAKEWORD(2, 2), &wsa_data);
- ASSERT(r == 0);
- }
-#endif
-
- start_server();
-
- for (i = 0; i < NUM_CLIENTS; i++)
- start_client();
-
- r = uv_run(uv_default_loop(), UV_RUN_DEFAULT);
- ASSERT(r == 0);
-
- /* Assert that at most five percent of the writable wakeups was spurious. */
- ASSERT(spurious_writable_wakeups == 0 ||
- (valid_writable_wakeups + spurious_writable_wakeups) /
- spurious_writable_wakeups > 20);
-
- ASSERT(closed_connections == NUM_CLIENTS * 2);
- ASSERT(disconnects == NUM_CLIENTS * 2);
-
- MAKE_VALGRIND_HAPPY();
-}
-
-
-TEST_IMPL(poll_duplex) {
- test_mode = DUPLEX;
- start_poll_test();
- return 0;
-}
-
-
-TEST_IMPL(poll_unidirectional) {
- test_mode = UNIDIRECTIONAL;
- start_poll_test();
- return 0;
-}
-
-
-/* Windows won't let you open a directory so we open a file instead.
- * OS X lets you poll a file so open the $PWD instead. Both fail
- * on Linux so it doesn't matter which one we pick. Both succeed
- * on FreeBSD, Solaris and AIX so skip the test on those platforms.
- */
-TEST_IMPL(poll_bad_fdtype) {
-#if !defined(__DragonFly__) && !defined(__FreeBSD__) && !defined(__sun) && \
- !defined(_AIX)
- uv_poll_t poll_handle;
- int fd;
-
-#if defined(_WIN32)
- fd = open("test/fixtures/empty_file", O_RDONLY);
-#else
- fd = open(".", O_RDONLY);
-#endif
- ASSERT(fd != -1);
- ASSERT(0 != uv_poll_init(uv_default_loop(), &poll_handle, fd));
- ASSERT(0 == close(fd));
-#endif
-
- MAKE_VALGRIND_HAPPY();
- return 0;
-}