#include "uv.h"
#include "task.h"
#include <string.h> /* memset */
#ifndef _WIN32
#include <unistd.h> /* close */
#endif
struct
thread_ctx {
uv_barrier_t barrier;
uv_file fd;
};
static
void
thread_main(
void
* arg) {
struct
thread_ctx* ctx;
uv_fs_t req;
uv_buf_t bufs[1];
char
buf[4096];
ssize_t n;
int
uv_errno;
bufs[0] = uv_buf_init(buf,
sizeof
(buf));
ctx = arg;
uv_barrier_wait(&ctx->barrier);
uv_sleep(100);
do
{
uv_errno = uv_fs_read(NULL, &req, ctx->fd, bufs, 1, -1, NULL);
n = req.result;
uv_fs_req_cleanup(&req);
}
while
(n > 0 || (n == -1 && uv_errno == UV_EINTR));
ASSERT_OK(n);
}
#ifdef _WIN32
static
void
write_cb(uv_write_t* req,
int
status) {
ASSERT_OK(status);
req->handle = NULL;
}
#endif
#ifdef _WIN32
#define NWRITES (10 << 16)
#else
#define NWRITES (10 << 20)
#endif
TEST_IMPL(pipe_set_non_blocking) {
struct
thread_ctx ctx;
uv_pipe_t pipe_handle;
uv_thread_t
thread
;
size_t
nwritten;
char
data[4096];
uv_buf_t buf;
uv_file fd[2];
int
n;
#ifdef _WIN32
uv_write_t write_req;
#endif
ASSERT_OK(uv_pipe_init(uv_default_loop(), &pipe_handle, 0));
ASSERT_OK(uv_pipe(fd, 0, 0));
ASSERT_OK(uv_pipe_open(&pipe_handle, fd[1]));
ASSERT_OK(uv_stream_set_blocking((uv_stream_t*) &pipe_handle, 1));
fd[1] = -1;
ctx.fd = fd[0];
ASSERT_OK(uv_barrier_init(&ctx.barrier, 2));
ASSERT_OK(uv_thread_create(&
thread
, thread_main, &ctx));
uv_barrier_wait(&ctx.barrier);
buf.len =
sizeof
(data);
buf.base = data;
memset
(data,
'.'
,
sizeof
(data));
nwritten = 0;
while
(nwritten < NWRITES) {
n = uv_try_write((uv_stream_t*) &pipe_handle, &buf, 1);
#ifdef _WIN32
ASSERT_EQ(n, UV_EAGAIN);
ASSERT_OK(uv_write(&write_req,
(uv_stream_t*) &pipe_handle,
&buf,
1,
write_cb));
ASSERT_NOT_NULL(write_req.handle);
ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_ONCE));
ASSERT_NULL(write_req.handle);
n = buf.len;
#endif
ASSERT_EQ(n,
sizeof
(data));
nwritten += n;
}
uv_close((uv_handle_t*) &pipe_handle, NULL);
ASSERT_OK(uv_run(uv_default_loop(), UV_RUN_DEFAULT));
ASSERT_OK(uv_thread_join(&
thread
));
#ifdef _WIN32
ASSERT_OK(_close(fd[0]));
#else
ASSERT_OK(close(fd[0]));
#endif
fd[0] = -1;
uv_barrier_destroy(&ctx.barrier);
MAKE_VALGRIND_HAPPY(uv_default_loop());
return
0;
}