From 0bc57e43d20d519761780b6adc7cdb2a24a34592 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Tue, 25 Mar 2014 09:21:20 +0000 Subject: [PATCH] Server: correctly handle Accepters lifetime When exiting kakoune, ClientAccepters (now Server::Accepter) could stay alive, which left an FDWatcher in the EventManager triggering an assert. Now Server is handling their lifetime. --- src/remote.cc | 19 +++++++++++++------ src/remote.hh | 4 ++++ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/remote.cc b/src/remote.cc index 1140d6f7..ecdc03ce 100644 --- a/src/remote.cc +++ b/src/remote.cc @@ -479,10 +479,10 @@ void send_command(const String& session, const String& command) // * When a nul byte is recieved, the socket is handed to a new Client along // with the command. // * When the connection is closed, the command is run in an empty context. -class ClientAccepter +class Server::Accepter { public: - ClientAccepter(int socket) + Accepter(int socket) : m_socket_watcher(socket, [this](FDWatcher&) { handle_available_input(); }) {} private: @@ -508,14 +508,14 @@ private: } catch (client_removed&) {} close(socket); - delete this; + Server::instance().remove_accepter(this); return; } if (c == 0) // end of initial command stream, go to interactive ui mode { ClientManager::instance().create_client( std::unique_ptr{new RemoteUI{socket}}, m_buffer); - delete this; + Server::instance().remove_accepter(this); return; } else @@ -547,7 +547,7 @@ Server::Server(String session_name) if (listen(listen_sock, 4) == -1) throw runtime_error("unable to listen on socket " + filename); - auto accepter = [](FDWatcher& watcher) { + auto accepter = [this](FDWatcher& watcher) { sockaddr_un client_addr; socklen_t client_addr_len = sizeof(sockaddr_un); int sock = accept(watcher.fd(), (sockaddr*) &client_addr, &client_addr_len); @@ -555,7 +555,7 @@ Server::Server(String session_name) throw runtime_error("accept failed"); fcntl(sock, F_SETFD, FD_CLOEXEC); - new ClientAccepter{sock}; + m_accepters.emplace_back(new Accepter{sock}); }; m_listener.reset(new FDWatcher{listen_sock, accepter}); } @@ -572,4 +572,11 @@ Server::~Server() close_session(); } +void Server::remove_accepter(Accepter* accepter) +{ + auto it = find(m_accepters, accepter); + kak_assert(it != m_accepters.end()); + m_accepters.erase(it); +} + } diff --git a/src/remote.hh b/src/remote.hh index 3881f349..22259930 100644 --- a/src/remote.hh +++ b/src/remote.hh @@ -48,8 +48,12 @@ struct Server : public Singleton void close_session(); private: + class Accepter; + void remove_accepter(Accepter* accepter); + String m_session; std::unique_ptr m_listener; + std::vector> m_accepters; }; }