diff options
author | David Robillard <d@drobilla.net> | 2013-02-04 00:54:25 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2013-02-04 00:54:25 +0000 |
commit | 46c3a486eee4b2ef69d9cc4f9e2701082c64d7c8 (patch) | |
tree | ecf7a89fb1c28a619106dd78ccd257a1ff52c70a /src/socket | |
parent | 69f98d63f5bd22c82208fef5fbc2a61613541bd7 (diff) | |
download | ingen-46c3a486eee4b2ef69d9cc4f9e2701082c64d7c8.tar.gz ingen-46c3a486eee4b2ef69d9cc4f9e2701082c64d7c8.tar.bz2 ingen-46c3a486eee4b2ef69d9cc4f9e2701082c64d7c8.zip |
Replace Raul::thread with std::thread.
git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@5047 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/socket')
-rw-r--r-- | src/socket/SocketClient.hpp | 4 | ||||
-rw-r--r-- | src/socket/SocketListener.cpp | 128 | ||||
-rw-r--r-- | src/socket/SocketListener.hpp | 46 | ||||
-rw-r--r-- | src/socket/SocketReader.cpp | 14 | ||||
-rw-r--r-- | src/socket/SocketReader.hpp | 9 | ||||
-rw-r--r-- | src/socket/ingen_socket_server.cpp | 118 | ||||
-rw-r--r-- | src/socket/wscript | 1 |
7 files changed, 124 insertions, 196 deletions
diff --git a/src/socket/SocketClient.hpp b/src/socket/SocketClient.hpp index b05cb343..f7d8b95e 100644 --- a/src/socket/SocketClient.hpp +++ b/src/socket/SocketClient.hpp @@ -34,9 +34,7 @@ public: : SocketWriter(world.uri_map(), world.uris(), uri, sock) , _respondee(respondee) , _reader(world, *respondee.get(), sock) - { - _reader.start(); - } + {} virtual SPtr<Interface> respondee() const { return _respondee; diff --git a/src/socket/SocketListener.cpp b/src/socket/SocketListener.cpp deleted file mode 100644 index c2c1d0ee..00000000 --- a/src/socket/SocketListener.cpp +++ /dev/null @@ -1,128 +0,0 @@ -/* - This file is part of Ingen. - Copyright 2007-2012 David Robillard <http://drobilla.net/> - - Ingen is free software: you can redistribute it and/or modify it under the - terms of the GNU Affero General Public License as published by the Free - Software Foundation, either version 3 of the License, or any later version. - - Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Affero General Public License for details. - - You should have received a copy of the GNU Affero General Public License - along with Ingen. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include <errno.h> -#include <poll.h> - -#include <sstream> - -#include "ingen/AtomReader.hpp" -#include "ingen/Configuration.hpp" -#include "ingen/Interface.hpp" -#include "ingen/Log.hpp" -#include "ingen/World.hpp" -#include "sord/sordmm.hpp" -#include "sratom/sratom.h" - -#include "../server/Engine.hpp" -#include "../server/EventWriter.hpp" -#include "SocketListener.hpp" -#include "SocketServer.hpp" - -namespace Ingen { -namespace Socket { - -SocketListener::SocketListener(Ingen::World& world) - : Raul::Thread() - , _world(world) - , _unix_sock(Socket::Type::UNIX) - , _net_sock(Socket::Type::TCP) -{ - // Create UNIX socket - _unix_path = world.conf().option("socket").ptr<char>(); - const Raul::URI unix_uri("unix://" + _unix_path); - if (!_unix_sock.bind(unix_uri) || !_unix_sock.listen()) { - _world.log().error("Failed to create UNIX socket\n"); - _unix_sock.close(); - } - _world.log().info(Raul::fmt("Listening on socket %1%\n") % unix_uri); - - // Create TCP socket - int port = world.conf().option("engine-port").get<int32_t>(); - std::ostringstream ss; - ss << "tcp://localhost:"; - ss << port; - if (!_net_sock.bind(Raul::URI(ss.str())) || !_net_sock.listen()) { - _world.log().error("Failed to create TCP socket\n"); - _net_sock.close(); - } - _world.log().info(Raul::fmt("Listening on TCP port %1%\n") % port); - - start(); -} - -SocketListener::~SocketListener() -{ - _exit_flag = true; - _unix_sock.shutdown(); - _net_sock.shutdown(); - _unix_sock.close(); - _net_sock.close(); - join(); - unlink(_unix_path.c_str()); -} - -void -SocketListener::_run() -{ - Server::Engine* engine = (Server::Engine*)_world.engine().get(); - - struct pollfd pfds[2]; - int nfds = 0; - if (_unix_sock.fd() != -1) { - pfds[nfds].fd = _unix_sock.fd(); - pfds[nfds].events = POLLIN; - pfds[nfds].revents = 0; - ++nfds; - } - if (_net_sock.fd() != -1) { - pfds[nfds].fd = _net_sock.fd(); - pfds[nfds].events = POLLIN; - pfds[nfds].revents = 0; - ++nfds; - } - - while (true) { - // Wait for input to arrive at a socket - const int ret = poll(pfds, nfds, -1); - if (_exit_flag) { - break; - } else if (ret == -1) { - _world.log().error(Raul::fmt("Poll error: %1%\n") % strerror(errno)); - break; - } else if (ret == 0) { - _world.log().error("Poll returned with no data\n"); - continue; - } - - if (pfds[0].revents & POLLIN) { - SPtr<Socket> conn = _unix_sock.accept(); - if (conn) { - new SocketServer(_world, *engine, conn); - } - } - - if (pfds[1].revents & POLLIN) { - SPtr<Socket> conn = _net_sock.accept(); - if (conn) { - new SocketServer(_world, *engine, conn); - } - } - } -} - -} // namespace Ingen -} // namespace Socket diff --git a/src/socket/SocketListener.hpp b/src/socket/SocketListener.hpp deleted file mode 100644 index bea55da2..00000000 --- a/src/socket/SocketListener.hpp +++ /dev/null @@ -1,46 +0,0 @@ -/* - This file is part of Ingen. - Copyright 2007-2012 David Robillard <http://drobilla.net/> - - Ingen is free software: you can redistribute it and/or modify it under the - terms of the GNU Affero General Public License as published by the Free - Software Foundation, either version 3 of the License, or any later version. - - Ingen is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR - A PARTICULAR PURPOSE. See the GNU Affero General Public License for details. - - You should have received a copy of the GNU Affero General Public License - along with Ingen. If not, see <http://www.gnu.org/licenses/>. -*/ - -#include <string> - -#include "raul/Thread.hpp" - -#include "Socket.hpp" - -namespace Ingen { - -class Interface; -class World; - -namespace Socket { - -class SocketListener : public Raul::Thread -{ -public: - explicit SocketListener(Ingen::World& world); - ~SocketListener(); - -private: - virtual void _run(); - - Ingen::World& _world; - std::string _unix_path; - Socket _unix_sock; - Socket _net_sock; -}; - -} // namespace Ingen -} // namespace Socket diff --git a/src/socket/SocketReader.cpp b/src/socket/SocketReader.cpp index 4ff65b3b..d3e6affc 100644 --- a/src/socket/SocketReader.cpp +++ b/src/socket/SocketReader.cpp @@ -33,20 +33,20 @@ namespace Socket { SocketReader::SocketReader(Ingen::World& world, Interface& iface, SPtr<Socket> sock) - : Raul::Thread() - , _world(world) + : _world(world) , _iface(iface) , _inserter(NULL) , _msg_node(NULL) , _socket(sock) -{ - start(); -} + , _exit_flag(false) + , _thread(&SocketReader::run, this) +{} SocketReader::~SocketReader() { + _exit_flag = true; _socket->shutdown(); - join(); + _thread.join(); } SerdStatus @@ -86,7 +86,7 @@ SocketReader::write_statement(SocketReader* iface, } void -SocketReader::_run() +SocketReader::run() { Sord::World* world = _world.rdf_world(); LV2_URID_Map* map = &_world.uri_map().urid_map_feature()->urid_map; diff --git a/src/socket/SocketReader.hpp b/src/socket/SocketReader.hpp index ea2bcd8e..489b7e3f 100644 --- a/src/socket/SocketReader.hpp +++ b/src/socket/SocketReader.hpp @@ -17,7 +17,8 @@ #ifndef INGEN_SOCKET_SOCKET_READER_HPP #define INGEN_SOCKET_SOCKET_READER_HPP -#include "raul/Thread.hpp" +#include <thread> + #include "sord/sord.h" #include "Socket.hpp" @@ -30,7 +31,7 @@ class World; namespace Socket { /** Calls Interface methods based on Turtle messages received via socket. */ -class SocketReader : public Raul::Thread +class SocketReader { public: SocketReader(World& world, @@ -40,7 +41,7 @@ public: ~SocketReader(); private: - virtual void _run(); + void run(); static SerdStatus set_base_uri(SocketReader* iface, const SerdNode* uri_node); @@ -64,6 +65,8 @@ private: SordInserter* _inserter; SordNode* _msg_node; SPtr<Socket> _socket; + bool _exit_flag; + std::thread _thread; }; } // namespace Ingen diff --git a/src/socket/ingen_socket_server.cpp b/src/socket/ingen_socket_server.cpp index 37b05bae..0a9d7494 100644 --- a/src/socket/ingen_socket_server.cpp +++ b/src/socket/ingen_socket_server.cpp @@ -14,31 +14,133 @@ along with Ingen. If not, see <http://www.gnu.org/licenses/>. */ +#include <errno.h> +#include <poll.h> + +#include <sstream> +#include <thread> + +#include "ingen/Configuration.hpp" #include "ingen/Module.hpp" #include "ingen/World.hpp" #include "../server/Engine.hpp" #include "../server/EventWriter.hpp" -#include "SocketListener.hpp" +#include "Socket.hpp" +#include "SocketServer.hpp" + +#define UNIX_SCHEME "unix://" + +namespace Ingen { +namespace Socket { + +static void +ingen_listen(Ingen::World* world, Socket* unix_sock, Socket* net_sock) +{ + const std::string unix_path(world->conf().option("socket").ptr<char>()); + + SPtr<Server::Engine> engine = dynamic_ptr_cast<Server::Engine>( + world->engine()); + + // Bind UNIX socket + const Raul::URI unix_uri(UNIX_SCHEME + unix_path); + if (!unix_sock->bind(unix_uri) || !unix_sock->listen()) { + world->log().error("Failed to create UNIX socket\n"); + unix_sock->close(); + } + world->log().info(Raul::fmt("Listening on socket %1%\n") % unix_uri); -using namespace Ingen; + // Bind TCP socket + const int port = world->conf().option("engine-port").get<int32_t>(); + std::ostringstream ss; + ss << "tcp://localhost:"; + ss << port; + if (!net_sock->bind(Raul::URI(ss.str())) || !net_sock->listen()) { + world->log().error("Failed to create TCP socket\n"); + net_sock->close(); + } + world->log().info(Raul::fmt("Listening on TCP port %1%\n") % port); -struct IngenSocketServerModule : public Ingen::Module { - void load(Ingen::World* world) { - listener = SPtr<Ingen::Socket::SocketListener>( - new Ingen::Socket::SocketListener(*world)); + struct pollfd pfds[2]; + int nfds = 0; + if (unix_sock->fd() != -1) { + pfds[nfds].fd = unix_sock->fd(); + pfds[nfds].events = POLLIN; + pfds[nfds].revents = 0; + ++nfds; + } + if (net_sock->fd() != -1) { + pfds[nfds].fd = net_sock->fd(); + pfds[nfds].events = POLLIN; + pfds[nfds].revents = 0; + ++nfds; } - SPtr<Ingen::Socket::SocketListener> listener; + while (true) { + // Wait for input to arrive at a socket + const int ret = poll(pfds, nfds, -1); + if (ret == -1) { + world->log().error(Raul::fmt("Poll error: %1%\n") % strerror(errno)); + break; + } else if ((pfds[0].revents & POLLHUP) || pfds[1].revents & POLLHUP) { + break; + } else if (ret == 0) { + world->log().error("Poll returned with no data\n"); + continue; + } + + if (pfds[0].revents & POLLIN) { + SPtr<Socket> conn = unix_sock->accept(); + if (conn) { + new SocketServer(*world, *engine, conn); + } + } + + if (pfds[1].revents & POLLIN) { + SPtr<Socket> conn = net_sock->accept(); + if (conn) { + new SocketServer(*world, *engine, conn); + } + } + } +} + +struct ServerModule : public Ingen::Module +{ + ServerModule() + : unix_sock(Socket::Type::UNIX) + , net_sock(Socket::Type::TCP) + {} + + ~ServerModule() { + unix_sock.shutdown(); + net_sock.shutdown(); + thread->join(); + unlink(unix_sock.uri().substr(strlen(UNIX_SCHEME)).c_str()); + } + + void load(World* world) { + world = world; + thread = std::unique_ptr<std::thread>( + new std::thread(ingen_listen, world, &unix_sock, &net_sock)); + } + + World* world; + Socket unix_sock; + Socket net_sock; + std::unique_ptr<std::thread> thread; }; +} // namespace Socket +} // namespace Ingen + extern "C" { Ingen::Module* ingen_module_load() { - return new IngenSocketServerModule(); + return new Ingen::Socket::ServerModule(); } } // extern "C" diff --git a/src/socket/wscript b/src/socket/wscript index f6705c37..e503e8a2 100644 --- a/src/socket/wscript +++ b/src/socket/wscript @@ -5,7 +5,6 @@ def build(bld): if bld.is_defined('HAVE_SOCKET'): obj = bld(features = 'cxx cxxshlib', source = ['Socket.cpp', - 'SocketListener.cpp', 'SocketReader.cpp', 'SocketWriter.cpp', 'ingen_socket_server.cpp'], |