File indexing completed on 2024-05-12 05:26:00

0001 /*
0002  * Copyright (C) 2014 Aaron Seigo <aseigo@kde.org>
0003  *
0004  *   This program is free software; you can redistribute it and/or modify
0005  *   it under the terms of the GNU General Public License as published by
0006  *   the Free Software Foundation; either version 2 of the License, or
0007  *   (at your option) any later version.
0008  *
0009  *   This program is distributed in the hope that it will be useful,
0010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
0011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0012  *   GNU General Public License for more details.
0013  *
0014  *   You should have received a copy of the GNU General Public License
0015  *   along with this program; if not, write to the
0016  *   Free Software Foundation, Inc.,
0017  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
0018  */
0019 
0020 #pragma once
0021 
0022 #include "sink_export.h"
0023 #include <QObject>
0024 
0025 #include <QPointer>
0026 #include <QLocalSocket>
0027 #include <flatbuffers/flatbuffers.h>
0028 #include <log.h>
0029 
0030 namespace Sink {
0031 class Resource;
0032 class Notification;
0033 }
0034 
0035 class QTimer;
0036 class QLocalServer;
0037 
0038 class Client
0039 {
0040 public:
0041     Client() : socket(nullptr), currentRevision(0)
0042     {
0043     }
0044 
0045     Client(const QString &n, QLocalSocket *s) : name(n), socket(s), currentRevision(0)
0046     {
0047     }
0048 
0049     QString name;
0050     QPointer<QLocalSocket> socket;
0051     QByteArray commandBuffer;
0052     qint64 currentRevision;
0053 };
0054 
0055 class SINK_EXPORT Listener : public QObject
0056 {
0057     Q_OBJECT
0058 public:
0059     Listener(const QByteArray &resourceName, const QByteArray &resourceType, QObject *parent = nullptr);
0060     ~Listener();
0061 
0062     void checkForUpgrade();
0063 
0064 signals:
0065     void noClients();
0066 
0067 public slots:
0068     void closeAllConnections();
0069     void emergencyAbortAllConnections();
0070 
0071 private slots:
0072     void acceptConnection();
0073     void clientDropped();
0074     void checkConnections();
0075     void onDataAvailable();
0076     void processClientBuffers();
0077     void refreshRevision(qint64);
0078     void notify(const Sink::Notification &);
0079     void quit();
0080 
0081 private:
0082     void processCommand(int commandId, uint messageId, const QByteArray &commandBuffer, Client &client, const std::function<void(bool)> &callback);
0083     bool processClientBuffer(Client &client);
0084     void sendCommandCompleted(QLocalSocket *socket, uint messageId, bool success);
0085     void updateClientsWithRevision(qint64);
0086     Sink::Resource &loadResource();
0087     void readFromSocket(QLocalSocket *socket);
0088     void sendShutdownNotification();
0089     qint64 lowerBoundRevision();
0090 
0091     std::unique_ptr<QLocalServer> m_server;
0092     QVector<Client> m_connections;
0093     flatbuffers::FlatBufferBuilder m_fbb;
0094     const QByteArray m_resourceName;
0095     const QByteArray m_resourceInstanceIdentifier;
0096     std::unique_ptr<Sink::Resource> m_resource;
0097     std::unique_ptr<QTimer> m_clientBufferProcessesTimer;
0098     std::unique_ptr<QTimer> m_checkConnectionsTimer;
0099     int m_messageId;
0100     bool m_exiting;
0101 };