uv_read_start() bug?
Last active
February 28, 2020 21:55
-
-
Save mpenick/d0978d80c2ce99a46002857ac78ead63 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
build |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
cmake_minimum_required(VERSION 3.5) | |
project(read_start_bug) | |
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}") | |
include(FindLibuv) | |
list(APPEND LIBRARIES ${LIBUV_LIBRARIES}) | |
list(APPEND INCLUDE_DIRS ${LIBUV_INCLUDE_DIRS}) | |
add_executable(read_start_bug read_start_bug.c) | |
target_include_directories(read_start_bug PRIVATE ${INCLUDE_DIRS}) | |
target_link_libraries(read_start_bug ${LIBRARIES}) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
find_package(PkgConfig) | |
if (PKG_CONFIG_FOUND) | |
pkg_check_modules(PC_LIBUV QUIET libuv) | |
endif() | |
set(LIBUV_HINTS ${LIBUV_ROOT_DIR} ENV LIBUV_ROOT_DIR) | |
find_path(LIBUV_INCLUDE_DIR NAMES uv.h | |
HINTS ${LIBUV_HINTS} | |
PATH_SUFFIXES include) | |
find_library(LIBUV_LIBRARY NAMES uv libuv | |
HINTS ${LIBUV_HINTS} | |
PATH_SUFFIXES lib) | |
mark_as_advanced(LIBUV_INCLUDE_DIR LIBUV_LIBRARY) | |
set(LIBUV_LIBRARIES ${LIBUV_LIBRARY}) | |
set(LIBUV_INCLUDE_DIRS ${LIBUV_INCLUDE_DIR}) | |
include(FindPackageHandleStandardArgs) | |
find_package_handle_standard_args(Libuv DEFAULT_MSG | |
LIBUV_LIBRARY LIBUV_INCLUDE_DIR) | |
mark_as_advanced(LIBUV_INCLUDE_DIR LIBUV_LIBRARY) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdlib.h> | |
#include <uv.h> | |
#define ASSERT(x) \ | |
do { \ | |
if (!(x)) { \ | |
fprintf(stderr, "'" #x "' failed on line %d\n", __LINE__); \ | |
abort(); \ | |
} \ | |
} while (0); | |
static uv_tcp_t server; | |
static uv_tcp_t connection; | |
static uv_tcp_t client; | |
static uv_connect_t connect_req; | |
static void on_write_close_immediately(uv_write_t *req, int status) { | |
ASSERT(0 == status); | |
uv_close((uv_handle_t*)req->handle, NULL); /* Close immediately */ | |
free(req); | |
} | |
static void on_write(uv_write_t* req, int status) { | |
ASSERT(0 == status); | |
free(req); | |
} | |
static void do_write(uv_stream_t *stream, uv_write_cb cb) { | |
uv_write_t *req = (uv_write_t *)malloc(sizeof(uv_write_t)); | |
uv_buf_t buf; | |
buf.base = "1234578"; | |
buf.len = 8; | |
ASSERT(0 == uv_write(req, stream, &buf, 1, cb)); | |
} | |
static void on_alloc(uv_handle_t *handle, size_t suggested_size, | |
uv_buf_t *buf) { | |
static char slab[65536]; | |
buf->base = slab; | |
buf->len = sizeof(slab); | |
} | |
static void on_read2(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf); | |
static void on_read1(uv_stream_t *stream, ssize_t nread, const uv_buf_t *buf) { | |
ASSERT(nread >= 0); | |
do_write(stream, on_write); | |
ASSERT(0 == uv_read_stop(stream)); | |
ASSERT(0 == uv_read_start(stream, on_alloc, on_read2)); | |
} | |
static void on_read2(uv_stream_t* stream, ssize_t nread, const uv_buf_t* buf) { | |
uv_close((uv_handle_t*)stream, NULL); | |
uv_close((uv_handle_t*)&server, NULL); | |
} | |
static void on_connection(uv_stream_t *server, int status) { | |
ASSERT(0 == status); | |
ASSERT(0 == uv_tcp_init(server->loop, &connection)); | |
ASSERT(0 == uv_accept(server, (uv_stream_t *)&connection)); | |
ASSERT(0 == uv_read_start((uv_stream_t *)&connection, on_alloc, on_read1)); | |
} | |
static void on_connect(uv_connect_t *req, int status) { | |
ASSERT(0 == status); | |
do_write((uv_stream_t*)&client, on_write_close_immediately); | |
} | |
int main() { | |
uv_loop_t loop; | |
ASSERT(0 == uv_loop_init(&loop)); | |
{ /* Server */ | |
struct sockaddr_in addr; | |
ASSERT(0 == uv_ip4_addr("0.0.0.0", 8080, &addr)); | |
ASSERT(0 == uv_tcp_init(&loop, &server)); | |
ASSERT(0 == uv_tcp_bind(&server, (struct sockaddr*) & addr, 0)); | |
ASSERT(0 == uv_listen((uv_stream_t*)&server, 10, on_connection)); | |
} | |
{ /* Client */ | |
struct sockaddr_in addr; | |
ASSERT(0 == uv_ip4_addr("0.0.0.0", 8080, &addr)); | |
ASSERT(0 == uv_tcp_init(&loop, &client)); | |
ASSERT(0 == uv_tcp_connect(&connect_req, &client, | |
(const struct sockaddr*) & addr, on_connect)); | |
} | |
uv_run(&loop, UV_RUN_DEFAULT); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment