diff --git a/src/libs/clangbackendipc/connectionserver.cpp b/src/libs/clangbackendipc/connectionserver.cpp index 9d84dbbad36..6828041de81 100644 --- a/src/libs/clangbackendipc/connectionserver.cpp +++ b/src/libs/clangbackendipc/connectionserver.cpp @@ -25,124 +25,9 @@ #include "connectionserver.h" -#include - -#include -#include -#include - -#include - namespace ClangBackEnd { -QString ConnectionServer::connectionName; - -ConnectionServer::ConnectionServer(const QString &connectionName) - : aliveTimerId(startTimer(5000)) -{ - this->connectionName = connectionName; - - localServer.setMaxPendingConnections(1); - - connect(&localServer, &QLocalServer::newConnection, this, &ConnectionServer::handleNewConnection); - std::atexit(&ConnectionServer::removeServer); -#if defined(_GLIBCXX_HAVE_AT_QUICK_EXIT) - std::at_quick_exit(&ConnectionServer::removeServer); -#endif - std::set_terminate(&ConnectionServer::removeServer); -} - -ConnectionServer::~ConnectionServer() -{ - killTimer(aliveTimerId); - removeServer(); -} - -void ConnectionServer::start() -{ - QLocalServer::removeServer(connectionName); - localServer.listen(connectionName); -} - -void ConnectionServer::setClangCodeModelServer(ClangCodeModelServerInterface *ipcServer) -{ - this->ipcServer = ipcServer; - -} - -int ConnectionServer::clientProxyCount() const -{ - return static_cast(ipcServerProxies.size()); -} - -void ConnectionServer::timerEvent(QTimerEvent *timerEvent) -{ - if (aliveTimerId == timerEvent->timerId()) - sendAliveMessage(); -} - -void ConnectionServer::handleNewConnection() -{ - QLocalSocket *localSocket(nextPendingConnection()); - - ipcServerProxies.emplace_back(ipcServer, localSocket); - - ipcServer->setClient(&ipcServerProxies.back()); - - localSockets.push_back(localSocket); - - emit newConnection(); -} - -void ConnectionServer::sendAliveMessage() -{ - ipcServer->client()->alive(); -} - -void ConnectionServer::handleSocketDisconnect() -{ - QLocalSocket *senderLocalSocket = static_cast(sender()); - - removeClientProxyWithLocalSocket(senderLocalSocket); - localSockets.erase(std::remove_if(localSockets.begin(), - localSockets.end(), - [senderLocalSocket](QLocalSocket *localSocketInList) { return localSocketInList == senderLocalSocket;})); - - delayedExitApplicationIfNoSockedIsConnected(); -} - -void ConnectionServer::removeClientProxyWithLocalSocket(QLocalSocket *localSocket) -{ - ipcServerProxies.erase(std::remove_if(ipcServerProxies.begin(), - ipcServerProxies.end(), - [localSocket](const ClangCodeModelClientProxy &client) { return client.isUsingThatIoDevice(localSocket);})); -} - -QLocalSocket *ConnectionServer::nextPendingConnection() -{ - QLocalSocket *localSocket = localServer.nextPendingConnection(); - - connect(localSocket, &QLocalSocket::disconnected, this, &ConnectionServer::handleSocketDisconnect); - - return localSocket; -} - -void ConnectionServer::removeServer() -{ - QLocalServer::removeServer(connectionName); -} - -void ConnectionServer::delayedExitApplicationIfNoSockedIsConnected() -{ - if (localSockets.size() == 0) - QTimer::singleShot(60000, this, &ConnectionServer::exitApplicationIfNoSockedIsConnected); -} - -void ConnectionServer::exitApplicationIfNoSockedIsConnected() -{ - if (localSockets.size() == 0) - QCoreApplication::exit(); -} +QString ConnectionName::connectionName; } // namespace ClangBackEnd diff --git a/src/libs/clangbackendipc/connectionserver.h b/src/libs/clangbackendipc/connectionserver.h index e3a904ec8d5..4e3c0b18f33 100644 --- a/src/libs/clangbackendipc/connectionserver.h +++ b/src/libs/clangbackendipc/connectionserver.h @@ -25,10 +25,14 @@ #pragma once -#include +#include "clangbackendipc_global.h" +#include #include +#include +#include +#include #include namespace ClangBackEnd { @@ -36,42 +40,112 @@ namespace ClangBackEnd { class ClangCodeModelServerInterface; class ClangCodeModelClientProxy; -class CMBIPC_EXPORT ConnectionServer : public QObject -{ - Q_OBJECT -public: - ConnectionServer(const QString &connectionName); - ~ConnectionServer(); - - void start(); - void setClangCodeModelServer(ClangCodeModelServerInterface *ipcServer); - - int clientProxyCount() const; - - static void removeServer(); - -signals: - void newConnection(); - -protected: - void timerEvent(QTimerEvent *timerEvent); - -private: - void handleNewConnection(); - void sendAliveMessage(); - void handleSocketDisconnect(); - void removeClientProxyWithLocalSocket(QLocalSocket *localSocket); - QLocalSocket *nextPendingConnection(); - void delayedExitApplicationIfNoSockedIsConnected(); - void exitApplicationIfNoSockedIsConnected(); - -private: - std::vector ipcServerProxies; - std::vector localSockets; - ClangCodeModelServerInterface *ipcServer; - QLocalServer localServer; +struct CMBIPC_EXPORT ConnectionName { static QString connectionName; - int aliveTimerId; +}; + +template +class ConnectionServer +{ +public: + ConnectionServer(const QString &connectionName) + { + ConnectionName::connectionName = connectionName; + + aliveTimer.start(5000); + + localServer.setMaxPendingConnections(1); + + QObject::connect(&localServer, + &QLocalServer::newConnection, + [&] { handleNewConnection(); }); + QObject::connect(&aliveTimer, + &QTimer::timeout, + [&] { sendAliveMessage(); }); + + std::atexit(&ConnectionServer::removeServer); + #if defined(_GLIBCXX_HAVE_AT_QUICK_EXIT) + std::at_quick_exit(&ConnectionServer::removeServer); + #endif + std::set_terminate(&ConnectionServer::removeServer); + } + + ~ConnectionServer() + { + removeServer(); + } + + void start() + { + QLocalServer::removeServer(ConnectionName::connectionName); + localServer.listen(ConnectionName::connectionName); + } + + void setClangCodeModelServer(ServerInterface *ipcServer) + { + this->ipcServer = ipcServer; + + } + + static void removeServer() + { + QLocalServer::removeServer(ConnectionName::connectionName); + } + +private: + void handleNewConnection() + { + localSocket = nextPendingConnection(); + + ipcClientProxy.reset(new ClientProxy(ipcServer, localSocket)); + + ipcServer->setClient(ipcClientProxy.get()); + } + + void sendAliveMessage() + { + ipcClientProxy->alive(); + } + + void handleSocketDisconnect() + { + ipcClientProxy.reset(); + + localSocket = nullptr; + + delayedExitApplicationIfNoSockedIsConnected(); + } + + QLocalSocket *nextPendingConnection() + { + QLocalSocket *localSocket = localServer.nextPendingConnection(); + + QObject::connect(localSocket, + &QLocalSocket::disconnected, + [&] { handleSocketDisconnect(); }); + + return localSocket; + } + + void delayedExitApplicationIfNoSockedIsConnected() + { + if (localSocket == nullptr) + QTimer::singleShot(60000, [&] { exitApplicationIfNoSockedIsConnected(); }); + } + + void exitApplicationIfNoSockedIsConnected() + { + if (localSocket == nullptr) + QCoreApplication::exit(); + } + +private: + std::unique_ptr ipcClientProxy; + QLocalSocket* localSocket; + ServerInterface *ipcServer; + QLocalServer localServer; + QTimer aliveTimer; }; } // namespace ClangBackEnd diff --git a/src/tools/clangbackend/clangbackendmain.cpp b/src/tools/clangbackend/clangbackendmain.cpp index de234cf6b2e..914df5c0170 100644 --- a/src/tools/clangbackend/clangbackendmain.cpp +++ b/src/tools/clangbackend/clangbackendmain.cpp @@ -29,6 +29,11 @@ #include #include +#include + +using ClangBackEnd::ClangCodeModelClientProxy; +using ClangBackEnd::ClangCodeModelServer; +using ClangBackEnd::ConnectionServer; QString processArguments(QCoreApplication &application) { @@ -62,8 +67,8 @@ int main(int argc, char *argv[]) clang_toggleCrashRecovery(true); clang_enableStackTraces(); - ClangBackEnd::ClangCodeModelServer clangCodeModelServer; - ClangBackEnd::ConnectionServer connectionServer(connection); + ClangCodeModelServer clangCodeModelServer; + ConnectionServer connectionServer(connection); connectionServer.start(); connectionServer.setClangCodeModelServer(&clangCodeModelServer); diff --git a/tests/unit/echoserver/echoclangcodemodelserver.cpp b/tests/unit/echoserver/echoclangcodemodelserver.cpp index 6f2997a0104..930c81c8fda 100644 --- a/tests/unit/echoserver/echoclangcodemodelserver.cpp +++ b/tests/unit/echoserver/echoclangcodemodelserver.cpp @@ -54,7 +54,7 @@ void EchoClangCodeModelServer::dispatch(const MessageEnvelop &message) void EchoClangCodeModelServer::end() { - ConnectionServer::removeServer(); + ConnectionServer::removeServer(); QCoreApplication::quit(); } diff --git a/tests/unit/echoserver/echoserverprocessmain.cpp b/tests/unit/echoserver/echoserverprocessmain.cpp index cd10d692041..3d76664c1e1 100644 --- a/tests/unit/echoserver/echoserverprocessmain.cpp +++ b/tests/unit/echoserver/echoserverprocessmain.cpp @@ -25,10 +25,15 @@ #include "echoclangcodemodelserver.h" +#include #include #include +using ClangBackEnd::ClangCodeModelClientProxy; +using ClangBackEnd::ConnectionServer; +using ClangBackEnd::EchoClangCodeModelServer; + int main(int argc, char *argv[]) { QCoreApplication::setOrganizationName("QtProject"); @@ -43,8 +48,8 @@ int main(int argc, char *argv[]) return 1; } - ClangBackEnd::EchoClangCodeModelServer echoClangCodeModelServer; - ClangBackEnd::ConnectionServer connectionServer(application.arguments()[1]); + EchoClangCodeModelServer echoClangCodeModelServer; + ConnectionServer connectionServer(application.arguments()[1]); connectionServer.start(); connectionServer.setClangCodeModelServer(&echoClangCodeModelServer);