1
0
mirror of https://github.com/qTox/qTox.git synced 2024-03-22 14:00:36 +08:00

Merge pull request #4607

anthony.bilinski (1):
      fix(receipts): Prevent double message send for received receipt
This commit is contained in:
sudden6 2017-09-17 23:19:24 +02:00
commit 9c01eec268
No known key found for this signature in database
GPG Key ID: 279509B499E032B9
3 changed files with 66 additions and 15 deletions

View File

@ -220,7 +220,6 @@ void Nexus::showMainGUI()
connect(core, &Core::friendStatusMessageChanged, widget, &Widget::onFriendStatusMessageChanged); connect(core, &Core::friendStatusMessageChanged, widget, &Widget::onFriendStatusMessageChanged);
connect(core, &Core::friendRequestReceived, widget, &Widget::onFriendRequestReceived); connect(core, &Core::friendRequestReceived, widget, &Widget::onFriendRequestReceived);
connect(core, &Core::friendMessageReceived, widget, &Widget::onFriendMessageReceived); connect(core, &Core::friendMessageReceived, widget, &Widget::onFriendMessageReceived);
connect(core, &Core::receiptRecieved, widget, &Widget::onReceiptRecieved);
connect(core, &Core::groupInviteReceived, widget, &Widget::onGroupInviteReceived); connect(core, &Core::groupInviteReceived, widget, &Widget::onGroupInviteReceived);
connect(core, &Core::groupMessageReceived, widget, &Widget::onGroupMessageReceived); connect(core, &Core::groupMessageReceived, widget, &Widget::onGroupMessageReceived);
connect(core, &Core::groupNamelistChanged, widget, &Widget::onGroupNamelistChanged); connect(core, &Core::groupNamelistChanged, widget, &Widget::onGroupNamelistChanged);

View File

@ -25,6 +25,7 @@
#include "src/persistence/settings.h" #include "src/persistence/settings.h"
#include <QMutexLocker> #include <QMutexLocker>
#include <QTimer> #include <QTimer>
#include <QCoreApplication>
/** /**
* @var static const int OfflineMsgEngine::offlineTimeout * @var static const int OfflineMsgEngine::offlineTimeout
@ -52,19 +53,14 @@ void OfflineMsgEngine::dischargeReceipt(int receipt)
{ {
QMutexLocker ml(&mutex); QMutexLocker ml(&mutex);
Profile* profile = Nexus::getProfile();
auto it = receipts.find(receipt); auto it = receipts.find(receipt);
if (it != receipts.end()) { if (it == receipts.end()) {
int mID = it.value(); it = receipts.insert(receipt, Receipt());
auto msgIt = undeliveredMsgs.find(mID); } else if (it->bRecepitReceived) {
if (msgIt != undeliveredMsgs.end()) { qWarning() << "Received duplicate receipt";
if (profile->isHistoryEnabled())
profile->getHistory()->markAsSent(mID);
msgIt.value().msg->markAsSent(QDateTime::currentDateTime());
undeliveredMsgs.erase(msgIt);
}
receipts.erase(it);
} }
it->bRecepitReceived = true;
processReceipt(receipt);
} }
void OfflineMsgEngine::registerReceipt(int receipt, int64_t messageID, ChatMessage::Ptr msg, void OfflineMsgEngine::registerReceipt(int receipt, int64_t messageID, ChatMessage::Ptr msg,
@ -72,8 +68,16 @@ void OfflineMsgEngine::registerReceipt(int receipt, int64_t messageID, ChatMessa
{ {
QMutexLocker ml(&mutex); QMutexLocker ml(&mutex);
receipts[receipt] = messageID; auto it = receipts.find(receipt);
if (it == receipts.end()) {
it = receipts.insert(receipt, Receipt());
} else if (it->bRowValid && receipt != 0 /* offline receipt */) {
qWarning() << "Received duplicate registration of receipt";
}
it->rowId = messageID;
it->bRowValid = true;
undeliveredMsgs[messageID] = {msg, timestamp, receipt}; undeliveredMsgs[messageID] = {msg, timestamp, receipt};
processReceipt(receipt);
} }
void OfflineMsgEngine::deliverOfflineMsgs() void OfflineMsgEngine::deliverOfflineMsgs()
@ -119,3 +123,43 @@ void OfflineMsgEngine::removeAllReceipts()
receipts.clear(); receipts.clear();
} }
void OfflineMsgEngine::updateTimestamp(int receiptId)
{
QMutexLocker ml(&mutex);
auto receipt = receipts.find(receiptId);
const auto msg = undeliveredMsgs.constFind(receipt->rowId);
if (msg == undeliveredMsgs.end()) {
// this should never occur as registerReceipt adds the msg before processReceipt calls updateTimestamp
qCritical() << "Message was not in undeliveredMsgs map when attempting to update its timestamp!";
return;
}
msg->msg->markAsSent(QDateTime::currentDateTime());
undeliveredMsgs.remove(receipt->rowId);
receipts.erase(receipt);
}
void OfflineMsgEngine::processReceipt(int receiptId)
{
const auto receipt = receipts.constFind(receiptId);
if (receipt == receipts.end()) {
// this should never occur as callers ensure receipts contains receiptId
qCritical() << "Receipt was not added to map prior to attempting to process it!";
return;
}
if (!receipt->bRecepitReceived || !receipt->bRowValid)
return;
Profile* const profile = Nexus::getProfile();
if (profile->isHistoryEnabled()) {
profile->getHistory()->markAsSent(receipt->rowId);
}
if (QThread::currentThread() == QCoreApplication::instance()->thread()) {
updateTimestamp(receiptId);
} else {
QMetaObject::invokeMethod(this, "updateTimestamp", Qt::QueuedConnection, Q_ARG(int, receiptId));
}
}

View File

@ -45,18 +45,26 @@ public:
public slots: public slots:
void deliverOfflineMsgs(); void deliverOfflineMsgs();
void removeAllReceipts(); void removeAllReceipts();
void updateTimestamp(int receiptId);
private: private:
void processReceipt(int receiptId);
struct Receipt
{
bool bRowValid{false};
int64_t rowId{0};
bool bRecepitReceived{false};
};
struct MsgPtr struct MsgPtr
{ {
ChatMessage::Ptr msg; ChatMessage::Ptr msg;
QDateTime timestamp; QDateTime timestamp;
int receipt; int receipt;
}; };
QMutex mutex; QMutex mutex;
Friend* f; Friend* f;
QHash<int, int64_t> receipts; QHash<int, Receipt> receipts;
QMap<int64_t, MsgPtr> undeliveredMsgs; QMap<int64_t, MsgPtr> undeliveredMsgs;
static const int offlineTimeout; static const int offlineTimeout;