diff options
Diffstat (limited to 'common/listener.cpp')
-rw-r--r-- | common/listener.cpp | 33 |
1 files changed, 23 insertions, 10 deletions
diff --git a/common/listener.cpp b/common/listener.cpp index 2c5c1df..6f86ee5 100644 --- a/common/listener.cpp +++ b/common/listener.cpp | |||
@@ -45,7 +45,8 @@ Listener::Listener(const QByteArray &resourceInstanceIdentifier, const QByteArra | |||
45 | m_resourceName(resourceType), | 45 | m_resourceName(resourceType), |
46 | m_resourceInstanceIdentifier(resourceInstanceIdentifier), | 46 | m_resourceInstanceIdentifier(resourceInstanceIdentifier), |
47 | m_clientBufferProcessesTimer(new QTimer(this)), | 47 | m_clientBufferProcessesTimer(new QTimer(this)), |
48 | m_messageId(0) | 48 | m_messageId(0), |
49 | m_exiting(false) | ||
49 | { | 50 | { |
50 | connect(m_server.get(), &QLocalServer::newConnection, this, &Listener::acceptConnection); | 51 | connect(m_server.get(), &QLocalServer::newConnection, this, &Listener::acceptConnection); |
51 | SinkTrace() << "Trying to open " << m_resourceInstanceIdentifier; | 52 | SinkTrace() << "Trying to open " << m_resourceInstanceIdentifier; |
@@ -177,7 +178,7 @@ void Listener::checkConnections() | |||
177 | void Listener::onDataAvailable() | 178 | void Listener::onDataAvailable() |
178 | { | 179 | { |
179 | QLocalSocket *socket = qobject_cast<QLocalSocket *>(sender()); | 180 | QLocalSocket *socket = qobject_cast<QLocalSocket *>(sender()); |
180 | if (!socket) { | 181 | if (!socket || m_exiting) { |
181 | return; | 182 | return; |
182 | } | 183 | } |
183 | readFromSocket(socket); | 184 | readFromSocket(socket); |
@@ -270,9 +271,7 @@ void Listener::processCommand(int commandId, uint messageId, const QByteArray &c | |||
270 | break; | 271 | break; |
271 | case Sink::Commands::ShutdownCommand: | 272 | case Sink::Commands::ShutdownCommand: |
272 | SinkLog() << QString("Received shutdown command from %1").arg(client.name); | 273 | SinkLog() << QString("Received shutdown command from %1").arg(client.name); |
273 | // Immediately reject new connections | 274 | m_exiting = true; |
274 | m_server->close(); | ||
275 | QTimer::singleShot(0, this, &Listener::quit); | ||
276 | break; | 275 | break; |
277 | case Sink::Commands::PingCommand: | 276 | case Sink::Commands::PingCommand: |
278 | SinkTrace() << QString("Received ping command from %1").arg(client.name); | 277 | SinkTrace() << QString("Received ping command from %1").arg(client.name); |
@@ -292,8 +291,7 @@ void Listener::processCommand(int commandId, uint messageId, const QByteArray &c | |||
292 | SinkLog() << QString("Received a remove from disk command from %1").arg(client.name); | 291 | SinkLog() << QString("Received a remove from disk command from %1").arg(client.name); |
293 | m_resource.reset(nullptr); | 292 | m_resource.reset(nullptr); |
294 | loadResource().removeDataFromDisk(); | 293 | loadResource().removeDataFromDisk(); |
295 | m_server->close(); | 294 | m_exiting = true; |
296 | QTimer::singleShot(0, this, &Listener::quit); | ||
297 | } break; | 295 | } break; |
298 | default: | 296 | default: |
299 | if (commandId > Sink::Commands::CustomCommand) { | 297 | if (commandId > Sink::Commands::CustomCommand) { |
@@ -323,7 +321,7 @@ qint64 Listener::lowerBoundRevision() | |||
323 | return lowerBound; | 321 | return lowerBound; |
324 | } | 322 | } |
325 | 323 | ||
326 | void Listener::quit() | 324 | void Listener::sendShutdownNotification() |
327 | { | 325 | { |
328 | // Broadcast shutdown notifications to open clients, so they don't try to restart the resource | 326 | // Broadcast shutdown notifications to open clients, so they don't try to restart the resource |
329 | auto command = Sink::Commands::CreateNotification(m_fbb, Sink::Notification::Shutdown); | 327 | auto command = Sink::Commands::CreateNotification(m_fbb, Sink::Notification::Shutdown); |
@@ -333,10 +331,20 @@ void Listener::quit() | |||
333 | Sink::Commands::write(client.socket, ++m_messageId, Sink::Commands::NotificationCommand, m_fbb); | 331 | Sink::Commands::write(client.socket, ++m_messageId, Sink::Commands::NotificationCommand, m_fbb); |
334 | } | 332 | } |
335 | } | 333 | } |
334 | } | ||
335 | |||
336 | void Listener::quit() | ||
337 | { | ||
338 | m_clientBufferProcessesTimer->stop(); | ||
339 | m_server->close(); | ||
340 | sendShutdownNotification(); | ||
341 | closeAllConnections(); | ||
336 | m_fbb.Clear(); | 342 | m_fbb.Clear(); |
337 | 343 | ||
338 | // Connections will be cleaned up later | 344 | QTimer::singleShot(0, this, [this]() { |
339 | emit noClients(); | 345 | // This will destroy this object |
346 | emit noClients(); | ||
347 | }); | ||
340 | } | 348 | } |
341 | 349 | ||
342 | bool Listener::processClientBuffer(Client &client) | 350 | bool Listener::processClientBuffer(Client &client) |
@@ -369,6 +377,10 @@ bool Listener::processClientBuffer(Client &client) | |||
369 | SinkLog() << QString("Socket became invalid before we could send a response. client: %1").arg(clientName); | 377 | SinkLog() << QString("Socket became invalid before we could send a response. client: %1").arg(clientName); |
370 | } | 378 | } |
371 | }); | 379 | }); |
380 | if (m_exiting) { | ||
381 | quit(); | ||
382 | return false; | ||
383 | } | ||
372 | 384 | ||
373 | return client.commandBuffer.size() >= headerSize; | 385 | return client.commandBuffer.size() >= headerSize; |
374 | } | 386 | } |
@@ -446,6 +458,7 @@ Sink::Resource &Listener::loadResource() | |||
446 | m_resource = std::unique_ptr<Sink::Resource>(new Sink::Resource); | 458 | m_resource = std::unique_ptr<Sink::Resource>(new Sink::Resource); |
447 | } | 459 | } |
448 | } | 460 | } |
461 | Q_ASSERT(m_resource); | ||
449 | return *m_resource; | 462 | return *m_resource; |
450 | } | 463 | } |
451 | 464 | ||