From bbf11af22fff91b6f8f757a252ee4255bd018166 Mon Sep 17 00:00:00 2001 From: Haavard Date: Fri, 21 Apr 2017 14:33:12 +0000 Subject: let socket handle handle more socket stuff very simple Socket/SimpleSocket stop using fastos sockets in websocket experimental code stop using fastos sockets in vbench --- vbench/CMakeLists.txt | 1 - vbench/src/tests/server_socket/.gitignore | 1 - vbench/src/tests/server_socket/CMakeLists.txt | 9 -- vbench/src/tests/server_socket/FILES | 1 - .../src/tests/server_socket/server_socket_test.cpp | 24 ---- vbench/src/vbench/core/socket.cpp | 33 ++--- vbench/src/vbench/core/socket.h | 34 ++++-- vbench/src/vbench/test/CMakeLists.txt | 1 - vbench/src/vbench/test/all.h | 1 - vbench/src/vbench/test/server_socket.cpp | 39 ------ vbench/src/vbench/test/server_socket.h | 28 ----- vespalib/src/tests/net/socket/socket_client.cpp | 15 +-- vespalib/src/tests/net/socket/socket_server.cpp | 23 ++-- vespalib/src/tests/net/socket/socket_test.cpp | 134 ++++++++++----------- vespalib/src/tests/websocket/websocket_test.cpp | 39 +----- vespalib/src/vespa/vespalib/net/server_socket.cpp | 70 +++++++---- vespalib/src/vespa/vespalib/net/server_socket.h | 19 +-- vespalib/src/vespa/vespalib/net/socket.cpp | 51 +------- vespalib/src/vespa/vespalib/net/socket.h | 37 +++--- vespalib/src/vespa/vespalib/net/socket_address.cpp | 10 +- vespalib/src/vespa/vespalib/net/socket_handle.cpp | 41 +++++++ vespalib/src/vespa/vespalib/net/socket_handle.h | 15 ++- .../src/vespa/vespalib/websocket/CMakeLists.txt | 2 - vespalib/src/vespa/vespalib/websocket/acceptor.cpp | 15 ++- vespalib/src/vespa/vespalib/websocket/acceptor.h | 7 +- vespalib/src/vespa/vespalib/websocket/connection.h | 2 +- .../src/vespa/vespalib/websocket/server_socket.cpp | 44 ------- .../src/vespa/vespalib/websocket/server_socket.h | 31 ----- vespalib/src/vespa/vespalib/websocket/socket.cpp | 44 ------- vespalib/src/vespa/vespalib/websocket/socket.h | 29 ----- 30 files changed, 279 insertions(+), 521 deletions(-) delete mode 100644 vbench/src/tests/server_socket/.gitignore delete mode 100644 vbench/src/tests/server_socket/CMakeLists.txt delete mode 100644 vbench/src/tests/server_socket/FILES delete mode 100644 vbench/src/tests/server_socket/server_socket_test.cpp delete mode 100644 vbench/src/vbench/test/server_socket.cpp delete mode 100644 vbench/src/vbench/test/server_socket.h delete mode 100644 vespalib/src/vespa/vespalib/websocket/server_socket.cpp delete mode 100644 vespalib/src/vespa/vespalib/websocket/server_socket.h delete mode 100644 vespalib/src/vespa/vespalib/websocket/socket.cpp delete mode 100644 vespalib/src/vespa/vespalib/websocket/socket.h diff --git a/vbench/CMakeLists.txt b/vbench/CMakeLists.txt index 493505fc91c..1a5f2860bce 100644 --- a/vbench/CMakeLists.txt +++ b/vbench/CMakeLists.txt @@ -35,7 +35,6 @@ vespa_define_module( src/tests/request_dumper src/tests/request_generator src/tests/request_sink - src/tests/server_socket src/tests/server_spec src/tests/server_tagger src/tests/socket diff --git a/vbench/src/tests/server_socket/.gitignore b/vbench/src/tests/server_socket/.gitignore deleted file mode 100644 index e79511c3a0a..00000000000 --- a/vbench/src/tests/server_socket/.gitignore +++ /dev/null @@ -1 +0,0 @@ -vbench_server_socket_test_app diff --git a/vbench/src/tests/server_socket/CMakeLists.txt b/vbench/src/tests/server_socket/CMakeLists.txt deleted file mode 100644 index ac76763ae16..00000000000 --- a/vbench/src/tests/server_socket/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -vespa_add_executable(vbench_server_socket_test_app TEST - SOURCES - server_socket_test.cpp - DEPENDS - vbench_test - vbench -) -vespa_add_test(NAME vbench_server_socket_test_app COMMAND vbench_server_socket_test_app) diff --git a/vbench/src/tests/server_socket/FILES b/vbench/src/tests/server_socket/FILES deleted file mode 100644 index 47bee2d3769..00000000000 --- a/vbench/src/tests/server_socket/FILES +++ /dev/null @@ -1 +0,0 @@ -server_socket_test.cpp diff --git a/vbench/src/tests/server_socket/server_socket_test.cpp b/vbench/src/tests/server_socket/server_socket_test.cpp deleted file mode 100644 index 575c7dfaa02..00000000000 --- a/vbench/src/tests/server_socket/server_socket_test.cpp +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include -#include -#include - -using namespace vbench; - -TEST_MT_F("require that close will interrupt accept", 2, ServerSocket()) { - if (thread_id == 0) { - for (;;) { - Stream::UP stream = f1.accept(); - if (stream.get() == 0) { - break; - } - } - Stream::UP s2 = f1.accept(); - EXPECT_TRUE(s2.get() == 0); - } else { - vespalib::Thread::sleep(20); - f1.close(); - } -} - -TEST_MAIN() { TEST_RUN_ALL(); } diff --git a/vbench/src/vbench/core/socket.cpp b/vbench/src/vbench/core/socket.cpp index 84975adf4ae..7306d25cf32 100644 --- a/vbench/src/vbench/core/socket.cpp +++ b/vbench/src/vbench/core/socket.cpp @@ -2,12 +2,22 @@ #include #include "socket.h" +#include +#include namespace vbench { +namespace { + +vespalib::SocketHandle connect(const string &host, int port) { + return vespalib::SocketSpec::from_host_port(host, port).client_address().connect(); +} + +} // namespace vbench:: + constexpr size_t READ_SIZE = 32768; -Socket::Socket(std::unique_ptr socket) +Socket::Socket(vespalib::SocketHandle socket) : _socket(std::move(socket)), _input(), _output(), @@ -16,35 +26,26 @@ Socket::Socket(std::unique_ptr socket) { } -Socket::Socket(const string host, int port) - : _socket(new FastOS_Socket()), +Socket::Socket(const string &host, int port) + : _socket(connect(host, port)), _input(), _output(), _taint(), _eof(false) { - if (!_socket->SetAddressByHostName(port, host.c_str()) || - !_socket->SetSoBlocking(true) || - !_socket->Connect() || - !_socket->SetSoLinger(false, 0)) - { - _socket->Close(); + if (!_socket.valid() || !_socket.set_linger(false, 0)) { _taint.reset(strfmt("socket connect failed: host: %s, port: %d", host.c_str(), port)); + _socket.reset(); } } -Socket::~Socket() -{ - _socket->Close(); -} - Memory Socket::obtain() { if ((_input.get().size == 0) && !_eof && !_taint) { WritableMemory buf = _input.reserve(READ_SIZE); - ssize_t res = _socket->Read(buf.data, buf.size); + ssize_t res = _socket.read(buf.data, buf.size); if (res > 0) { _input.commit(res); } else if (res < 0) { @@ -75,7 +76,7 @@ Socket::commit(size_t bytes) _output.commit(bytes); while ((_output.get().size > 0) && !_taint) { Memory buf = _output.obtain(); - ssize_t res = _socket->Write(buf.data, buf.size); + ssize_t res = _socket.write(buf.data, buf.size); if (res > 0) { _output.evict(res); } else { diff --git a/vbench/src/vbench/core/socket.h b/vbench/src/vbench/core/socket.h index 092a28952f4..e961994c37a 100644 --- a/vbench/src/vbench/core/socket.h +++ b/vbench/src/vbench/core/socket.h @@ -5,10 +5,10 @@ #include "string.h" #include "stream.h" #include +#include +#include #include -class FastOS_SocketInterface; - namespace vbench { using Input = vespalib::Input; @@ -20,16 +20,15 @@ using WritableMemory = vespalib::WritableMemory; class Socket : public Stream { private: - std::unique_ptr _socket; - SimpleBuffer _input; - SimpleBuffer _output; - Taint _taint; - bool _eof; + vespalib::SocketHandle _socket; + SimpleBuffer _input; + SimpleBuffer _output; + Taint _taint; + bool _eof; public: - Socket(std::unique_ptr socket); - Socket(const string host, int port); - virtual ~Socket(); + Socket(vespalib::SocketHandle socket); + Socket(const string &host, int port); virtual bool eof() const override { return _eof; } virtual Memory obtain() override; virtual Input &evict(size_t bytes) override; @@ -38,5 +37,20 @@ public: virtual const Taint &tainted() const override { return _taint; } }; +struct ServerSocket { + vespalib::ServerSocket server_socket; + ServerSocket() : server_socket(0) {} + int port() const { return server_socket.address().port(); } + Stream::UP accept() { + vespalib::SocketHandle handle = server_socket.accept(); + if (handle.valid()) { + return std::make_unique(std::move(handle)); + } else { + return Stream::UP(); + } + } + void close() { server_socket.shutdown(); } +}; + } // namespace vbench diff --git a/vbench/src/vbench/test/CMakeLists.txt b/vbench/src/vbench/test/CMakeLists.txt index ddd37822969..2691e78e689 100644 --- a/vbench/src/vbench/test/CMakeLists.txt +++ b/vbench/src/vbench/test/CMakeLists.txt @@ -2,7 +2,6 @@ vespa_add_library(vbench_test STATIC SOURCES request_receptor.cpp - server_socket.cpp simple_http_result_handler.cpp DEPENDS ) diff --git a/vbench/src/vbench/test/all.h b/vbench/src/vbench/test/all.h index c8dd8cf9ac8..3b4167285d9 100644 --- a/vbench/src/vbench/test/all.h +++ b/vbench/src/vbench/test/all.h @@ -39,7 +39,6 @@ #include #include #include -#include #include #include #include diff --git a/vbench/src/vbench/test/server_socket.cpp b/vbench/src/vbench/test/server_socket.cpp deleted file mode 100644 index b87a245dc88..00000000000 --- a/vbench/src/vbench/test/server_socket.cpp +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - - -#include -#include "server_socket.h" -#include -#include - -namespace vbench { - -ServerSocket::ServerSocket() - : _serverSocket(0, 500, 0, 0), - _closed(false) -{ - _serverSocket.SetSoBlocking(false); - _serverSocket.Listen(); -} - -Stream::UP -ServerSocket::accept() -{ - while (!_closed) { - std::unique_ptr socket(_serverSocket.Accept()); - if (socket.get() != 0) { - socket->SetSoBlocking(true); - return Stream::UP(new Socket(std::move(socket))); - } else { - int error = FastOS_Socket::GetLastError(); - if (error == FastOS_Socket::ERR_WOULDBLOCK) { - vespalib::Thread::sleep(10); - } else { - return Stream::UP(); - } - } - } - return Stream::UP(); -} - -} // namespace vbench diff --git a/vbench/src/vbench/test/server_socket.h b/vbench/src/vbench/test/server_socket.h deleted file mode 100644 index 6be9673142f..00000000000 --- a/vbench/src/vbench/test/server_socket.h +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - - -#pragma once - -#include -#include - -namespace vbench { - -/** - * Simple server socket listening to a random port. - **/ -class ServerSocket -{ -private: - FastOS_ServerSocket _serverSocket; - volatile bool _closed; - -public: - ServerSocket(); - Stream::UP accept(); - int port() { return _serverSocket.GetLocalPort(); } - void close() { _closed = true; } -}; - -} // namespace vbench - diff --git a/vespalib/src/tests/net/socket/socket_client.cpp b/vespalib/src/tests/net/socket/socket_client.cpp index e12fe5330d0..fd4abd2813d 100644 --- a/vespalib/src/tests/net/socket/socket_client.cpp +++ b/vespalib/src/tests/net/socket/socket_client.cpp @@ -11,7 +11,7 @@ using namespace vespalib; -vespalib::string read_msg(Socket &socket) { +vespalib::string read_msg(SocketHandle &socket) { vespalib::string msg; for (;;) { char c; @@ -27,7 +27,7 @@ vespalib::string read_msg(Socket &socket) { } } -void write_msg(Socket &socket, const vespalib::string &msg) { +void write_msg(SocketHandle &socket, const vespalib::string &msg) { for (size_t i = 0; i < msg.size(); ++i) { ssize_t ret = socket.write(&msg[i], 1); if (ret != 1) { @@ -53,14 +53,15 @@ int main(int argc, char **argv) { fprintf(stderr, " %s\n", addr.spec().c_str()); } } - Socket::UP socket = Socket::connect(SocketSpec::from_host_port(host, port)); - if (!socket->valid()) { + SocketHandle socket = SocketSpec::from_host_port(host, port).client_address().connect(); + if (!socket.valid()) { fprintf(stderr, "connect failed\n"); return 1; } fprintf(stderr, "connected to: %s (local address: %s)\n", - socket->peer_address().spec().c_str(), socket->address().spec().c_str()); - write_msg(*socket, "hello from client\n"); - fprintf(stderr, "message from server: '%s'\n", read_msg(*socket).c_str()); + SocketAddress::peer_address(socket.get()).spec().c_str(), + SocketAddress::address_of(socket.get()).spec().c_str()); + write_msg(socket, "hello from client\n"); + fprintf(stderr, "message from server: '%s'\n", read_msg(socket).c_str()); return 0; } diff --git a/vespalib/src/tests/net/socket/socket_server.cpp b/vespalib/src/tests/net/socket/socket_server.cpp index ff8d77f317d..c14c69caa70 100644 --- a/vespalib/src/tests/net/socket/socket_server.cpp +++ b/vespalib/src/tests/net/socket/socket_server.cpp @@ -12,7 +12,7 @@ using namespace vespalib; -vespalib::string read_msg(Socket &socket) { +vespalib::string read_msg(SocketHandle &socket) { vespalib::string msg; for (;;) { char c; @@ -28,7 +28,7 @@ vespalib::string read_msg(Socket &socket) { } } -void write_msg(Socket &socket, const vespalib::string &msg) { +void write_msg(SocketHandle &socket, const vespalib::string &msg) { for (size_t i = 0; i < msg.size(); ++i) { ssize_t ret = socket.write(&msg[i], 1); if (ret != 1) { @@ -39,8 +39,8 @@ void write_msg(Socket &socket, const vespalib::string &msg) { } int main(int, char **) { - ServerSocket::UP server = ServerSocket::listen(SocketSpec::from_port(0)); - if (!server->valid()) { + ServerSocket server(0); + if (!server.valid()) { fprintf(stderr, "listen failed, exiting\n"); return 1; } @@ -52,18 +52,19 @@ int main(int, char **) { fprintf(stderr, " %s\n", addr.spec().c_str()); } } - fprintf(stderr, "listening to %s\n", server->address().spec().c_str()); + fprintf(stderr, "listening to %s\n", server.address().spec().c_str()); fprintf(stderr, "client command: ./vespalib_socket_client_app %s %d\n", - HostName::get().c_str(), server->address().port()); + HostName::get().c_str(), server.address().port()); fprintf(stderr, "use ^C (SIGINT) to exit\n"); SignalHandler::INT.hook(); while (!SignalHandler::INT.check()) { - Socket::UP socket = server->accept(); - if (socket->valid()) { + SocketHandle socket = server.accept(); + if (socket.valid()) { fprintf(stderr, "got connection from: %s (local address: %s)\n", - socket->peer_address().spec().c_str(), socket->address().spec().c_str()); - fprintf(stderr, "message from client: '%s'\n", read_msg(*socket).c_str()); - write_msg(*socket, "hello from server\n"); + SocketAddress::peer_address(socket.get()).spec().c_str(), + SocketAddress::address_of(socket.get()).spec().c_str()); + fprintf(stderr, "message from client: '%s'\n", read_msg(socket).c_str()); + write_msg(socket, "hello from server\n"); } else { fprintf(stderr, "(got invalid socket from accept)\n"); } diff --git a/vespalib/src/tests/net/socket/socket_test.cpp b/vespalib/src/tests/net/socket/socket_test.cpp index bf0a5a2f273..c4b1e5286b2 100644 --- a/vespalib/src/tests/net/socket/socket_test.cpp +++ b/vespalib/src/tests/net/socket/socket_test.cpp @@ -74,7 +74,7 @@ vespalib::string get_meta(const SocketAddress &addr) { return meta; } -vespalib::string read_bytes(Socket &socket, size_t wanted_bytes) { +vespalib::string read_bytes(SocketHandle &socket, size_t wanted_bytes) { char tmp[64]; vespalib::string result; while (result.size() < wanted_bytes) { @@ -88,7 +88,7 @@ vespalib::string read_bytes(Socket &socket, size_t wanted_bytes) { return result; } -void verify_socket_io(bool is_server, Socket &socket) { +void verify_socket_io(bool is_server, SocketHandle &socket) { vespalib::string server_message = "hello, this is the server speaking"; vespalib::string client_message = "please pick up, I need to talk to you"; if(is_server) { @@ -104,7 +104,7 @@ void verify_socket_io(bool is_server, Socket &socket) { } } -Socket::UP connect_sockets(bool is_server, ServerSocket &server_socket) { +SocketHandle connect_sockets(bool is_server, ServerSocket &server_socket) { if (is_server) { return server_socket.accept(); } else { @@ -113,7 +113,7 @@ Socket::UP connect_sockets(bool is_server, ServerSocket &server_socket) { auto client = SocketSpec(spec).client_address(); fprintf(stderr, "connecting to '%s' (server: %s) (client: %s)\n", spec.c_str(), get_meta(server).c_str(), get_meta(client).c_str()); - return Socket::connect(SocketSpec(spec)); + return client.connect(); } } @@ -187,84 +187,79 @@ TEST("local client/server addresses") { fprintf(stderr, "server(tcp/123): %s (%s)\n", server.spec().c_str(), get_meta(server).c_str()); } -struct ServerWrapper { - ServerSocket::UP server; - ServerWrapper(const vespalib::string &spec) : server(ServerSocket::listen(SocketSpec(spec))) {} -}; - -TEST_MT_FF("require that basic socket io works", 2, ServerWrapper("tcp/0"), TimeBomb(60)) { +TEST_MT_FF("require that basic socket io works", 2, ServerSocket("tcp/0"), TimeBomb(60)) { bool is_server = (thread_id == 0); - Socket::UP socket = connect_sockets(is_server, *f1.server); - TEST_DO(verify_socket_io(is_server, *socket)); + SocketHandle socket = connect_sockets(is_server, f1); + TEST_DO(verify_socket_io(is_server, socket)); } TEST_MT_FF("require that basic unix domain socket io works (path)", 2, - ServerWrapper("ipc/file:my_socket"), TimeBomb(60)) + ServerSocket("ipc/file:my_socket"), TimeBomb(60)) { bool is_server = (thread_id == 0); - Socket::UP socket = connect_sockets(is_server, *f1.server); - TEST_DO(verify_socket_io(is_server, *socket)); + SocketHandle socket = connect_sockets(is_server, f1); + TEST_DO(verify_socket_io(is_server, socket)); } TEST_MT_FF("require that basic unix domain socket io works (name)", 2, - ServerWrapper(make_string("ipc/name:my_socket-%d", int(getpid()))), TimeBomb(60)) + ServerSocket(make_string("ipc/name:my_socket-%d", int(getpid()))), TimeBomb(60)) { bool is_server = (thread_id == 0); - Socket::UP socket = connect_sockets(is_server, *f1.server); - TEST_DO(verify_socket_io(is_server, *socket)); + SocketHandle socket = connect_sockets(is_server, f1); + TEST_DO(verify_socket_io(is_server, socket)); } -TEST_MT_FF("require that server accept can be interrupted", 2, ServerWrapper("tcp/0"), TimeBomb(60)) { +TEST_MT_FF("require that server accept can be interrupted", 2, ServerSocket("tcp/0"), TimeBomb(60)) { bool is_server = (thread_id == 0); if (is_server) { fprintf(stderr, "--> calling accept\n"); - Socket::UP socket = f1.server->accept(); + SocketHandle socket = f1.accept(); fprintf(stderr, "<-- accept returned\n"); - EXPECT_TRUE(!socket->valid()); + EXPECT_TRUE(!socket.valid()); } else { std::this_thread::sleep_for(std::chrono::milliseconds(500)); fprintf(stderr, "--- closing server socket\n"); - f1.server->shutdown(); + f1.shutdown(); } } TEST("require that socket file is removed by server socket when destructed") { remove_file("my_socket"); - ServerSocket::UP server = ServerSocket::listen(SocketSpec("ipc/file:my_socket")); - EXPECT_TRUE(server->valid()); + ServerSocket server("ipc/file:my_socket"); + EXPECT_TRUE(server.valid()); EXPECT_TRUE(is_socket("my_socket")); - server.reset(); + server = ServerSocket("invalid"); EXPECT_TRUE(!is_socket("my_socket")); } TEST("require that socket file is only removed on destruction if it is a socket") { remove_file("my_socket"); - ServerSocket::UP server = ServerSocket::listen(SocketSpec("ipc/file:my_socket")); - EXPECT_TRUE(server->valid()); + ServerSocket server("ipc/file:my_socket"); + EXPECT_TRUE(server.valid()); EXPECT_TRUE(is_socket("my_socket")); replace_file("my_socket", "hello\n"); - server.reset(); + server = ServerSocket("invalid"); EXPECT_TRUE(is_file("my_socket")); remove_file("my_socket"); } TEST("require that a server socket will fail to listen to a path that is already a regular file") { replace_file("my_socket", "hello\n"); - ServerSocket::UP server = ServerSocket::listen(SocketSpec("ipc/file:my_socket")); - EXPECT_TRUE(!server->valid()); - server.reset(); + ServerSocket server("ipc/file:my_socket"); + EXPECT_TRUE(!server.valid()); + server = ServerSocket("invalid"); EXPECT_TRUE(is_file("my_socket")); remove_file("my_socket"); } TEST("require that a server socket will fail to listen to a path that is already taken by another server") { remove_file("my_socket"); - ServerSocket::UP server1 = ServerSocket::listen(SocketSpec("ipc/file:my_socket")); - ServerSocket::UP server2 = ServerSocket::listen(SocketSpec("ipc/file:my_socket")); - EXPECT_TRUE(server1->valid()); - EXPECT_TRUE(!server2->valid()); + ServerSocket server1("ipc/file:my_socket"); + ServerSocket server2("ipc/file:my_socket"); + EXPECT_TRUE(server1.valid()); + EXPECT_TRUE(!server2.valid()); EXPECT_TRUE(is_socket("my_socket")); - server1.reset(); + server1 = ServerSocket("invalid"); EXPECT_TRUE(!is_socket("my_socket")); } @@ -275,55 +270,54 @@ TEST("require that a server socket will remove an old socket file if it cannot b EXPECT_TRUE(is_socket("my_socket")); } EXPECT_TRUE(is_socket("my_socket")); - ServerSocket::UP server = ServerSocket::listen(SocketSpec("ipc/file:my_socket")); - EXPECT_TRUE(server->valid()); - server.reset(); + ServerSocket server("ipc/file:my_socket"); + EXPECT_TRUE(server.valid()); + server = ServerSocket("invalid"); EXPECT_TRUE(!is_socket("my_socket")); } TEST("require that two server sockets cannot have the same abstract unix domain socket name") { vespalib::string spec = make_string("ipc/name:my_socket-%d", int(getpid())); - ServerSocket::UP server1 = ServerSocket::listen(SocketSpec(spec)); - ServerSocket::UP server2 = ServerSocket::listen(SocketSpec(spec)); - EXPECT_TRUE(server1->valid()); - EXPECT_TRUE(!server2->valid()); + ServerSocket server1(spec); + ServerSocket server2(spec); + EXPECT_TRUE(server1.valid()); + EXPECT_TRUE(!server2.valid()); } TEST("require that abstract socket names are freed when the server socket is destructed") { vespalib::string spec = make_string("ipc/name:my_socket-%d", int(getpid())); - ServerSocket::UP server1 = ServerSocket::listen(SocketSpec(spec)); - EXPECT_TRUE(server1->valid()); - server1.reset(); - ServerSocket::UP server2 = ServerSocket::listen(SocketSpec(spec)); - EXPECT_TRUE(server2->valid()); + ServerSocket server1(spec); + EXPECT_TRUE(server1.valid()); + server1 = ServerSocket("invalid"); + ServerSocket server2(spec); + EXPECT_TRUE(server2.valid()); } TEST("require that abstract sockets do not have socket files") { vespalib::string name = make_string("my_socket-%d", int(getpid())); - vespalib::string spec = make_string("ipc/name:%s", name.c_str()); - ServerSocket::UP server = ServerSocket::listen(SocketSpec(spec)); - EXPECT_TRUE(server->valid()); + ServerSocket server(SocketSpec::from_name(name)); + EXPECT_TRUE(server.valid()); EXPECT_TRUE(!is_socket(name)); EXPECT_TRUE(!is_file(name)); } TEST_MT_FFF("require that abstract and file-based unix domain sockets are not in conflict", 4, - ServerWrapper(make_string("ipc/file:my_socket-%d", int(getpid()))), - ServerWrapper(make_string("ipc/name:my_socket-%d", int(getpid()))), TimeBomb(60)) + ServerSocket(make_string("ipc/file:my_socket-%d", int(getpid()))), + ServerSocket(make_string("ipc/name:my_socket-%d", int(getpid()))), TimeBomb(60)) { bool is_server = ((thread_id % 2) == 0); - ServerSocket &server_socket = ((thread_id / 2) == 0) ? *f1.server : *f2.server; - Socket::UP socket = connect_sockets(is_server, server_socket); - TEST_DO(verify_socket_io(is_server, *socket)); + ServerSocket &server_socket = ((thread_id / 2) == 0) ? f1 : f2; + SocketHandle socket = connect_sockets(is_server, server_socket); + TEST_DO(verify_socket_io(is_server, socket)); } TEST("require that sockets can be set blocking and non-blocking") { SocketHandle handle(socket(my_inet(), SOCK_STREAM, 0)); test::SocketOptionsVerifier verifier(handle.get()); EXPECT_TRUE(!SocketOptions::set_blocking(-1, true)); - EXPECT_TRUE(SocketOptions::set_blocking(handle.get(), true)); + EXPECT_TRUE(handle.set_blocking(true)); TEST_DO(verifier.verify_blocking(true)); - EXPECT_TRUE(SocketOptions::set_blocking(handle.get(), false)); + EXPECT_TRUE(handle.set_blocking(false)); TEST_DO(verifier.verify_blocking(false)); } @@ -331,9 +325,9 @@ TEST("require that tcp nodelay can be enabled and disabled") { SocketHandle handle(socket(my_inet(), SOCK_STREAM, 0)); test::SocketOptionsVerifier verifier(handle.get()); EXPECT_TRUE(!SocketOptions::set_nodelay(-1, true)); - EXPECT_TRUE(SocketOptions::set_nodelay(handle.get(), true)); + EXPECT_TRUE(handle.set_nodelay(true)); TEST_DO(verifier.verify_nodelay(true)); - EXPECT_TRUE(SocketOptions::set_nodelay(handle.get(), false)); + EXPECT_TRUE(handle.set_nodelay(false)); TEST_DO(verifier.verify_nodelay(false)); } @@ -341,9 +335,9 @@ TEST("require that reuse addr can be set and cleared") { SocketHandle handle(socket(my_inet(), SOCK_STREAM, 0)); test::SocketOptionsVerifier verifier(handle.get()); EXPECT_TRUE(!SocketOptions::set_reuse_addr(-1, true)); - EXPECT_TRUE(SocketOptions::set_reuse_addr(handle.get(), true)); + EXPECT_TRUE(handle.set_reuse_addr(true)); TEST_DO(verifier.verify_reuse_addr(true)); - EXPECT_TRUE(SocketOptions::set_reuse_addr(handle.get(), false)); + EXPECT_TRUE(handle.set_reuse_addr(false)); TEST_DO(verifier.verify_reuse_addr(false)); } @@ -352,9 +346,9 @@ TEST("require that ipv6_only can be set and cleared") { SocketHandle handle(socket(my_inet(), SOCK_STREAM, 0)); test::SocketOptionsVerifier verifier(handle.get()); EXPECT_TRUE(!SocketOptions::set_ipv6_only(-1, true)); - EXPECT_TRUE(SocketOptions::set_ipv6_only(handle.get(), true)); + EXPECT_TRUE(handle.set_ipv6_only(true)); TEST_DO(verifier.verify_ipv6_only(true)); - EXPECT_TRUE(SocketOptions::set_ipv6_only(handle.get(), false)); + EXPECT_TRUE(handle.set_ipv6_only(false)); TEST_DO(verifier.verify_ipv6_only(false)); } else { fprintf(stderr, "WARNING: skipping ipv6_only test since ipv6 is disabled"); @@ -365,9 +359,9 @@ TEST("require that tcp keepalive can be set and cleared") { SocketHandle handle(socket(my_inet(), SOCK_STREAM, 0)); test::SocketOptionsVerifier verifier(handle.get()); EXPECT_TRUE(!SocketOptions::set_keepalive(-1, true)); - EXPECT_TRUE(SocketOptions::set_keepalive(handle.get(), true)); + EXPECT_TRUE(handle.set_keepalive(true)); TEST_DO(verifier.verify_keepalive(true)); - EXPECT_TRUE(SocketOptions::set_keepalive(handle.get(), false)); + EXPECT_TRUE(handle.set_keepalive(false)); TEST_DO(verifier.verify_keepalive(false)); } @@ -375,13 +369,13 @@ TEST("require that tcp lingering can be adjusted") { SocketHandle handle(socket(my_inet(), SOCK_STREAM, 0)); test::SocketOptionsVerifier verifier(handle.get()); EXPECT_TRUE(!SocketOptions::set_linger(-1, true, 0)); - EXPECT_TRUE(SocketOptions::set_linger(handle.get(), true, 0)); + EXPECT_TRUE(handle.set_linger(true, 0)); TEST_DO(verifier.verify_linger(true, 0)); - EXPECT_TRUE(SocketOptions::set_linger(handle.get(), true, 10)); + EXPECT_TRUE(handle.set_linger(true, 10)); TEST_DO(verifier.verify_linger(true, 10)); - EXPECT_TRUE(SocketOptions::set_linger(handle.get(), false, 0)); + EXPECT_TRUE(handle.set_linger(false, 0)); TEST_DO(verifier.verify_linger(false, 0)); - EXPECT_TRUE(SocketOptions::set_linger(handle.get(), false, 10)); + EXPECT_TRUE(handle.set_linger(false, 10)); TEST_DO(verifier.verify_linger(false, 0)); } diff --git a/vespalib/src/tests/websocket/websocket_test.cpp b/vespalib/src/tests/websocket/websocket_test.cpp index 962a78c5606..748b0fd5c1e 100644 --- a/vespalib/src/tests/websocket/websocket_test.cpp +++ b/vespalib/src/tests/websocket/websocket_test.cpp @@ -1,7 +1,6 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include -#include -#include +#include #include #include #include @@ -11,6 +10,7 @@ #include #include +using namespace vespalib; using namespace vespalib::ws; template @@ -62,14 +62,6 @@ void verify_socket_io_async(Socket &server, Socket &client) { client_thread.join(); } -Socket::UP connect_sockets(bool is_server, ServerSocket &server_socket) { - if (is_server) { - return server_socket.accept(); - } else { - return Socket::UP(new Socket("localhost", server_socket.port())); - } -} - void check_buffer_stats(const Buffer &buffer, size_t dead, size_t used, size_t free) { EXPECT_EQUAL(dead, buffer.dead()); EXPECT_EQUAL(used, buffer.used()); @@ -109,34 +101,13 @@ TEST("require that buffer moves contained data when more space is needed") { EXPECT_EQUAL('z', *buffer.obtain()); } -TEST_MT_F("require that basic socket io works", 2, ServerSocket(0)) { - bool is_server = (thread_id == 0); - Socket::UP socket = connect_sockets(is_server, f1); - TEST_DO(verify_socket_io(is_server, *socket)); -} - -TEST_MT_F("require that server accept can be interrupted", 2, ServerSocket(0)) { - bool is_server = (thread_id == 0); - if (is_server) { - fprintf(stderr, "--> calling accept\n"); - Socket::UP socket = f1.accept(); - fprintf(stderr, "<-- accept returned\n"); - EXPECT_TRUE(socket.get() == nullptr); - EXPECT_TRUE(f1.is_closed()); - } else { - std::this_thread::sleep_for(std::chrono::milliseconds(500)); - fprintf(stderr, "--- closing server socket\n"); - f1.close(); - } -} - TEST("require that an acceptor can accept connections asynchronously") { Receptor server; Acceptor acceptor(0, server); - Socket::UP client(new Socket("localhost", acceptor.port())); + Socket::UP client = SimpleSocket::connect(SocketSpec::from_port(acceptor.port())); server.gate.await(60000); - EXPECT_TRUE(server.obj.get() != nullptr); - EXPECT_TRUE(client.get() != nullptr); + ASSERT_TRUE(server.obj.get() != nullptr); + ASSERT_TRUE(client.get() != nullptr); TEST_DO(verify_socket_io_async(*server.obj, *client)); } diff --git a/vespalib/src/vespa/vespalib/net/server_socket.cpp b/vespalib/src/vespa/vespalib/net/server_socket.cpp index 04be8fc8888..3f9237b3835 100644 --- a/vespalib/src/vespa/vespalib/net/server_socket.cpp +++ b/vespalib/src/vespa/vespalib/net/server_socket.cpp @@ -16,19 +16,54 @@ bool is_socket(const vespalib::string &path) { return S_ISSOCK(info.st_mode); } -ServerSocket::ServerSocket(SocketHandle handle) - : _handle(std::move(handle)), - _path(SocketAddress::address_of(_handle.get()).path()) +void +ServerSocket::cleanup() { + if (valid() && is_socket(_path)) { + unlink(_path.c_str()); + } } -ServerSocket::~ServerSocket() +ServerSocket::ServerSocket(const SocketSpec &spec) + : _handle(spec.server_address().listen()), + _path(spec.path()) { - if (is_socket(_path)) { - unlink(_path.c_str()); + if (!_handle.valid() && is_socket(_path)) { + if (!spec.client_address().connect().valid()) { + LOG(warning, "removing old socket: '%s'", _path.c_str()); + unlink(_path.c_str()); + _handle = spec.server_address().listen(); + } } } +ServerSocket::ServerSocket(const vespalib::string &spec) + : ServerSocket(SocketSpec(spec)) +{ +} + +ServerSocket::ServerSocket(int port) + : ServerSocket(SocketSpec::from_port(port)) +{ +} + +ServerSocket::ServerSocket(ServerSocket &&rhs) + : _handle(std::move(rhs._handle)), + _path(std::move(rhs._path)) +{ + rhs._path.clear(); +} + +ServerSocket & +ServerSocket::operator=(ServerSocket &&rhs) +{ + cleanup(); + _handle = std::move(rhs._handle); + _path = std::move(rhs._path); + rhs._path.clear(); + return *this; +} + SocketAddress ServerSocket::address() const { @@ -38,30 +73,13 @@ ServerSocket::address() const void ServerSocket::shutdown() { - if (valid()) { - ::shutdown(_handle.get(), SHUT_RDWR); - } + _handle.shutdown(); } -Socket::UP +SocketHandle ServerSocket::accept() { - SocketHandle handle(::accept(_handle.get(), nullptr, 0)); - return std::make_unique(std::move(handle)); -} - -ServerSocket::UP -ServerSocket::listen(const SocketSpec &spec) -{ - SocketHandle handle = spec.server_address().listen(); - if (!handle.valid() && is_socket(spec.path())) { - if (!spec.client_address().connect().valid()) { - LOG(warning, "removing old socket: '%s'", spec.path().c_str()); - unlink(spec.path().c_str()); - handle = spec.server_address().listen(); - } - } - return std::make_unique(std::move(handle)); + return _handle.accept(); } } // namespace vespalib diff --git a/vespalib/src/vespa/vespalib/net/server_socket.h b/vespalib/src/vespa/vespalib/net/server_socket.h index 1c4f41343d7..70cdd61b6d2 100644 --- a/vespalib/src/vespa/vespalib/net/server_socket.h +++ b/vespalib/src/vespa/vespalib/net/server_socket.h @@ -1,11 +1,9 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - #pragma once #include "socket_handle.h" #include "socket_address.h" -#include "socket.h" namespace vespalib { @@ -17,17 +15,20 @@ private: SocketHandle _handle; vespalib::string _path; -public: - typedef std::unique_ptr UP; - ServerSocket(const ServerSocket &rhs) = delete; - ServerSocket &operator=(const ServerSocket &rhs) = delete; explicit ServerSocket(SocketHandle handle); - ~ServerSocket(); + static ServerSocket listen(const SocketSpec &spec); + void cleanup(); +public: + explicit ServerSocket(const SocketSpec &spec); + explicit ServerSocket(const vespalib::string &spec); + explicit ServerSocket(int port); + ServerSocket(ServerSocket &&rhs); + ServerSocket &operator=(ServerSocket &&rhs); + ~ServerSocket() { cleanup(); } bool valid() const { return _handle.valid(); } SocketAddress address() const; void shutdown(); - Socket::UP accept(); - static ServerSocket::UP listen(const SocketSpec &spec); + SocketHandle accept(); }; } // namespace vespalib diff --git a/vespalib/src/vespa/vespalib/net/socket.cpp b/vespalib/src/vespa/vespalib/net/socket.cpp index 8c016df3d6d..c0498e21324 100644 --- a/vespalib/src/vespa/vespalib/net/socket.cpp +++ b/vespalib/src/vespa/vespalib/net/socket.cpp @@ -1,57 +1,14 @@ -// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +// Copyright 2017 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "socket.h" #include "socket_spec.h" namespace vespalib { -SocketAddress -Socket::address() const +std::unique_ptr +SimpleSocket::connect(const SocketSpec &spec) { - return SocketAddress::address_of(_handle.get()); -} - -SocketAddress -Socket::peer_address() const -{ - return SocketAddress::peer_address(_handle.get()); -} - -void -Socket::shutdown() -{ - if (valid()) { - ::shutdown(_handle.get(), SHUT_RDWR); - } -} - -ssize_t -Socket::read(char *buf, size_t len) -{ - for (;;) { - ssize_t result = ::read(_handle.get(), buf, len); - if ((result >= 0) || (errno != EINTR)) { - return result; - } - } -} - -ssize_t -Socket::write(const char *buf, size_t len) -{ - for (;;) { - ssize_t result = ::write(_handle.get(), buf, len); - if ((result >= 0) || (errno != EINTR)) { - return result; - } - } -} - -Socket::UP -Socket::connect(const SocketSpec &spec) -{ - SocketHandle handle = spec.client_address().connect(); - return std::make_unique(std::move(handle)); + return std::make_unique(spec.client_address().connect()); } } // namespace vespalib diff --git a/vespalib/src/vespa/vespalib/net/socket.h b/vespalib/src/vespa/vespalib/net/socket.h index b83faf0a67c..1df5ee97c26 100644 --- a/vespalib/src/vespa/vespalib/net/socket.h +++ b/vespalib/src/vespa/vespalib/net/socket.h @@ -1,33 +1,30 @@ -// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - +// Copyright 2017 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once -#include #include "socket_handle.h" -#include "socket_address.h" +#include namespace vespalib { class SocketSpec; -class Socket -{ -private: - SocketHandle _handle; +/** + * Abstract stream-based socket interface. + **/ +struct Socket { + using UP = std::unique_ptr; + virtual ssize_t read(char *buf, size_t len) = 0; + virtual ssize_t write(const char *buf, size_t len) = 0; + virtual ~Socket() {} +}; -public: - typedef std::unique_ptr UP; - Socket(const Socket &rhs) = delete; - Socket &operator=(const Socket &rhs) = delete; - explicit Socket(SocketHandle handle) : _handle(std::move(handle)) {} - bool valid() const { return _handle.valid(); } - SocketAddress address() const; - SocketAddress peer_address() const; - void shutdown(); - ssize_t read(char *buf, size_t len); - ssize_t write(const char *buf, size_t len); - static Socket::UP connect(const SocketSpec &spec); +struct SimpleSocket : public Socket { + SocketHandle handle; + explicit SimpleSocket(SocketHandle handle_in) : handle(std::move(handle_in)) {} + ssize_t read(char *buf, size_t len) final override { return handle.read(buf, len); } + ssize_t write(const char *buf, size_t len) final override { return handle.write(buf, len); } + static std::unique_ptr connect(const SocketSpec &spec); }; } // namespace vespalib diff --git a/vespalib/src/vespa/vespalib/net/socket_address.cpp b/vespalib/src/vespa/vespalib/net/socket_address.cpp index 6a70491beb8..9e862059ffa 100644 --- a/vespalib/src/vespa/vespalib/net/socket_address.cpp +++ b/vespalib/src/vespa/vespalib/net/socket_address.cpp @@ -133,7 +133,7 @@ SocketAddress::connect() const { if (valid()) { SocketHandle handle(socket(_addr.ss_family, SOCK_STREAM, 0)); - if (handle && (::connect(handle.get(), addr(), _size) == 0)) { + if (handle.valid() && (::connect(handle.get(), addr(), _size) == 0)) { return handle; } } @@ -145,14 +145,12 @@ SocketAddress::listen(int backlog) const { if (valid()) { SocketHandle handle(socket(_addr.ss_family, SOCK_STREAM, 0)); - if (handle) { + if (handle.valid()) { if (is_ipv6()) { - int disable = 0; - setsockopt(handle.get(), IPPROTO_IPV6, IPV6_V6ONLY, &disable, sizeof(disable)); + handle.set_ipv6_only(false); } if (port() > 0) { - int enable = 1; - setsockopt(handle.get(), SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable)); + handle.set_reuse_addr(true); } if ((bind(handle.get(), addr(), _size) == 0) && (::listen(handle.get(), backlog) == 0)) diff --git a/vespalib/src/vespa/vespalib/net/socket_handle.cpp b/vespalib/src/vespa/vespalib/net/socket_handle.cpp index 3e8afa66584..343bfc60924 100644 --- a/vespalib/src/vespa/vespalib/net/socket_handle.cpp +++ b/vespalib/src/vespa/vespalib/net/socket_handle.cpp @@ -1,7 +1,48 @@ // Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "socket_handle.h" +#include +#include namespace vespalib { +ssize_t +SocketHandle::read(char *buf, size_t len) +{ + for (;;) { + ssize_t result = ::read(_fd, buf, len); + if ((result >= 0) || (errno != EINTR)) { + return result; + } + } +} + +ssize_t +SocketHandle::write(const char *buf, size_t len) +{ + for (;;) { + ssize_t result = ::write(_fd, buf, len); + if ((result >= 0) || (errno != EINTR)) { + return result; + } + } +} + +SocketHandle +SocketHandle::accept() +{ + for (;;) { + SocketHandle result(::accept(_fd, nullptr, 0)); + if (result.valid() || (errno != EINTR)) { + return result; + } + } +} + +void +SocketHandle::shutdown() +{ + ::shutdown(_fd, SHUT_RDWR); +} + } // namespace vespalib diff --git a/vespalib/src/vespa/vespalib/net/socket_handle.h b/vespalib/src/vespa/vespalib/net/socket_handle.h index a7dc44c6f2b..baef0c04e19 100644 --- a/vespalib/src/vespa/vespalib/net/socket_handle.h +++ b/vespalib/src/vespa/vespalib/net/socket_handle.h @@ -2,6 +2,7 @@ #pragma once +#include "socket_options.h" #include namespace vespalib { @@ -33,6 +34,7 @@ public: _fd = rhs.release(); return *this; } + ~SocketHandle() { maybe_close(_fd); } bool valid() const { return (_fd >= 0); } operator bool() const { return valid(); } int get() const { return _fd; } @@ -45,7 +47,18 @@ public: maybe_close(_fd); _fd = fd; } - ~SocketHandle() { maybe_close(_fd); } + + bool set_blocking(bool value) { return SocketOptions::set_blocking(_fd, value); } + bool set_nodelay(bool value) { return SocketOptions::set_nodelay(_fd, value); } + bool set_reuse_addr(bool value) { return SocketOptions::set_reuse_addr(_fd, value); } + bool set_ipv6_only(bool value) { return SocketOptions::set_ipv6_only(_fd, value); } + bool set_keepalive(bool value) { return SocketOptions::set_keepalive(_fd, value); } + bool set_linger(bool enable, int value) { return SocketOptions::set_linger(_fd, enable, value); } + + ssize_t read(char *buf, size_t len); + ssize_t write(const char *buf, size_t len); + SocketHandle accept(); + void shutdown(); }; } // namespace vespalib diff --git a/vespalib/src/vespa/vespalib/websocket/CMakeLists.txt b/vespalib/src/vespa/vespalib/websocket/CMakeLists.txt index 172008d2a73..c7a7e5d63af 100644 --- a/vespalib/src/vespa/vespalib/websocket/CMakeLists.txt +++ b/vespalib/src/vespa/vespalib/websocket/CMakeLists.txt @@ -8,8 +8,6 @@ vespa_add_library(vespalib_vespalib_websocket OBJECT handler.cpp key.cpp request.cpp - server_socket.cpp - socket.cpp websocket_server.cpp DEPENDS ) diff --git a/vespalib/src/vespa/vespalib/websocket/acceptor.cpp b/vespalib/src/vespa/vespalib/websocket/acceptor.cpp index 53b6f64ceee..d5d92285cd9 100644 --- a/vespalib/src/vespa/vespalib/websocket/acceptor.cpp +++ b/vespalib/src/vespa/vespalib/websocket/acceptor.cpp @@ -3,6 +3,7 @@ #include #include "acceptor.h" #include +#include namespace vespalib { namespace ws { @@ -10,23 +11,25 @@ namespace ws { void Acceptor::accept_main(Handler &socket_handler) { - while (!_server_socket.is_closed()) { - Socket::UP socket = _server_socket.accept(); - if (socket) { - socket_handler.handle(std::move(socket)); + while (!_is_closed) { + SocketHandle handle = _server_socket.accept(); + if (handle.valid()) { + socket_handler.handle(std::make_unique(std::move(handle))); } } } Acceptor::Acceptor(int port_in, Handler &socket_handler) : _server_socket(port_in), - _accept_thread(&Acceptor::accept_main, this, std::ref(socket_handler)) + _accept_thread(&Acceptor::accept_main, this, std::ref(socket_handler)), + _is_closed(false) { } Acceptor::~Acceptor() { - _server_socket.close(); + _server_socket.shutdown(); + _is_closed = true; _accept_thread.join(); } diff --git a/vespalib/src/vespa/vespalib/websocket/acceptor.h b/vespalib/src/vespa/vespalib/websocket/acceptor.h index 329c5a0f998..8c85c4d524b 100644 --- a/vespalib/src/vespa/vespalib/websocket/acceptor.h +++ b/vespalib/src/vespa/vespalib/websocket/acceptor.h @@ -3,8 +3,10 @@ #pragma once #include "handler.h" -#include "server_socket.h" +#include +#include #include +#include namespace vespalib { namespace ws { @@ -13,13 +15,14 @@ class Acceptor { private: ServerSocket _server_socket; std::thread _accept_thread; + std::atomic _is_closed; void accept_main(Handler &socket_handler); public: Acceptor(int port_in, Handler &socket_handler); ~Acceptor(); - int port() { return _server_socket.port(); } + int port() { return _server_socket.address().port(); } }; } // namespace vespalib::ws diff --git a/vespalib/src/vespa/vespalib/websocket/connection.h b/vespalib/src/vespa/vespalib/websocket/connection.h index 0cb3433ce4f..d2cf18e7fbf 100644 --- a/vespalib/src/vespa/vespalib/websocket/connection.h +++ b/vespalib/src/vespa/vespalib/websocket/connection.h @@ -3,7 +3,7 @@ #pragma once -#include "socket.h" +#include #include "buffer.h" #include "frame.h" diff --git a/vespalib/src/vespa/vespalib/websocket/server_socket.cpp b/vespalib/src/vespa/vespalib/websocket/server_socket.cpp deleted file mode 100644 index 18f95cf4220..00000000000 --- a/vespalib/src/vespa/vespalib/websocket/server_socket.cpp +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - - -#include -#include -#include -#include "server_socket.h" - -namespace vespalib { -namespace ws { - -ServerSocket::ServerSocket(int port_in) - : _server_socket(port_in), - _closed(false) -{ - _server_socket.SetSoBlocking(true); - if (!_server_socket.Listen()) { - throw PortListenException(port_in, "tcp"); - } -} - -Socket::UP -ServerSocket::accept() -{ - std::unique_ptr socket(_server_socket.AcceptPlain()); - if (!socket) { - return Socket::UP(); - } - socket->SetSoBlocking(true); - return Socket::UP(new Socket(std::move(socket))); -} - -void -ServerSocket::close() -{ - _closed = true; - int fd = _server_socket.get_fd(); - if (fd >= 0) { - shutdown(fd, SHUT_RDWR); - } -} - -} // namespace vespalib::ws -} // namespace vespalib diff --git a/vespalib/src/vespa/vespalib/websocket/server_socket.h b/vespalib/src/vespa/vespalib/websocket/server_socket.h deleted file mode 100644 index 664056d82dc..00000000000 --- a/vespalib/src/vespa/vespalib/websocket/server_socket.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - - -#pragma once - -#include "socket.h" -#include - -namespace vespalib { -namespace ws { - -class ServerSocket -{ -private: - struct ServerSocketWrapper : public FastOS_ServerSocket { - ServerSocketWrapper(int port) : FastOS_ServerSocket(port, 50) {} - int get_fd() const { return _socketHandle; } - }; - ServerSocketWrapper _server_socket; - volatile bool _closed; - -public: - ServerSocket(int port_in); - Socket::UP accept(); - void close(); - int port() { return _server_socket.GetLocalPort(); } - bool is_closed() const { return _closed; } -}; - -} // namespace vespalib::ws -} // namespace vespalib diff --git a/vespalib/src/vespa/vespalib/websocket/socket.cpp b/vespalib/src/vespa/vespalib/websocket/socket.cpp deleted file mode 100644 index 3bdea494201..00000000000 --- a/vespalib/src/vespa/vespalib/websocket/socket.cpp +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - - -#include "socket.h" -#include - -namespace vespalib { -namespace ws { - -Socket::Socket(std::unique_ptr socket) - : _socket(std::move(socket)) -{ -} - -Socket::Socket(const vespalib::string &host, int port) - : _socket(new FastOS_Socket()) -{ - if (!_socket->SetAddressByHostName(port, host.c_str()) || - !_socket->SetSoBlocking(true) || - !_socket->Connect()) - { - _socket->Close(); - } -} - -Socket::~Socket() -{ - _socket->Close(); -} - -ssize_t -Socket::read(char *buf, size_t len) -{ - return _socket->Read(buf, len); -} - -ssize_t -Socket::write(const char *buf, size_t len) -{ - return _socket->Write(buf, len); -} - -} // namespace vespalib::ws -} // namespace vespalib diff --git a/vespalib/src/vespa/vespalib/websocket/socket.h b/vespalib/src/vespa/vespalib/websocket/socket.h deleted file mode 100644 index cced2a8b505..00000000000 --- a/vespalib/src/vespa/vespalib/websocket/socket.h +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - - -#pragma once - -#include -#include - -class FastOS_SocketInterface; - -namespace vespalib { -namespace ws { - -class Socket -{ -private: - std::unique_ptr _socket; - -public: - typedef std::unique_ptr UP; - Socket(std::unique_ptr socket); - Socket(const vespalib::string &host, int port); - virtual ~Socket(); - ssize_t read(char *buf, size_t len); - ssize_t write(const char *buf, size_t len); -}; - -} // namespace vespalib::ws -} // namespace vespalib -- cgit v1.2.3