Skip to content

Commit

Permalink
Added 'pipe' feature for unix systems. (Samsung#120)
Browse files Browse the repository at this point in the history
It is disabled by default. 'TUV_FEATURE_PIPE' cmake define must be set to enable.

libtuv-DCO-1.0-Signed-off-by: László Langó llango.u-szeged@partner.samsung.com
  • Loading branch information
LaszloLango authored and yichoi committed Jul 25, 2018
1 parent e60b6d7 commit 9f32c3d
Show file tree
Hide file tree
Showing 21 changed files with 1,316 additions and 17 deletions.
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ CMAKE_DEFINES := \
-DBUILDTESTER=${TUV_BUILDTESTER} \
-DBUILD_HOST_HELPER=${TUV_BUILDHOSTHELPER} \
-DCREATE_SHARED_LIB=${TUV_CREATE_SHARED_LIB} \
-DTUV_FEATURE_SIGNAL=ON
-DTUV_FEATURE_SIGNAL=ON \
-DTUV_FEATURE_PIPE=ON

ifneq ($(TUV_BOARD),unknown)
CMAKE_DEFINES += -DTARGET_BOARD=${TUV_BOARD}
Expand Down
39 changes: 30 additions & 9 deletions cmake/option/option_unix_common.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ set(PLATFORM_SRCFILES
${UNIX_PATH}/internal.h
${UNIX_PATH}/loop.c
${UNIX_PATH}/loop-watcher.c
# ${UNIX_PATH}/pipe.c
${UNIX_PATH}/poll.c
${UNIX_PATH}/process.c
# ${UNIX_PATH}/proctitle.c
Expand All @@ -60,12 +59,6 @@ set(PLATFORM_SRCFILES
${UNIX_PATH}/udp.c
)

if(TUV_FEATURE_SIGNAL)
set(PLATFORM_SRCFILES "${PLATFORM_SRCFILES}"
${UNIX_PATH}/signal.c)
set(FLAGS_COMMON "${FLAGS_COMMON}" "-DTUV_FEATURE_SIGNAL=1")
endif()

set(TEST_MAINFILE "${TEST_ROOT}/runner_main.c")

set(TEST_UNITFILES
Expand All @@ -84,8 +77,36 @@ set(TEST_UNITFILES
"${TEST_ROOT}/test_active.c"
"${TEST_ROOT}/test_walk_handles.c"
"${TEST_ROOT}/test_async.c"
"${TEST_ROOT}/test_signal.c"
)
)

# { TUV_CHANGES@20180724:
# Made pipe build time configurable }
if(TUV_FEATURE_PIPE)
set(PLATFORM_SRCFILES "${PLATFORM_SRCFILES}"
${UNIX_PATH}/pipe.c)
set(FLAGS_COMMON "${FLAGS_COMMON}" "-DTUV_FEATURE_PIPE=1")
set(TEST_UNITFILES "${TEST_UNITFILES}"
"${TEST_ROOT}/test_pipe_bind_error.c"
"${TEST_ROOT}/test_pipe_close_stdout_read_stdin.c"
"${TEST_ROOT}/test_pipe_connect_error.c"
"${TEST_ROOT}/test_pipe_connect_multiple.c"
"${TEST_ROOT}/test_pipe_connect_prepare.c"
"${TEST_ROOT}/test_pipe_getsockname.c"
"${TEST_ROOT}/test_pipe_pending_instances.c"
"${TEST_ROOT}/test_pipe_sendmsg.c"
"${TEST_ROOT}/test_pipe_server_close.c"
"${TEST_ROOT}/test_pipe_set_non_blocking.c"
)
endif()

# { TUV_CHANGES@20180723:
# Made signal build time configurable }
if(TUV_FEATURE_SIGNAL)
set(PLATFORM_SRCFILES "${PLATFORM_SRCFILES}"
${UNIX_PATH}/signal.c)
set(FLAGS_COMMON "${FLAGS_COMMON}" "-DTUV_FEATURE_SIGNAL=1")
set(TEST_UNITFILES "${TEST_UNITFILES}" "${TEST_ROOT}/test_signal.c")
endif()

# configuration values
set(CONFIG_FILESYSTEM 1)
6 changes: 6 additions & 0 deletions src/unix/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,12 @@ void uv_close(uv_handle_t* handle, uv_close_cb close_cb) {
handle->close_cb = close_cb;

switch (handle->type) {
#ifdef TUV_FEATURE_PIPE
case UV_NAMED_PIPE:
uv__pipe_close((uv_pipe_t*)handle);
break;
#endif

case UV_TTY:
uv__stream_close((uv_stream_t*)handle);
break;
Expand Down
17 changes: 17 additions & 0 deletions src/unix/stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,9 @@ int uv_accept(uv_stream_t* server, uv_stream_t* client) {
return -EAGAIN;

switch (client->type) {
#ifdef TUV_FEATURE_PIPE
case UV_NAMED_PIPE:
#endif
case UV_TCP:
err = uv__stream_open(client,
server->accepted_fd,
Expand Down Expand Up @@ -662,6 +664,12 @@ int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) {
err = uv_tcp_listen((uv_tcp_t*)stream, backlog, cb);
break;

#ifdef TUV_FEATURE_PIPE
case UV_NAMED_PIPE:
err = uv_pipe_listen((uv_pipe_t*)stream, backlog, cb);
break;
#endif

default:
err = -EINVAL;
}
Expand Down Expand Up @@ -1673,3 +1681,12 @@ void uv__stream_close(uv_stream_t* handle) {
assert(!uv__io_active(&handle->io_watcher, POLLIN | POLLOUT));
}


#ifdef TUV_FEATURE_PIPE
int uv_stream_set_blocking(uv_stream_t* handle, int blocking) {
/* Don't need to check the file descriptor, uv__nonblock()
* will fail with EBADF if it's not valid.
*/
return uv__nonblock(uv__stream_fd(handle), !blocking);
}
#endif
21 changes: 21 additions & 0 deletions src/unix/thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -592,3 +592,24 @@ int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex, uint64_t timeout) {
abort();
return -EINVAL; /* Satisfy the compiler. */
}


#ifdef TUV_FEATURE_PIPE
int uv_barrier_init(uv_barrier_t* barrier, unsigned int count) {
return -pthread_barrier_init(barrier, NULL, count);
}


void uv_barrier_destroy(uv_barrier_t* barrier) {
if (pthread_barrier_destroy(barrier))
abort();
}


int uv_barrier_wait(uv_barrier_t* barrier) {
int r = pthread_barrier_wait(barrier);
if (r && r != PTHREAD_BARRIER_SERIAL_THREAD)
abort();
return r == PTHREAD_BARRIER_SERIAL_THREAD;
}
#endif
7 changes: 6 additions & 1 deletion src/uv-common.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ static uv__allocator_t uv__allocator = {
free,
};

#if defined(__APPLE__) || defined(_WIN32)
#if defined(__APPLE__) || defined(_WIN32) || defined(TUV_FEATURE_PIPE)
char* uv__strdup(const char* s) {
size_t len = strlen(s) + 1;
char* m = uv__malloc(len);
Expand Down Expand Up @@ -330,6 +330,11 @@ void uv_unref(uv_handle_t* handle) {
}


void uv_stop(uv_loop_t* loop) {
loop->stop_flag = 1;
}


uint64_t uv_now(const uv_loop_t* loop) {
return loop->time;
}
Expand Down
2 changes: 1 addition & 1 deletion src/uv-common.h
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ void uv__fs_scandir_cleanup(uv_fs_t* req);

/* Allocator prototypes */
void *uv__calloc(size_t count, size_t size);
#if defined(__APPLE__)
#if defined(__APPLE__) || defined(_WIN32) || defined(TUV_FEATURE_PIPE)
char *uv__strdup(const char* s);
#endif
void* uv__malloc(size_t size);
Expand Down
8 changes: 4 additions & 4 deletions test/echo_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,14 +167,14 @@ static void on_connection(uv_stream_t* server, int status) {
TUV_ASSERT(r == 0);
break;

/*
case PIPE:
#ifdef TUV_FEATURE_PIPE
case TEST_PIPE:
stream = (uv_stream_t*)malloc(sizeof(uv_pipe_t));
TUV_ASSERT(stream != NULL);
r = uv_pipe_init(loop, (uv_pipe_t*)stream, 0);
r = uv_pipe_init(&loop, (uv_pipe_t*)stream, 0);
TUV_ASSERT(r == 0);
break;
*/
#endif

default:
TUV_ASSERT(0 && "Bad serverType");
Expand Down
10 changes: 10 additions & 0 deletions test/runner.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
extern "C" {
#endif

#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))

#if defined(__NUTTX__) || defined(__TUV_RAW__)
#define EMBED_LOW_MEMORY
Expand Down Expand Up @@ -79,6 +80,15 @@ typedef struct {
int run_helper_##name(void); \
int run_helper_##name(void)

#ifdef _WIN32
# define TEST_PIPENAME "\\\\?\\pipe\\uv-test"
# define TEST_PIPENAME_2 "\\\\?\\pipe\\uv-test2"
# define TEST_PIPENAME_3 "\\\\?\\pipe\\uv-test3"
#else
# define TEST_PIPENAME "/tmp/uv-test-sock"
# define TEST_PIPENAME_2 "/tmp/uv-test-sock2"
# define TEST_PIPENAME_3 "/tmp/uv-test-sock3"
#endif

/* Have our own assert, so we are sure it does not get optimized away in
* a release build.
Expand Down
19 changes: 19 additions & 0 deletions test/runner_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,26 @@
TE(getaddrinfo_basic, 5000) \
TE(getaddrinfo_basic_sync, 5000) \
TE(getaddrinfo_concurrent, 5000) \
\
TE(pipe_bind_error_addrinuse, 5000) \
TE(pipe_bind_error_addrnotavail, 5000) \
TE(pipe_bind_error_inval, 5000) \
TE(pipe_listen_without_bind, 5000) \
/*TE(pipe_close_stdout_read_stdin, 5000)*/ \
TE(pipe_connect_bad_name, 5000) \
/*TE(pipe_connect_to_file, 5000)*/ \
/*TE(pipe_connect_multiple, 5000)*/ \
/*TE(pipe_connect_on_prepare, 5000)*/ \
TE(pipe_getsockname, 5000) \
TE(pipe_getsockname_abstract, 5000) \
TE(pipe_getsockname_blocking, 5000) \
TE(pipe_pending_instances, 5000) \
TE(pipe_sendmsg, 5000) \
TE(pipe_server_close, 5000) \
TE(pipe_set_non_blocking, 5000) \
\
TE(we_get_signal, 5000) \
TE(we_get_signals, 5000)

#elif defined(__TUV_RAW__)
#define TEST_LIST_EXT(TE) \
Expand Down
137 changes: 137 additions & 0 deletions test/test_pipe_bind_error.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/* 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 "uv.h"
#include "runner.h"

#include <stdio.h>
#include <stdlib.h>


#ifdef _WIN32
# define BAD_PIPENAME "bad-pipe"
#else
# define BAD_PIPENAME "/path/to/unix/socket/that/really/should/not/be/there"
#endif


static int close_cb_called = 0;


static void close_cb(uv_handle_t* handle) {
TUV_ASSERT(handle != NULL);
close_cb_called++;
}


TEST_IMPL(pipe_bind_error_addrinuse) {
uv_pipe_t server1, server2;
int r;
close_cb_called = 0;

r = uv_pipe_init(uv_default_loop(), &server1, 0);
TUV_ASSERT(r == 0);
r = uv_pipe_bind(&server1, TEST_PIPENAME);
TUV_ASSERT(r == 0);

r = uv_pipe_init(uv_default_loop(), &server2, 0);
TUV_ASSERT(r == 0);
r = uv_pipe_bind(&server2, TEST_PIPENAME);
TUV_ASSERT(r == UV_EADDRINUSE);

r = uv_listen((uv_stream_t*)&server1, SOMAXCONN, NULL);
TUV_ASSERT(r == 0);
r = uv_listen((uv_stream_t*)&server2, SOMAXCONN, NULL);
TUV_ASSERT(r == UV_EINVAL);

uv_close((uv_handle_t*)&server1, close_cb);
uv_close((uv_handle_t*)&server2, close_cb);

uv_run(uv_default_loop(), UV_RUN_DEFAULT);

TUV_ASSERT(close_cb_called == 2);

return 0;
}


TEST_IMPL(pipe_bind_error_addrnotavail) {
uv_pipe_t server;
int r;
close_cb_called = 0;

r = uv_pipe_init(uv_default_loop(), &server, 0);
TUV_ASSERT(r == 0);

r = uv_pipe_bind(&server, BAD_PIPENAME);
TUV_ASSERT(r == UV_EACCES);

uv_close((uv_handle_t*)&server, close_cb);

uv_run(uv_default_loop(), UV_RUN_DEFAULT);

TUV_ASSERT(close_cb_called == 1);

return 0;
}


TEST_IMPL(pipe_bind_error_inval) {
uv_pipe_t server;
int r;
close_cb_called = 0;

r = uv_pipe_init(uv_default_loop(), &server, 0);
TUV_ASSERT(r == 0);
r = uv_pipe_bind(&server, TEST_PIPENAME);
TUV_ASSERT(r == 0);
r = uv_pipe_bind(&server, TEST_PIPENAME_2);
TUV_ASSERT(r == UV_EINVAL);

uv_close((uv_handle_t*)&server, close_cb);

uv_run(uv_default_loop(), UV_RUN_DEFAULT);

TUV_ASSERT(close_cb_called == 1);

return 0;
}


TEST_IMPL(pipe_listen_without_bind) {
uv_pipe_t server;
int r;
close_cb_called = 0;

r = uv_pipe_init(uv_default_loop(), &server, 0);
TUV_ASSERT(r == 0);

r = uv_listen((uv_stream_t*)&server, SOMAXCONN, NULL);
TUV_ASSERT(r == UV_EINVAL);

uv_close((uv_handle_t*)&server, close_cb);

uv_run(uv_default_loop(), UV_RUN_DEFAULT);

TUV_ASSERT(close_cb_called == 1);

return 0;
}
Loading

0 comments on commit 9f32c3d

Please sign in to comment.