diff --git a/libretroshare/src/gxstrans/p3gxstrans.cc b/libretroshare/src/gxstrans/p3gxstrans.cc index f21e94180..42c225b52 100644 --- a/libretroshare/src/gxstrans/p3gxstrans.cc +++ b/libretroshare/src/gxstrans/p3gxstrans.cc @@ -40,7 +40,10 @@ p3GxsTrans::~p3GxsTrans() bool p3GxsTrans::getStatistics(GxsTransStatistics& stats) { - stats.prefered_group_id = mPreferredGroupId; + { + RS_STACK_MUTEX(mDataMutex); + stats.prefered_group_id = mPreferredGroupId; + } stats.outgoing_records.clear(); { @@ -143,6 +146,19 @@ void p3GxsTrans::handleResponse(uint32_t token, uint32_t req_type) std::vector groups; getGroupData(token, groups); + // First recompute the prefered group Id. + + { + RS_STACK_MUTEX(mDataMutex); + mPreferredGroupId.clear(); + + for( auto grp : groups ) + locked_supersedePreferredGroup(grp->meta.mGroupId); + } + +#ifdef DEBUG_GXSTRANS + std::cerr << " computed preferred group id: " << mPreferredGroupId << std::endl; +#endif for( auto grp : groups ) { /* For each group check if it is better candidate then @@ -155,18 +171,24 @@ void p3GxsTrans::handleResponse(uint32_t token, uint32_t req_type) const RsGroupMetaData& meta = grp->meta; bool subscribed = IS_GROUP_SUBSCRIBED(meta.mSubscribeFlags); - bool old = olderThen( meta.mLastPost, - UNUSED_GROUP_UNSUBSCRIBE_INTERVAL ); - bool supersede = supersedePreferredGroup(meta.mGroupId); + bool old = olderThen( meta.mLastPost, UNUSED_GROUP_UNSUBSCRIBE_INTERVAL ); uint32_t token; - bool shoudlSubscribe = !subscribed && ( !old || supersede ); - bool shoudlUnSubscribe = subscribed && old - && meta.mGroupId != mPreferredGroupId; + bool shouldSubscribe = false ; + bool shouldUnSubscribe = false ; + { + RS_STACK_MUTEX(mDataMutex); + bool shouldSubscribe = !subscribed && ( !old || meta.mGroupId == mPreferredGroupId ); + bool shouldUnSubscribe = subscribed && old && meta.mGroupId != mPreferredGroupId; + } - if(shoudlSubscribe) +#ifdef DEBUG_GXSTRANS + std::cout << " group " << grp->meta.mGroupId << ", subscribed: " << subscribed << " last post: " << meta.mLastPost << " should subscribe: "<< shouldSubscribe + << ", should unsubscribe: " << shouldUnSubscribe << std::endl; +#endif + if(shouldSubscribe) RsGenExchange::subscribeToGroup(token, meta.mGroupId, true); - else if(shoudlUnSubscribe) + else if(shouldUnSubscribe) RsGenExchange::subscribeToGroup(token, meta.mGroupId, false); #ifdef GXS_MAIL_GRP_DEBUG @@ -188,7 +210,14 @@ void p3GxsTrans::handleResponse(uint32_t token, uint32_t req_type) delete grp; } - if(mPreferredGroupId.isNull()) + bool have_preferred_group = false ; + + { + RS_STACK_MUTEX(mDataMutex); + have_preferred_group = !mPreferredGroupId.isNull(); + } + + if(!have_preferred_group) { /* This is true only at first run when we haven't received mail * distribuition groups from friends @@ -214,7 +243,9 @@ void p3GxsTrans::handleResponse(uint32_t token, uint32_t req_type) #endif RsGxsGroupId grpId; acknowledgeTokenGrp(token, grpId); - supersedePreferredGroup(grpId); + + RS_STACK_MUTEX(mDataMutex); + locked_supersedePreferredGroup(grpId); break; } case MAILS_UPDATE: @@ -346,6 +377,9 @@ void p3GxsTrans::GxsTransIntegrityCleanupThread::run() { std::vector& msgV = mit->second; std::vector::iterator vit = msgV.begin(); +#ifdef DEBUG_GXSTRANS + std::cerr << "Group " << mit->first << ": " << std::endl; +#endif for(; vit != msgV.end(); ++vit) { @@ -817,6 +851,8 @@ void p3GxsTrans::locked_processOutgoingRecord(OutgoingRecord& pr) } case GxsTransSendStatus::PENDING_PREFERRED_GROUP: { + RS_STACK_MUTEX(mDataMutex); + if(mPreferredGroupId.isNull()) { requestGroupsData(); @@ -841,7 +877,10 @@ void p3GxsTrans::locked_processOutgoingRecord(OutgoingRecord& pr) grsrz.resize(grsz); RsGxsTransSerializer().serialise(&grcpt, &grsrz[0], &grsz); - pr.presignedReceipt.grpId = mPreferredGroupId; + { + RS_STACK_MUTEX(mDataMutex); + pr.presignedReceipt.grpId = mPreferredGroupId; + } pr.presignedReceipt.metaData = new RsGxsMsgMetaData(); *pr.presignedReceipt.metaData = grcpt.meta; pr.presignedReceipt.msg.setBinData(&grsrz[0], grsz); diff --git a/libretroshare/src/gxstrans/p3gxstrans.h b/libretroshare/src/gxstrans/p3gxstrans.h index 1b029444a..0045cea8e 100644 --- a/libretroshare/src/gxstrans/p3gxstrans.h +++ b/libretroshare/src/gxstrans/p3gxstrans.h @@ -99,7 +99,8 @@ public: mServClientsMutex("p3GxsTrans client services map mutex"), mOutgoingMutex("p3GxsTrans outgoing queue map mutex"), mIngoingMutex("p3GxsTrans ingoing queue map mutex"), - mPerUserStatsMutex("p3GxsTrans user stats mutex") + mPerUserStatsMutex("p3GxsTrans user stats mutex"), + mDataMutex("p3GxsTrans data mutex") { mLastMsgCleanup = time(NULL) - MAX_DELAY_BETWEEN_CLEANUPS + 30; // always check 30 secs after start mCleanupThread = NULL ; @@ -253,7 +254,7 @@ private: * @return true if preferredGroupId has been supeseded by potentialGrId * false otherwise. */ - bool inline supersedePreferredGroup(const RsGxsGroupId& potentialGrId) + bool inline locked_supersedePreferredGroup(const RsGxsGroupId& potentialGrId) { if(mPreferredGroupId < potentialGrId) { @@ -320,5 +321,9 @@ private: RsMutex mPerUserStatsMutex; std::map per_user_statistics ; + + // Mutex to protect local data + + RsMutex mDataMutex; }; diff --git a/retroshare-gui/src/gui/statistics/GxsTransportStatistics.cpp b/retroshare-gui/src/gui/statistics/GxsTransportStatistics.cpp index 7233b6981..9d1811d8d 100644 --- a/retroshare-gui/src/gui/statistics/GxsTransportStatistics.cpp +++ b/retroshare-gui/src/gui/statistics/GxsTransportStatistics.cpp @@ -252,8 +252,10 @@ void GxsTransportStatistics::updateContent() groupTreeWidget->addTopLevelItem(item); groupTreeWidget->setItemExpanded(item,openned_groups.find(it->first) != openned_groups.end()); + QString msg_time_string = (stat.last_publish_TS>0)?QString(" (Last msg: %1)").arg(QDateTime::fromTime_t(stat.last_publish_TS).toString()):"" ; + + item->setData(COL_GROUP_NUM_MSGS, Qt::DisplayRole, QString::number(stat.mNumMsgs) + msg_time_string) ; item->setData(COL_GROUP_GRP_ID, Qt::DisplayRole, QString::fromStdString(stat.mGrpId.toStdString())) ; - item->setData(COL_GROUP_NUM_MSGS, Qt::DisplayRole, QString::number(stat.mNumMsgs)) ; item->setData(COL_GROUP_SIZE_MSGS, Qt::DisplayRole, QString::number(stat.mTotalSizeOfMsgs)) ; item->setData(COL_GROUP_SUBSCRIBED,Qt::DisplayRole, stat.subscribed?tr("Yes"):tr("No")) ; item->setData(COL_GROUP_POPULARITY,Qt::DisplayRole, QString::number(stat.popularity)) ; @@ -429,6 +431,7 @@ void GxsTransportStatistics::loadMsgMeta(const uint32_t& token) return ; for(GxsMsgMetaMap::const_iterator it(m.begin());it!=m.end();++it) - mGroupStats[it->first].messages_metas = it->second ; + for(uint32_t i=0;isecond.size();++i) + mGroupStats[it->first].addMessageMeta(it->second[i]) ; } diff --git a/retroshare-gui/src/gui/statistics/GxsTransportStatistics.h b/retroshare-gui/src/gui/statistics/GxsTransportStatistics.h index c57d63c11..3f3b4f2e2 100644 --- a/retroshare-gui/src/gui/statistics/GxsTransportStatistics.h +++ b/retroshare-gui/src/gui/statistics/GxsTransportStatistics.h @@ -38,11 +38,24 @@ class UIStateHelper; class RsGxsTransGroupStatistics: public GxsGroupStatistic { public: - RsGxsTransGroupStatistics() {} + RsGxsTransGroupStatistics() + { + last_publish_TS = 0; + popularity = 0; + subscribed = false; + } + + void addMessageMeta(const RsMsgMetaData& meta) + { + messages_metas.push_back(meta) ; + last_publish_TS = std::max(last_publish_TS,meta.mPublishTs) ; + } bool subscribed ; int popularity ; + time_t last_publish_TS; + std::vector messages_metas ; };