diff options
author | Robert Adam <dev@robert-adam.de> | 2020-08-19 17:33:21 +0300 |
---|---|---|
committer | Robert Adam <dev@robert-adam.de> | 2020-08-21 12:30:26 +0300 |
commit | 3a55fb4a66f411772339fe4e92da4fe545a66415 (patch) | |
tree | 693e059c36b8b56d793720e1864efa894a987bab /src/ChannelListener.cpp | |
parent | f2acfb50f43965a41cc8a3c3b94c6bf27b8a5cc7 (diff) |
FIX(client): Racecondition deleting ChannelListeners
As ChannelListeners are only synchronised with the server once
msgServerSync has been received, there is still a racecondition for them
even though we only save them if the ServerSync has happened yet.
The connection could be terminated before the answer of the server for
the request to add the respective listeners reaches the client. In that
case the listeners would be erased by the call to
ChannelListener::saveToDB().
Thus this commit introduces yet another flag indicating whether the
listeners have synchronised with the server yet.
Diffstat (limited to 'src/ChannelListener.cpp')
-rw-r--r-- | src/ChannelListener.cpp | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/src/ChannelListener.cpp b/src/ChannelListener.cpp index 5bb9ee951..64d2fbc18 100644 --- a/src/ChannelListener.cpp +++ b/src/ChannelListener.cpp @@ -32,6 +32,7 @@ ChannelListener::ChannelListener() #ifdef MUMBLE , m_volumeLock() , m_listenerVolumeAdjustments() + , m_initialSyncDone(false) #endif {} @@ -125,6 +126,10 @@ QHash<int, float> ChannelListener::getAllListenerLocalVolumeAdjustmentsImpl(bool return volumeMap; } } + +void ChannelListener::setInitialServerSyncDoneImpl(bool done) { + m_initialSyncDone.store(done); +} #endif void ChannelListener::clearImpl() { @@ -241,12 +246,23 @@ QHash<int, float> ChannelListener::getAllListenerLocalVolumeAdjustments(bool fil return get().getAllListenerLocalVolumeAdjustmentsImpl(filter); } +void ChannelListener::setInitialServerSyncDone(bool done) { + get().setInitialServerSyncDoneImpl(done); +} + void ChannelListener::saveToDB() { if (!g.sh || g.sh->qbaDigest.isEmpty() || g.uiSession == 0) { // Can't save as we don't have enough context return; } + if (!get().m_initialSyncDone.load()) { + // If we were to save the listeners before the sync is done, we'd overwrite the list of listeners in the + // DB with an empty set, effectively erasing all set-up listeners. + qWarning("ChannelListener: Aborting save of user's listeners as initial ServerSync is not done yet"); + return; + } + // Save the currently listened channels g.db->setChannelListeners(g.sh->qbaDigest, ChannelListener::getListenedChannelsForUser(g.uiSession)); // And also the currently set volume adjustments (if they're not set to 1.0) |