summaryrefslogtreecommitdiffstats
path: root/resource/listener.cpp
diff options
context:
space:
mode:
authorAaron Seigo <aseigo@kde.org>2014-12-01 11:54:37 +0100
committerAaron Seigo <aseigo@kde.org>2014-12-01 12:01:13 +0100
commit2f52bd2ed26cc151fa90ed9e06b1ea9990f9fc7c (patch)
treee125101f32ad78a679c63f9c08571d3b11cd691f /resource/listener.cpp
parentaf38dcdf3a836a1b94064a617acac387a2de6539 (diff)
downloadsink-2f52bd2ed26cc151fa90ed9e06b1ea9990f9fc7c.tar.gz
sink-2f52bd2ed26cc151fa90ed9e06b1ea9990f9fc7c.zip
send revision updates from resource to client
this includes an initial revision message on connect
Diffstat (limited to 'resource/listener.cpp')
-rw-r--r--resource/listener.cpp72
1 files changed, 63 insertions, 9 deletions
diff --git a/resource/listener.cpp b/resource/listener.cpp
index 8a571e9..5dd8cc3 100644
--- a/resource/listener.cpp
+++ b/resource/listener.cpp
@@ -3,13 +3,15 @@
3#include "common/console.h" 3#include "common/console.h"
4#include "common/commands.h" 4#include "common/commands.h"
5#include "common/handshake_generated.h" 5#include "common/handshake_generated.h"
6#include "common/revisionupdate_generated.h"
6 7
7#include <QLocalSocket> 8#include <QLocalSocket>
8#include <QTimer> 9#include <QTimer>
9 10
10Listener::Listener(const QString &resource, QObject *parent) 11Listener::Listener(const QString &resource, QObject *parent)
11 : QObject(parent), 12 : QObject(parent),
12 m_server(new QLocalServer(this)) 13 m_server(new QLocalServer(this)),
14 m_revision(0)
13{ 15{
14 connect(m_server, &QLocalServer::newConnection, 16 connect(m_server, &QLocalServer::newConnection,
15 this, &Listener::acceptConnection); 17 this, &Listener::acceptConnection);
@@ -34,6 +36,19 @@ Listener::~Listener()
34{ 36{
35} 37}
36 38
39void Listener::setRevision(unsigned long long revision)
40{
41 if (m_revision != revision) {
42 m_revision = revision;
43 updateClientsWithRevision();
44 }
45}
46
47unsigned long long Listener::revision() const
48{
49 return m_revision;
50}
51
37void Listener::closeAllConnections() 52void Listener::closeAllConnections()
38{ 53{
39 //TODO: close all client connectionsin m_connections 54 //TODO: close all client connectionsin m_connections
@@ -73,7 +88,7 @@ void Listener::clientDropped()
73 } 88 }
74 89
75 Console::main()->log("Dropping connection..."); 90 Console::main()->log("Dropping connection...");
76 QMutableListIterator<Client> it(m_connections); 91 QMutableVectorIterator<Client> it(m_connections);
77 while (it.hasNext()) { 92 while (it.hasNext()) {
78 const Client &client = it.next(); 93 const Client &client = it.next();
79 if (client.socket == socket) { 94 if (client.socket == socket) {
@@ -102,24 +117,25 @@ void Listener::readFromSocket()
102 } 117 }
103 118
104 Console::main()->log("Reading from socket..."); 119 Console::main()->log("Reading from socket...");
105 QMutableListIterator<Client> it(m_connections); 120 for (Client &client: m_connections) {
106 while (it.hasNext()) {
107 Client &client = it.next();
108 if (client.socket == socket) { 121 if (client.socket == socket) {
109 Console::main()->log(QString(" Client: %1").arg(client.name)); 122 Console::main()->log(QString(" Client: %1").arg(client.name));
110 client.commandBuffer += socket->readAll(); 123 client.commandBuffer += socket->readAll();
111 processClientBuffer(client); 124 // FIXME: schedule these rather than process them all at once
125 // right now this can lead to starvation of clients due to
126 // one overly active client
127 while (processClientBuffer(client)) {}
112 break; 128 break;
113 } 129 }
114 } 130 }
115} 131}
116 132
117void Listener::processClientBuffer(Client &client) 133bool Listener::processClientBuffer(Client &client)
118{ 134{
119 static const int headerSize = (sizeof(int) * 2); 135 static const int headerSize = (sizeof(int) * 2);
120 Console::main()->log(QString("processing %1").arg(client.commandBuffer.size())); 136 Console::main()->log(QString("processing %1").arg(client.commandBuffer.size()));
121 if (client.commandBuffer.size() < headerSize) { 137 if (client.commandBuffer.size() < headerSize) {
122 return; 138 return false;
123 } 139 }
124 140
125 int commandId, size; 141 int commandId, size;
@@ -134,12 +150,50 @@ void Listener::processClientBuffer(Client &client)
134 case Commands::HandshakeCommand: { 150 case Commands::HandshakeCommand: {
135 auto buffer = Toynadi::GetHandshake(data.constData()); 151 auto buffer = Toynadi::GetHandshake(data.constData());
136 Console::main()->log(QString(" Handshake from %1").arg(buffer->name()->c_str())); 152 Console::main()->log(QString(" Handshake from %1").arg(buffer->name()->c_str()));
137 //TODO: reply? 153 sendCurrentRevision(client);
138 break; 154 break;
139 } 155 }
140 default: 156 default:
141 // client.hasSentCommand = true; 157 // client.hasSentCommand = true;
142 break; 158 break;
143 } 159 }
160
161 return client.commandBuffer.size() >= headerSize;
162 } else {
163 return false;
164 }
165}
166
167void Listener::sendCurrentRevision(Client &client)
168{
169 if (!client.socket || !client.socket->isValid()) {
170 return;
171 }
172
173 flatbuffers::FlatBufferBuilder fbb;
174 auto command = Toynadi::CreateRevisionUpdate(fbb, m_revision);
175 Toynadi::FinishRevisionUpdateBuffer(fbb, command);
176 const int commandId = Commands::RevisionUpdateCommand;
177 const int dataSize = fbb.GetSize();
178 client.socket->write((const char*)&commandId, sizeof(int));
179 client.socket->write((const char*)&dataSize, sizeof(int));
180 client.socket->write((const char*)fbb.GetBufferPointer(), dataSize);
181}
182
183void Listener::updateClientsWithRevision()
184{
185 flatbuffers::FlatBufferBuilder fbb;
186 auto command = Toynadi::CreateRevisionUpdate(fbb, m_revision);
187 Toynadi::FinishRevisionUpdateBuffer(fbb, command);
188 const int commandId = Commands::RevisionUpdateCommand;
189 const int dataSize = fbb.GetSize();
190
191 for (const Client &client: m_connections) {
192 if (!client.socket || !client.socket->isValid()) {
193 continue;
194 }
195 client.socket->write((const char*)&commandId, sizeof(int));
196 client.socket->write((const char*)&dataSize, sizeof(int));
197 client.socket->write((const char*)fbb.GetBufferPointer(), dataSize);
144 } 198 }
145} 199}