diff --git a/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc b/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc index 81dd097e0..3b20527e1 100644 --- a/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc +++ b/libretroshare/src/gossipdiscovery/p3gossipdiscovery.cc @@ -108,14 +108,6 @@ p3discovery2::p3discovery2( // Add self into PGP FriendList. mFriendList[AuthGPG::getAuthGPG()->getGPGOwnId()] = DiscPgpInfo(); - - if(rsEvents) - rsEvents->registerEventsHandler( - RsEventType::GOSSIP_DISCOVERY, - [this](std::shared_ptr event) - { - rsEventsHandler(*event); - }, mRsEventsHandle ); // mRsEventsHandle is zeroed in initializer list } @@ -1280,11 +1272,6 @@ bool p3discovery2::setPeerVersion(const RsPeerId &peerId, const std::string &ver return true; } -void p3discovery2::rsEventsHandler(const RsEvent& event) -{ - Dbg3() << __PRETTY_FUNCTION__ << " " << static_cast(event.mType) << std::endl; -} - /*************************************************************************************/ /* AuthGPGService */ diff --git a/libretroshare/src/jsonapi/jsonapi.cpp b/libretroshare/src/jsonapi/jsonapi.cpp index 993165fdb..a24d73c4b 100644 --- a/libretroshare/src/jsonapi/jsonapi.cpp +++ b/libretroshare/src/jsonapi/jsonapi.cpp @@ -352,7 +352,7 @@ JsonApiServer::JsonApiServer(): configMutex("JsonApiServer config"), rsEvents, "rsEvents", cAns, session ) ) return; - RsEventType eventType = RsEventType::NONE; + RsEventType eventType = RsEventType::__NONE; // deserialize input parameters from JSON { @@ -395,7 +395,8 @@ JsonApiServer::JsonApiServer(): configMutex("JsonApiServer config"), } ); }; - bool retval = rsEvents->registerEventsHandler(eventType,multiCallback, hId); + bool retval = rsEvents->registerEventsHandler( + multiCallback, hId, eventType ); { RsGenericSerializer::SerializeContext& ctx(cAns); diff --git a/libretroshare/src/retroshare/rsevents.h b/libretroshare/src/retroshare/rsevents.h index cd23cacd9..c960a16a2 100644 --- a/libretroshare/src/retroshare/rsevents.h +++ b/libretroshare/src/retroshare/rsevents.h @@ -50,7 +50,7 @@ extern RsEvents* rsEvents; */ enum class RsEventType : uint32_t { - NONE = 0, /// Used to detect uninitialized event + __NONE = 0, /// Used internally to detect invalid event type passed /// @see RsBroadcastDiscovery BROADCAST_DISCOVERY = 1, @@ -64,7 +64,7 @@ enum class RsEventType : uint32_t /// @see pqissl PEER_CONNECTION = 4, - /// @see RsGxsChanges // this one is used in RsGxsBroadcast + /// @see RsGxsChanges, used also in @see RsGxsBroadcast GXS_CHANGES = 5, /// Emitted when a peer state changes, @see RsPeers @@ -95,9 +95,9 @@ enum class RsEventType : uint32_t FILE_TRANSFER = 14, /// @see RsMsgs - CHAT_MESSAGE = 15, + CHAT_MESSAGE = 15, - MAX /// Used to detect invalid event type passed + __MAX /// Used internally to detect invalid event type passed }; /** @@ -107,7 +107,7 @@ enum class RsEventType : uint32_t struct RsEvent : RsSerializable { protected: - RsEvent(RsEventType type) : + explicit RsEvent(RsEventType type) : mType(type), mTimePoint(std::chrono::system_clock::now()) {} RsEvent() = delete; @@ -174,8 +174,9 @@ public: * @brief Register events handler * Every time an event is dispatced the registered events handlers will get * their method handleEvent called with the event passed as paramether. + * @attention Callbacks must not fiddle internally with methods of this + * class otherwise a deadlock will happen. * @jsonapi{development,manualwrapper} - * @param eventType Type of event for which the callback is called * @param multiCallback Function that will be called each time an event * is dispatched. * @param[inout] hId Optional storage for handler id, useful to @@ -183,13 +184,15 @@ public: * value may be provided to the function call but * must habe been generated with * @see generateUniqueHandlerId() + * @param eventType Optional type of event for which the callback is + * called, if NONE is passed multiCallback is + * called for every events without filtering. * @return False on error, true otherwise. */ virtual bool registerEventsHandler( - RsEventType eventType, std::function)> multiCallback, - RsEventsHandlerId_t& hId = RS_DEFAULT_STORAGE_PARAM(RsEventsHandlerId_t, 0) - ) = 0; + RsEventsHandlerId_t& hId = RS_DEFAULT_STORAGE_PARAM(RsEventsHandlerId_t, 0), + RsEventType eventType = RsEventType::__NONE ) = 0; /** * @brief Unregister event handler @@ -200,4 +203,3 @@ public: virtual ~RsEvents(); }; - diff --git a/libretroshare/src/services/rseventsservice.cc b/libretroshare/src/services/rseventsservice.cc index c1aa0958c..f0db8bc3f 100644 --- a/libretroshare/src/services/rseventsservice.cc +++ b/libretroshare/src/services/rseventsservice.cc @@ -39,7 +39,7 @@ bool isEventValid( return false; } - if(event->mType <= RsEventType::NONE) + if(event->mType <= RsEventType::__NONE) { errorMessage = "Event has type NONE: " + std::to_string( @@ -48,9 +48,9 @@ bool isEventValid( return false; } - if(event->mType >= RsEventType::MAX) + if(event->mType >= RsEventType::__MAX) { - errorMessage = "Event has type >= RsEventType::MAX: " + + errorMessage = "Event has type >= RsEventType::__MAX: " + std::to_string( static_cast::type >( event->mType ) ); @@ -100,25 +100,30 @@ RsEventsHandlerId_t RsEventsService::generateUniqueHandlerId_unlocked() } bool RsEventsService::registerEventsHandler( - RsEventType eventType, std::function)> multiCallback, - RsEventsHandlerId_t& hId ) + RsEventsHandlerId_t& hId, RsEventType eventType ) { RS_STACK_MUTEX(mHandlerMapMtx); - if( (int)eventType > mHandlerMaps.size() + 10) - { - RsErr() << "Cannot register an event handler for an event type larger than 10 plus the max pre-defined event (value passed was " << (int)eventType << " whereas max is " << (int)RsEventType::MAX << ")" << std::endl; - return false; - } + if( eventType >= RsEventType::__MAX) + { + RsErr() << __PRETTY_FUNCTION__ << " Invalid event type: " + << static_cast(eventType) << " >= RsEventType::__MAX:" + << static_cast(RsEventType::__MAX) << std::endl; + print_stacktrace(); + return false; + } - if( (int)eventType >= mHandlerMaps.size()) - mHandlerMaps.resize( (int)eventType +1 ); + if(!hId) hId = generateUniqueHandlerId_unlocked(); + else if (hId > mLastHandlerId) + { + RsErr() << __PRETTY_FUNCTION__ << " Invalid handler id: " << hId + << " how did you generate it? " << std::endl; + print_stacktrace(); + return false; + } - if(!hId) - hId = generateUniqueHandlerId_unlocked(); - - mHandlerMaps[(int)eventType][hId] = multiCallback; + mHandlerMaps[static_cast(eventType)][hId] = multiCallback; return true; } @@ -126,14 +131,14 @@ bool RsEventsService::unregisterEventsHandler(RsEventsHandlerId_t hId) { RS_STACK_MUTEX(mHandlerMapMtx); - for(uint32_t i=0;i event) { - std::function)> mCallback; + uint32_t event_type_index = static_cast(event->mType); - uint32_t event_type_index = static_cast(event->mType); + if(RsEventType::__NONE >= event->mType || event->mType >= RsEventType::__MAX ) + { + RsErr() << __PRETTY_FUNCTION__ << " Invalid event type: " + << event_type_index << std::endl; + print_stacktrace(); + return; + } { - RS_STACK_MUTEX(mHandlerMapMtx); /* LOCKED AREA */ + RS_STACK_MUTEX(mHandlerMapMtx); + /* It is important to also call the callback under mutex protection to + * ensure they are not unregistered in the meanwhile. + * If a callback try to fiddle with registering/unregistering it will + * deadlock */ - if(event_type_index >= mHandlerMaps.size() || event_type_index < 1) - { - RsErr() << "Cannot handle an event of type " << event_type_index << ": out of scope!" << std::endl; - return; - } + // Call all clients that registered a callback for this event type + for(auto cbit: mHandlerMaps[event_type_index]) cbit.second(event); - // Call all clients that registered a callback for this event type - - for(auto cbit: mHandlerMaps[event_type_index]) - cbit.second(event); - - // Also call all clients that registered with NONE, meaning that they expect all events - - for(auto cbit: mHandlerMaps[static_cast(RsEventType::NONE)]) - cbit.second(event); + /* Also call all clients that registered with NONE, meaning that they + * expect all events */ + for(auto cbit: mHandlerMaps[static_cast(RsEventType::__NONE)]) + cbit.second(event); } } diff --git a/libretroshare/src/services/rseventsservice.h b/libretroshare/src/services/rseventsservice.h index 805a173a0..3a61cdd79 100644 --- a/libretroshare/src/services/rseventsservice.h +++ b/libretroshare/src/services/rseventsservice.h @@ -3,7 +3,8 @@ * * * libretroshare: retroshare core library * * * - * Copyright (C) 2019 Gioacchino Mazzurco * + * Copyright (C) 2019-2020 Gioacchino Mazzurco * + * Copyright (C) 2020 AsociaciĆ³n Civil Altermundi * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * @@ -24,6 +25,7 @@ #include #include #include +#include #include "retroshare/rsevents.h" #include "util/rsthreads.h" @@ -35,7 +37,6 @@ class RsEventsService : public: RsEventsService(): mHandlerMapMtx("RsEventsService::mHandlerMapMtx"), mLastHandlerId(1), - mHandlerMaps(static_cast(RsEventType::MAX)), mEventQueueMtx("RsEventsService::mEventQueueMtx") {} /// @see RsEvents @@ -55,10 +56,9 @@ public: /// @see RsEvents bool registerEventsHandler( - RsEventType eventType, std::function)> multiCallback, - RsEventsHandlerId_t& hId = RS_DEFAULT_STORAGE_PARAM(RsEventsHandlerId_t, 0) - ) override; + RsEventsHandlerId_t& hId = RS_DEFAULT_STORAGE_PARAM(RsEventsHandlerId_t, 0), + RsEventType eventType = RsEventType::__NONE ) override; /// @see RsEvents bool unregisterEventsHandler(RsEventsHandlerId_t hId) override; @@ -67,10 +67,12 @@ protected: RsMutex mHandlerMapMtx; RsEventsHandlerId_t mLastHandlerId; - std::vector< - std::map< - RsEventsHandlerId_t, - std::function)> > > mHandlerMaps; + std::array< + std::map< + RsEventsHandlerId_t, + std::function)> >, + static_cast(RsEventType::__MAX) + > mHandlerMaps; RsMutex mEventQueueMtx; std::deque< std::shared_ptr > mEventQueue; diff --git a/retroshare-gui/src/gui/FileTransfer/TransfersDialog.cpp b/retroshare-gui/src/gui/FileTransfer/TransfersDialog.cpp index 3c00f2122..ab5a6d9fd 100644 --- a/retroshare-gui/src/gui/FileTransfer/TransfersDialog.cpp +++ b/retroshare-gui/src/gui/FileTransfer/TransfersDialog.cpp @@ -1076,30 +1076,36 @@ TransfersDialog::TransfersDialog(QWidget *parent) // load settings processSettings(true); - int S = QFontMetricsF(font()).height(); - QString help_str = tr( - "

  File Transfer

\ -

Retroshare brings two ways of transferring files: direct transfers from your friends, and \ - distant anonymous tunnelled transfers. In addition, file transfer is multi-source and allows swarming \ - (you can be a source while downloading)

\ -

You can share files using the icon from the left side bar. \ - These files will be listed in the My Files tab. You can decide for each friend group whether they can or not see these files \ - in their Friends Files tab

\ -

The search tab reports files from your friends' file lists, and distant files that can be reached \ - anonymously using the multi-hop tunnelling system.

\ - ").arg(QString::number(2*S)).arg(QString::number(S)) ; + int S = static_cast(QFontMetricsF(font()).height()); + QString help_str = tr( + "

  " + "File Transfer

" + "

Retroshare brings two ways of transferring files: direct " + "transfers from your friends, and distant anonymous tunnelled " + "transfers. In addition, file transfer is multi-source and " + "allows swarming (you can be a source while downloading)

" + "

You can share files using the " + "" + " icon from the left side bar. These files will be listed in " + "the My Files tab. You can decide for each friend group whether" + " they can or not see these files in their Friends Files tab

" + "

The search tab reports files from your friends' file lists," + " and distant files that can be reached anonymously using the " + "multi-hop tunnelling system.

") + .arg(QString::number(2*S)).arg(QString::number(S)) ; - registerHelpButton(ui.helpButton,help_str,"TransfersDialog") ; + registerHelpButton(ui.helpButton,help_str,"TransfersDialog") ; - mEventHandlerId=0; - rsEvents->registerEventsHandler(RsEventType::FILE_TRANSFER, [this](std::shared_ptr event) { handleEvent(event); }, mEventHandlerId ); + mEventHandlerId=0; + rsEvents->registerEventsHandler( + [this](std::shared_ptr event) { handleEvent(event); }, + mEventHandlerId, RsEventType::FILE_TRANSFER ); } void TransfersDialog::handleEvent(std::shared_ptr event) { - if(event->mType != RsEventType::FILE_TRANSFER) - return; + if(event->mType != RsEventType::FILE_TRANSFER) return; const RsFileTransferEvent *fe = dynamic_cast(event.get()); if(!fe) diff --git a/retroshare-gui/src/gui/Identity/IdDialog.cpp b/retroshare-gui/src/gui/Identity/IdDialog.cpp index d02de1742..d646227f8 100644 --- a/retroshare-gui/src/gui/Identity/IdDialog.cpp +++ b/retroshare-gui/src/gui/Identity/IdDialog.cpp @@ -149,11 +149,17 @@ IdDialog::IdDialog(QWidget *parent) : MainPage(parent), ui(new Ui::IdDialog) { ui->setupUi(this); - mEventHandlerId_identity = 0; - rsEvents->registerEventsHandler(RsEventType::GXS_IDENTITY, [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, mEventHandlerId_identity ); + mEventHandlerId_identity = 0; + rsEvents->registerEventsHandler( + [this](std::shared_ptr event) + { RsQThreadUtils::postToObject([=](){ handleEvent_main_thread(event); }, this); }, + mEventHandlerId_identity, RsEventType::GXS_IDENTITY ); - mEventHandlerId_circles = 0; - rsEvents->registerEventsHandler(RsEventType::GXS_CIRCLES, [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, mEventHandlerId_circles ); + mEventHandlerId_circles = 0; + rsEvents->registerEventsHandler( + [this](std::shared_ptr event) + { RsQThreadUtils::postToObject([=](){ handleEvent_main_thread(event); }, this); }, + mEventHandlerId_circles, RsEventType::GXS_CIRCLES ); // This is used to grab the broadcast of changes from p3GxsCircles, which is discarded by the current dialog, since it expects data for p3Identity only. //mCirclesBroadcastBase = new RsGxsUpdateBroadcastBase(rsGxsCircles, this); diff --git a/retroshare-gui/src/gui/NewsFeed.cpp b/retroshare-gui/src/gui/NewsFeed.cpp index 111bc1fe8..9b85a32d1 100644 --- a/retroshare-gui/src/gui/NewsFeed.cpp +++ b/retroshare-gui/src/gui/NewsFeed.cpp @@ -67,12 +67,11 @@ * #define NEWS_DEBUG 1 ****/ -static NewsFeed *instance = NULL; +static NewsFeed* instance = nullptr; /** Constructor */ -NewsFeed::NewsFeed(QWidget *parent) : MainPage(parent), ui(new Ui::NewsFeed) -{ - mEventTypes = { +NewsFeed::NewsFeed(QWidget *parent) : MainPage(parent), ui(new Ui::NewsFeed), + mEventTypes({ RsEventType::AUTHSSL_CONNECTION_AUTENTICATION, RsEventType::PEER_CONNECTION , RsEventType::GXS_CIRCLES , @@ -80,12 +79,14 @@ NewsFeed::NewsFeed(QWidget *parent) : MainPage(parent), ui(new Ui::NewsFeed) RsEventType::GXS_FORUMS , RsEventType::GXS_POSTED , RsEventType::MAIL_STATUS - }; - - for(uint32_t i=0;iregisterEventsHandler(mEventTypes[i], [this](std::shared_ptr event) { handleEvent(event); }, mEventHandlerIds.back() ); + rsEvents->registerEventsHandler( + [this](std::shared_ptr event) { handleEvent(event); }, + mEventHandlerIds.back(), mEventTypes[i] ); } /* Invoke the Qt Designer generated object setup routine */ diff --git a/retroshare-gui/src/gui/Posted/PostedDialog.cpp b/retroshare-gui/src/gui/Posted/PostedDialog.cpp index a6fdda0bd..6c2772276 100644 --- a/retroshare-gui/src/gui/Posted/PostedDialog.cpp +++ b/retroshare-gui/src/gui/Posted/PostedDialog.cpp @@ -41,13 +41,14 @@ public: }; /** Constructor */ -PostedDialog::PostedDialog(QWidget *parent) - : GxsGroupFrameDialog(rsPosted, parent) +PostedDialog::PostedDialog(QWidget *parent): + GxsGroupFrameDialog(rsPosted, parent), mEventHandlerId(0) { - mEventHandlerId = 0; - // Needs to be asynced because this function is likely to be called by another thread! - - rsEvents->registerEventsHandler(RsEventType::GXS_POSTED, [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, mEventHandlerId ); + // Needs to be asynced because this function is likely to be called by another thread! + rsEvents->registerEventsHandler( + [this](std::shared_ptr event) + { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, + mEventHandlerId, RsEventType::GXS_POSTED ); } void PostedDialog::handleEvent_main_thread(std::shared_ptr event) diff --git a/retroshare-gui/src/gui/Posted/PostedListWidget.cpp b/retroshare-gui/src/gui/Posted/PostedListWidget.cpp index babf214e3..6c6e04158 100644 --- a/retroshare-gui/src/gui/Posted/PostedListWidget.cpp +++ b/retroshare-gui/src/gui/Posted/PostedListWidget.cpp @@ -107,9 +107,11 @@ PostedListWidget::PostedListWidget(const RsGxsGroupId &postedId, QWidget *parent processSettings(true); mEventHandlerId = 0; - // Needs to be asynced because this function is likely to be called by another thread! - - rsEvents->registerEventsHandler(RsEventType::GXS_POSTED, [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, mEventHandlerId ); + // Needs to be asynced because this function is called by another thread! + rsEvents->registerEventsHandler( + [this](std::shared_ptr event) + { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, + mEventHandlerId, RsEventType::GXS_POSTED ); /* Initialize GUI */ setGroupId(postedId); diff --git a/retroshare-gui/src/gui/common/NewFriendList.cpp b/retroshare-gui/src/gui/common/NewFriendList.cpp index 428479d84..131281285 100644 --- a/retroshare-gui/src/gui/common/NewFriendList.cpp +++ b/retroshare-gui/src/gui/common/NewFriendList.cpp @@ -177,8 +177,10 @@ NewFriendList::NewFriendList(QWidget *parent) : /* RsAutoUpdatePage(5000,parent) ui->filterLineEdit->setPlaceholderText(tr("Search")) ; ui->filterLineEdit->showFilterIcon(); - mEventHandlerId=0; // forces initialization - rsEvents->registerEventsHandler( RsEventType::PEER_CONNECTION, [this](std::shared_ptr e) { handleEvent(e); }, mEventHandlerId ); + mEventHandlerId=0; // forces initialization + rsEvents->registerEventsHandler( + [this](std::shared_ptr e) { handleEvent(e); }, + mEventHandlerId, RsEventType::PEER_CONNECTION ); mModel = new RsFriendListModel(); mProxyModel = new FriendListSortFilterProxyModel(ui->peerTreeWidget->header(),this); diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp index 70f3de04a..8e25e4ea0 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelDialog.cpp @@ -47,12 +47,14 @@ // }; /** Constructor */ -GxsChannelDialog::GxsChannelDialog(QWidget *parent) - : GxsGroupFrameDialog(rsGxsChannels, parent,true) +GxsChannelDialog::GxsChannelDialog(QWidget *parent): + GxsGroupFrameDialog(rsGxsChannels, parent, true), mEventHandlerId(0) { - mEventHandlerId = 0; - // Needs to be asynced because this function is likely to be called by another thread! - rsEvents->registerEventsHandler(RsEventType::GXS_CHANNELS, [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, mEventHandlerId ); + // Needs to be asynced because this function is called by another thread! + rsEvents->registerEventsHandler( + [this](std::shared_ptr event) + { RsQThreadUtils::postToObject([=]() { handleEvent_main_thread(event); }, this ); }, + mEventHandlerId, RsEventType::GXS_CHANNELS ); } void GxsChannelDialog::handleEvent_main_thread(std::shared_ptr event) diff --git a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.cpp b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.cpp index 2421756b8..8ca863954 100644 --- a/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.cpp +++ b/retroshare-gui/src/gui/gxschannels/GxsChannelPostsWidget.cpp @@ -130,9 +130,11 @@ GxsChannelPostsWidget::GxsChannelPostsWidget(const RsGxsGroupId &channelId, QWid setGroupId(channelId); mEventHandlerId = 0; - // Needs to be asynced because this function is likely to be called by another thread! - - rsEvents->registerEventsHandler(RsEventType::GXS_CHANNELS, [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, mEventHandlerId ); + // Needs to be asynced because this function is called by another thread! + rsEvents->registerEventsHandler( + [this](std::shared_ptr event) + { RsQThreadUtils::postToObject([=](){ handleEvent_main_thread(event); }, this ); }, + mEventHandlerId, RsEventType::GXS_CHANNELS ); } void GxsChannelPostsWidget::handleEvent_main_thread(std::shared_ptr event) diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp index 37b479e6a..b3e98f7b1 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumThreadWidget.cpp @@ -345,10 +345,12 @@ GxsForumThreadWidget::GxsForumThreadWidget(const RsGxsGroupId &forumId, QWidget ui->threadTreeWidget->enableColumnCustomize(true); #endif - mEventHandlerId = 0; - // Needs to be asynced because this function is likely to be called by another thread! - - rsEvents->registerEventsHandler(RsEventType::GXS_FORUMS, [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, mEventHandlerId ); + mEventHandlerId = 0; + // Needs to be asynced because this function is called by another thread! + rsEvents->registerEventsHandler( + [this](std::shared_ptr event) + { RsQThreadUtils::postToObject([=](){ handleEvent_main_thread(event); }, this ); }, + mEventHandlerId, RsEventType::GXS_FORUMS ); } void GxsForumThreadWidget::handleEvent_main_thread(std::shared_ptr event) diff --git a/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp b/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp index 1b0a36c6f..b0dcc0402 100644 --- a/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp +++ b/retroshare-gui/src/gui/gxsforums/GxsForumsDialog.cpp @@ -38,14 +38,15 @@ public: }; /** Constructor */ -GxsForumsDialog::GxsForumsDialog(QWidget *parent) - : GxsGroupFrameDialog(rsGxsForums, parent) +GxsForumsDialog::GxsForumsDialog(QWidget *parent) : + GxsGroupFrameDialog(rsGxsForums, parent), mEventHandlerId(0) { mCountChildMsgs = true; - mEventHandlerId = 0; - // Needs to be asynced because this function is likely to be called by another thread! - rsEvents->registerEventsHandler(RsEventType::GXS_FORUMS, [this](std::shared_ptr event) { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, mEventHandlerId ); + rsEvents->registerEventsHandler( + [this](std::shared_ptr event) + { RsQThreadUtils::postToObject( [=]() { handleEvent_main_thread(event); }, this ); }, + mEventHandlerId, RsEventType::GXS_FORUMS ); } void GxsForumsDialog::handleEvent_main_thread(std::shared_ptr event) diff --git a/retroshare-gui/src/gui/statusbar/hashingstatus.cpp b/retroshare-gui/src/gui/statusbar/hashingstatus.cpp index 997ca5f8f..563c8385a 100644 --- a/retroshare-gui/src/gui/statusbar/hashingstatus.cpp +++ b/retroshare-gui/src/gui/statusbar/hashingstatus.cpp @@ -52,8 +52,10 @@ HashingStatus::HashingStatus(QWidget *parent) hashloader->hide(); statusHashing->hide(); - mEventHandlerId=0; - rsEvents->registerEventsHandler(RsEventType::SHARED_DIRECTORIES, [this](std::shared_ptr event) { handleEvent(event); }, mEventHandlerId ); + mEventHandlerId=0; + rsEvents->registerEventsHandler( + [this](std::shared_ptr event) { handleEvent(event); }, + mEventHandlerId, RsEventType::SHARED_DIRECTORIES ); } void HashingStatus::handleEvent(std::shared_ptr event) diff --git a/retroshare-gui/src/util/RsGxsUpdateBroadcast.cpp b/retroshare-gui/src/util/RsGxsUpdateBroadcast.cpp index efd54a8e7..5128f069d 100644 --- a/retroshare-gui/src/util/RsGxsUpdateBroadcast.cpp +++ b/retroshare-gui/src/util/RsGxsUpdateBroadcast.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * util/RsGxsUpdateBroadcast.cpp * * * - * Copyright (c) 2014 Retroshare Team * + * Copyright (C) 2014-2020 Retroshare Team * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU Affero General Public License as * @@ -32,17 +32,17 @@ // now the update notify works through rsnotify and notifyqt // so the single instance per service is not really needed anymore -QMap updateBroadcastMap; +static QMap updateBroadcastMap; RsGxsUpdateBroadcast::RsGxsUpdateBroadcast(RsGxsIfaceHelper *ifaceImpl) : - QObject(NULL), mIfaceImpl(ifaceImpl) + QObject(nullptr), mIfaceImpl(ifaceImpl), mEventHandlerId(0) { - mEventHandlerId = 0; // forces initialization in registerEventsHandler() - - rsEvents->registerEventsHandler(RsEventType::GXS_CHANGES, [this](std::shared_ptr event) - { - onChangesReceived(*dynamic_cast(event.get())); - }, mEventHandlerId ); + /* No need of postToObject here as onChangesReceived just emit signals + * internally */ + rsEvents->registerEventsHandler( + [this](std::shared_ptr event) + { onChangesReceived(*dynamic_cast(event.get())); }, + mEventHandlerId, RsEventType::GXS_CHANGES ); } RsGxsUpdateBroadcast::~RsGxsUpdateBroadcast()