mirror of
https://github.com/RetroShare/RetroShare.git
synced 2025-02-07 18:45:35 -05:00
9b8d0afacb
In Restbed one is not supposed to call session->yield outside the threads controlled by Restbed. RetroShare JSON API async call were calling session->yield from threads controlled by RetroShare all the times, this caused crashes in some cases, like when the JSON API socket timed out concurrently with the session->yield call . To solve this problem session->yield from async calls are now wrapped insto mService->schedule to ensure they are executed on the right thread (aka one of the threads controlled by Restbed). While solving this issue I realized also that passing RsEvents as const references around was quite limiting in cases where the event need to be finally handled in another thread, in that case passing by const reference the RsEvent needed to be copied by value into the thread that process it, in this copy by value process the information of which was the original specific type is lost, and then only the data and methods from general RsEvents are available, unless the handler does tricky stuff with type coercion etc. To solve this limitation pass the events as std::shared_ptr<const RsEvent> seems the safer and more elegant solution.
82 lines
3.2 KiB
C++
82 lines
3.2 KiB
C++
/*******************************************************************************
|
|
* Retroshare events service *
|
|
* *
|
|
* libretroshare: retroshare core library *
|
|
* *
|
|
* Copyright (C) 2019 Gioacchino Mazzurco <gio@eigenlab.org> *
|
|
* *
|
|
* This program is free software: you can redistribute it and/or modify *
|
|
* it under the terms of the GNU Lesser General Public License as *
|
|
* published by the Free Software Foundation, either version 3 of the *
|
|
* License, or (at your option) any later version. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU Lesser General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU Lesser General Public License *
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>. *
|
|
* *
|
|
*******************************************************************************/
|
|
#pragma once
|
|
|
|
#include <memory>
|
|
#include <cstdint>
|
|
#include <deque>
|
|
|
|
#include "retroshare/rsevents.h"
|
|
#include "util/rsthreads.h"
|
|
#include "util/rsdebug.h"
|
|
|
|
class RsEventsService :
|
|
public RsEvents, public RsTickingThread
|
|
{
|
|
public:
|
|
RsEventsService():
|
|
mHandlerMapMtx("RsEventsService::mHandlerMapMtx"), mLastHandlerId(1),
|
|
mEventQueueMtx("RsEventsService::mEventQueueMtx") {}
|
|
|
|
/// @see RsEvents
|
|
bool postEvent(
|
|
std::shared_ptr<const RsEvent> event,
|
|
std::string& errorMessage = RS_DEFAULT_STORAGE_PARAM(std::string)
|
|
) override;
|
|
|
|
/// @see RsEvents
|
|
bool sendEvent(
|
|
std::shared_ptr<const RsEvent> event,
|
|
std::string& errorMessage = RS_DEFAULT_STORAGE_PARAM(std::string)
|
|
) override;
|
|
|
|
/// @see RsEvents
|
|
RsEventsHandlerId_t generateUniqueHandlerId() override;
|
|
|
|
/// @see RsEvents
|
|
bool registerEventsHandler(
|
|
std::function<void(std::shared_ptr<const RsEvent>)> multiCallback,
|
|
RsEventsHandlerId_t& hId = RS_DEFAULT_STORAGE_PARAM(RsEventsHandlerId_t, 0)
|
|
) override;
|
|
|
|
/// @see RsEvents
|
|
bool unregisterEventsHandler(RsEventsHandlerId_t hId) override;
|
|
|
|
protected:
|
|
RsMutex mHandlerMapMtx;
|
|
RsEventsHandlerId_t mLastHandlerId;
|
|
std::map<
|
|
RsEventsHandlerId_t,
|
|
std::function<void(std::shared_ptr<const RsEvent>)> > mHandlerMap;
|
|
|
|
RsMutex mEventQueueMtx;
|
|
std::deque< std::shared_ptr<const RsEvent> > mEventQueue;
|
|
|
|
/// @see RsTickingThread
|
|
void data_tick() override;
|
|
|
|
void handleEvent(std::shared_ptr<const RsEvent> event);
|
|
RsEventsHandlerId_t generateUniqueHandlerId_unlocked();
|
|
|
|
RS_SET_CONTEXT_DEBUG_LEVEL(3)
|
|
};
|