// Copyright 2019 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "dap/network.h" #include "socket.h" #include #include #include #include namespace { class Impl : public dap::net::Server { public: Impl() : stopped{true} {} ~Impl() { stop(); } bool start(int port, const OnConnect& onConnect, const OnError& onError) override { return start("localhost", port, onConnect, onError); } bool start(const char* address, int port, const OnConnect& onConnect, const OnError& onError) override { std::unique_lock lock(mutex); stopWithLock(); socket = std::unique_ptr( new dap::Socket(address, std::to_string(port).c_str())); if (!socket->isOpen()) { onError("Failed to open socket"); return false; } stopped = false; thread = std::thread([=] { while (true) { if (auto rw = socket->accept()) { onConnect(rw); continue; } if (!stopped) { onError("Failed to accept connection"); } break; }; }); return true; } void stop() override { std::unique_lock lock(mutex); stopWithLock(); } private: bool isRunning() { return !stopped; } void stopWithLock() { if (!stopped.exchange(true)) { socket->close(); thread.join(); } } std::mutex mutex; std::thread thread; std::unique_ptr socket; std::atomic stopped; OnError errorHandler; }; } // anonymous namespace namespace dap { namespace net { std::unique_ptr Server::create() { return std::unique_ptr(new Impl()); } std::shared_ptr connect(const char* addr, int port, uint32_t timeoutMillis) { return Socket::connect(addr, std::to_string(port).c_str(), timeoutMillis); } } // namespace net } // namespace dap