aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKitsune Ral <Kitsune-Ral@users.sf.net>2019-10-15 19:33:21 +0900
committerKitsune Ral <Kitsune-Ral@users.sf.net>2019-10-21 14:11:31 +0900
commit693beec0005bdd98732ad8b4ad760f9de4a9faee (patch)
tree803205562264c99b79e636b6ccdf97f207a8cb0b
parent34a4c5628d6561a26f07d6166dcca05ef3ace191 (diff)
downloadlibquotient-693beec0005bdd98732ad8b4ad760f9de4a9faee.tar.gz
libquotient-693beec0005bdd98732ad8b4ad760f9de4a9faee.zip
Connection: make syncLoop() reentrant
...in the sense that you can call it twice and expect the second invocation to be gracefully ignored rather than two loops conflicting with each other.
-rw-r--r--lib/connection.cpp21
1 files changed, 16 insertions, 5 deletions
diff --git a/lib/connection.cpp b/lib/connection.cpp
index af85d066..a7b1bee9 100644
--- a/lib/connection.cpp
+++ b/lib/connection.cpp
@@ -99,6 +99,7 @@ public:
DirectChatsMap dcLocalAdditions;
DirectChatsMap dcLocalRemovals;
UnorderedMap<QString, EventPtr> accountData;
+ QMetaObject::Connection syncLoopConnection {};
int syncLoopTimeout = -1;
GetCapabilitiesJob* capabilitiesJob = nullptr;
@@ -380,9 +381,20 @@ void Connection::sync(int timeout)
void Connection::syncLoop(int timeout)
{
- d->syncLoopTimeout = timeout;
- connect(this, &Connection::syncDone, this, &Connection::syncLoopIteration);
- syncLoopIteration(); // initial sync to start the loop
+ if (d->syncLoopConnection && d->syncLoopTimeout == timeout) {
+ qCInfo(MAIN) << "Attempt to run sync loop but there's one already "
+ "running; nothing will be done";
+ return;
+ }
+ std::swap(d->syncLoopTimeout, timeout);
+ if (d->syncLoopConnection) {
+ qCWarning(MAIN) << "Overriding timeout of the running sync loop from"
+ << timeout << "to" << d->syncLoopTimeout;
+ } else {
+ d->syncLoopConnection = connect(this, &Connection::syncDone,
+ this, &Connection::syncLoopIteration);
+ syncLoopIteration(); // initial sync to start the loop
+ }
}
QJsonObject toJson(const DirectChatsMap& directChats)
@@ -514,8 +526,7 @@ void Connection::onSyncSuccess(SyncData&& data, bool fromCache)
void Connection::stopSync()
{
// If there's a sync loop, break it
- disconnect(this, &Connection::syncDone, this,
- &Connection::syncLoopIteration);
+ disconnect(d->syncLoopConnection);
if (d->syncJob) // If there's an ongoing sync job, stop it too
{
d->syncJob->abandon();