Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ci debug tag #208

Open
wants to merge 3 commits into
base: next
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 48 additions & 83 deletions languages/cpp/src/shared/src/Event/Event.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@
namespace FireboltSDK {
Event* Event::_singleton = nullptr;
Event::Event()
: _internalEventMap()
, _externalEventMap()
: _eventMap()
, _adminLock()
, _transport(nullptr)
{
Expand Down Expand Up @@ -88,111 +87,77 @@ namespace FireboltSDK {
}
return result;
}


/* This function combines both internal and external event maps, and iterates over them to find the specified event.
If the event is found, it iterates over its associated callbacks, updating their states and executing them if applicable.
Callbacks in the REVOKED state are removed.
*/

Firebolt::Error Event::Dispatch(const string& eventName, const WPEFramework::Core::ProxyType<WPEFramework::Core::JSONRPC::Message>& jsonResponse) /* override */
{
string response = jsonResponse->Result.Value();
std::vector<EventMap*> eventMaps = {&_internalEventMap, &_externalEventMap};

// Combine both _internalEventMap and _externalEventMap into a single loop
for (auto eventMap : eventMaps) {
_adminLock.Lock();
EventMap::iterator eventIndex = eventMap->find(eventName);
if (eventIndex != eventMap->end()) {
CallbackMap& callbacks = eventIndex->second;
for (CallbackMap::iterator callbackIndex = callbacks.begin(); callbackIndex != callbacks.end();) {
State state;
if (callbackIndex->second.state != State::REVOKED) {
callbackIndex->second.state = State::EXECUTING;
}
state = callbackIndex->second.state;
_adminLock.Unlock();
if (state == State::EXECUTING) {
callbackIndex->second.lambda(callbackIndex->first, callbackIndex->second.userdata, response);
}
_adminLock.Lock();
if (callbackIndex->second.state == State::REVOKED) {
callbackIndex = callbacks.erase(callbackIndex);
if (callbacks.empty()) {
eventMap->erase(eventIndex); // Erase from the correct eventMap
break; // No need to continue iterating if map is empty
}
} else {
callbackIndex->second.state = State::IDLE;
++callbackIndex;
_adminLock.Lock();
EventMap::iterator eventIndex = _eventMap.find(eventName);
if (eventIndex != _eventMap.end()) {
CallbackMap::iterator callbackIndex = eventIndex->second.begin();
while(callbackIndex != eventIndex->second.end()) {
State state;
if (callbackIndex->second.state != State::REVOKED) {
callbackIndex->second.state = State::EXECUTING;
}
state = callbackIndex->second.state;
_adminLock.Unlock();
if (state == State::EXECUTING) {
callbackIndex->second.lambda(callbackIndex->first, callbackIndex->second.userdata, (jsonResponse->Result.Value()));
}
_adminLock.Lock();
if (callbackIndex->second.state == State::REVOKED) {
callbackIndex = eventIndex->second.erase(callbackIndex);
if (eventIndex->second.size() == 0) {
_eventMap.erase(eventIndex);
}
} else {
callbackIndex->second.state = State::IDLE;
callbackIndex++;
}
}
_adminLock.Unlock();
}
return Firebolt::Error::None;
}
_adminLock.Unlock();

return Firebolt::Error::None;;
}

Firebolt::Error Event::Revoke(const string& eventName, void* usercb)
{
Firebolt::Error status = Firebolt::Error::None;

// Combine both _internalEventMap and _externalEventMap into a single loop
std::vector<EventMap*> eventMaps = {&_internalEventMap, &_externalEventMap};

for (auto eventMap : eventMaps) {
_adminLock.Lock(); // Lock inside the loop

// Find the eventIndex for eventName in the current eventMap
EventMap::iterator eventIndex = eventMap->find(eventName);
if (eventIndex != eventMap->end()) {
// Find the callbackIndex for usercb in the current CallbackMap
CallbackMap::iterator callbackIndex = eventIndex->second.find(usercb);
_adminLock.Lock();
EventMap::iterator eventIndex = _eventMap.begin();
if (eventIndex != _eventMap.end()) {
CallbackMap::iterator callbackIndex = eventIndex->second.find(usercb);
if (callbackIndex->second.state != State::EXECUTING) {
if (callbackIndex != eventIndex->second.end()) {
// Check if callback is not executing, then erase it
if (callbackIndex->second.state != State::EXECUTING) {
eventIndex->second.erase(callbackIndex);
} else {
// Mark the callback as revoked
callbackIndex->second.state = State::REVOKED;
}

// Check if the CallbackMap is empty after potential erasure
if (eventIndex->second.empty()) {
eventMap->erase(eventIndex);
} else {
// Set status to General error if CallbackMap is not empty
status = Firebolt::Error::General;
}
eventIndex->second.erase(callbackIndex);
}
} else {
callbackIndex->second.state = State::REVOKED;
}
if (eventIndex->second.size() == 0) {
_eventMap.erase(eventIndex);
} else {
status = Firebolt::Error::General;
}

_adminLock.Unlock(); // Unlock after processing each eventMap
}
_adminLock.Unlock();

return status;
}

void Event::Clear()
{
// Clear both _internalEventMap and _externalEventMap
std::vector<EventMap*> eventMaps = {&_internalEventMap, &_externalEventMap};

for (auto eventMap : eventMaps) {
_adminLock.Lock(); // Lock before clearing

EventMap::iterator eventIndex = eventMap->begin();
while (eventIndex != eventMap->end()) {
CallbackMap::iterator callbackIndex = eventIndex->second.begin();
while (callbackIndex != eventIndex->second.end()) {
callbackIndex = eventIndex->second.erase(callbackIndex);
}
eventIndex = eventMap->erase(eventIndex);
EventMap::iterator eventIndex = _eventMap.begin();
while (eventIndex != _eventMap.end()) {
CallbackMap::iterator callbackIndex = eventIndex->second.begin();
while (callbackIndex != eventIndex->second.end()) {
callbackIndex = eventIndex->second.erase(callbackIndex);
}

_adminLock.Unlock(); // Unlock after clearing
eventIndex = _eventMap.erase(eventIndex);
}
_adminLock.Unlock();
}

}
41 changes: 14 additions & 27 deletions languages/cpp/src/shared/src/Event/Event.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,77 +80,65 @@ namespace FireboltSDK {
}

template <typename RESULT, typename CALLBACK>
Firebolt::Error Subscribe(const string& eventName, JsonObject& jsonParameters, const CALLBACK& callback, void* usercb, const void* userdata, bool prioritize = false)
Firebolt::Error Subscribe(const string& eventName, JsonObject& jsonParameters, const CALLBACK& callback, void* usercb, const void* userdata)
{
Firebolt::Error status = Firebolt::Error::General;

if (_transport != nullptr) {
EventMap& eventMap = prioritize ? _internalEventMap : _externalEventMap;

status = Assign<RESULT, CALLBACK>(eventMap, eventName, callback, usercb, userdata);

status = Assign<RESULT, CALLBACK>(eventName, callback, usercb, userdata);
if (status == Firebolt::Error::None) {
Response response;

WPEFramework::Core::JSON::Variant Listen = true;
jsonParameters.Set(_T("listen"), Listen);
string parameters;
jsonParameters.ToString(parameters);

status = _transport->Subscribe<Response>(eventName, parameters, response, prioritize);
status = _transport->Subscribe<Response>(eventName, parameters, response);

if (status != Firebolt::Error::None) {
Revoke(eventName, usercb);
} else if (response.Listening.IsSet() && response.Listening.Value()) {
} else if ((response.Listening.IsSet() == true) &&
(response.Listening.Value() == true)) {
status = Firebolt::Error::None;
}
}
}
return status;
}

// To prioritize internal and external events and its corresponding callbacks
template <typename RESULT, typename CALLBACK>
Firebolt::Error Prioritize(const string& eventName,JsonObject& jsonParameters, const CALLBACK& callback, void* usercb, const void* userdata)
{
Firebolt::Error status = Firebolt::Error::General;
// Assuming prioritized events also need subscription via transport
status = Subscribe<RESULT, CALLBACK>(eventName, jsonParameters, callback, usercb, userdata, true);
return status;
}


Firebolt::Error Unsubscribe(const string& eventName, void* usercb);

private:
template <typename PARAMETERS, typename CALLBACK>
Firebolt::Error Assign(EventMap& eventMap, const string& eventName, const CALLBACK& callback, void* usercb, const void* userdata)
Firebolt::Error Assign(const string& eventName, const CALLBACK& callback, void* usercb, const void* userdata)
{

Firebolt::Error status = Firebolt::Error::General;
std::function<void(void* usercb, const void* userdata, void* parameters)> actualCallback = callback;
DispatchFunction implementation = [actualCallback](void* usercb, const void* userdata, const string& parameters) -> Firebolt::Error {

WPEFramework::Core::ProxyType<PARAMETERS>* inbound = new WPEFramework::Core::ProxyType<PARAMETERS>();
*inbound = WPEFramework::Core::ProxyType<PARAMETERS>::Create();
(*inbound)->FromString(parameters);
actualCallback(usercb, userdata, static_cast<void*>(inbound));
return (Firebolt::Error::None);
};
CallbackData callbackData = {implementation, userdata, State::IDLE};

_adminLock.Lock();
EventMap::iterator eventIndex = eventMap.find(eventName);
if (eventIndex != eventMap.end()) {
EventMap::iterator eventIndex = _eventMap.find(eventName);
if (eventIndex != _eventMap.end()) {
CallbackMap::iterator callbackIndex = eventIndex->second.find(usercb);

if (callbackIndex == eventIndex->second.end()) {
std::cout << "Registering new callback for event: " << eventName << std::endl;
eventIndex->second.emplace(std::piecewise_construct, std::forward_as_tuple(usercb), std::forward_as_tuple(callbackData));
status = Firebolt::Error::None;
}
} else {

CallbackMap callbackMap;
callbackMap.emplace(std::piecewise_construct, std::forward_as_tuple(usercb), std::forward_as_tuple(callbackData));
eventMap.emplace(std::piecewise_construct, std::forward_as_tuple(eventName), std::forward_as_tuple(callbackMap));
_eventMap.emplace(std::piecewise_construct, std::forward_as_tuple(eventName), std::forward_as_tuple(callbackMap));
status = Firebolt::Error::None;

}
Expand All @@ -165,9 +153,8 @@ namespace FireboltSDK {
Firebolt::Error ValidateResponse(const WPEFramework::Core::ProxyType<WPEFramework::Core::JSONRPC::Message>& jsonResponse, bool& enabled) override;
Firebolt::Error Dispatch(const string& eventName, const WPEFramework::Core::ProxyType<WPEFramework::Core::JSONRPC::Message>& jsonResponse) override;

private:
EventMap _internalEventMap;
EventMap _externalEventMap;
private:
EventMap _eventMap;
WPEFramework::Core::CriticalSection _adminLock;
Transport<WPEFramework::Core::JSON::IElement>* _transport;

Expand Down
65 changes: 17 additions & 48 deletions languages/cpp/src/shared/src/Transport/Transport.h
Original file line number Diff line number Diff line change
Expand Up @@ -565,13 +565,7 @@ namespace FireboltSDK {
void Revoke(const string& eventName)
{
_adminLock.Lock();

// Remove from internal event map
_internalEventMap.erase(eventName);

// Remove from external event map
_externalEventMap.erase(eventName);

_eventMap.erase(eventName);
_adminLock.Unlock();
}

Expand Down Expand Up @@ -646,31 +640,22 @@ namespace FireboltSDK {
}

template <typename RESPONSE>

Firebolt::Error Subscribe(const string& eventName, const string& parameters, RESPONSE& response, bool updateInternal = false)
Firebolt::Error Subscribe(const string& eventName, const string& parameters, RESPONSE& response)
{
Entry slot;
uint32_t id = _channel->Sequence();
Firebolt::Error result = Send(eventName, parameters, id);

if (result == Firebolt::Error::None) {
_adminLock.Lock();

// Choose the map based on updateInternal flag
EventMap& eventMap = updateInternal ? _internalEventMap : _externalEventMap;

// Add to the selected event map
eventMap.emplace(std::piecewise_construct,
std::forward_as_tuple(eventName),
std::forward_as_tuple(id));

_eventMap.emplace(std::piecewise_construct,
std::forward_as_tuple(eventName),
std::forward_as_tuple(~0));
_adminLock.Unlock();

result = WaitForEventResponse(id, eventName, response, _waitTime, eventMap);

result = WaitForEventResponse(id, eventName, response, _waitTime);
}

return result;
return (result);
}

Firebolt::Error Unsubscribe(const string& eventName, const string& parameters)
Expand Down Expand Up @@ -707,34 +692,18 @@ namespace FireboltSDK {

private:
friend Channel;

inline bool IsEvent(const uint32_t id, string& eventName)
{
_adminLock.Lock();

bool eventExist = false;

// List of maps to search
std::vector<EventMap*> maps = {&_internalEventMap, &_externalEventMap};

// Loop through each map
for (const auto* map : maps) {
for (const auto& event : *map) {
if (event.second == id) {
eventName = event.first;
eventExist = true;
break; // Break the inner loop
}
}
if (eventExist) {
break; // Break the outer loop
for (auto& event : _eventMap) {
if (event.second == id) {
eventName = event.first;
break;
}
}

_adminLock.Unlock();
return eventExist;
return (eventName.empty() != true);
}

uint64_t Timed()
{
uint64_t result = ~0;
Expand Down Expand Up @@ -833,7 +802,8 @@ namespace FireboltSDK {

return (result);
}



template <typename PARAMETERS>
Firebolt::Error Send(const string& method, const PARAMETERS& parameters, const uint32_t& id)
{
Expand Down Expand Up @@ -874,7 +844,7 @@ namespace FireboltSDK {

static constexpr uint32_t WAITSLOT_TIME = 100;
template <typename RESPONSE>
Firebolt::Error WaitForEventResponse(const uint32_t& id, const string& eventName, RESPONSE& response, const uint32_t waitTime, EventMap& _eventMap)
Firebolt::Error WaitForEventResponse(const uint32_t& id, const string& eventName, RESPONSE& response, const uint32_t waitTime)
{
Firebolt::Error result = Firebolt::Error::Timedout;
_adminLock.Lock();
Expand Down Expand Up @@ -1003,12 +973,11 @@ namespace FireboltSDK {
WPEFramework::Core::ProxyType<Channel> _channel;
IEventHandler* _eventHandler;
PendingMap _pendingQueue;
EventMap _internalEventMap;
EventMap _externalEventMap;
EventMap _eventMap;
uint64_t _scheduledTime;
uint32_t _waitTime;
Listener _listener;
bool _connected;
Firebolt::Error _status;
};
}
}
Loading
Loading