Skip to content
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
1 change: 1 addition & 0 deletions syncd/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ libSyncd_a_SOURCES = \
SaiObj.cpp \
SaiSwitch.cpp \
SaiSwitchInterface.cpp \
SelectablesTracker.cpp \
ServiceMethodTable.cpp \
SingleReiniter.cpp \
SwitchNotifications.cpp \
Expand Down
114 changes: 114 additions & 0 deletions syncd/SelectablesTracker.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
#include "SelectablesTracker.h"

#include "swss/logger.h"

using namespace syncd;

bool SelectablesTracker::addSelectableToTracker(
_In_ swss::Selectable *selectable,
_In_ std::shared_ptr<SelectableEventHandler> eventHandler)
{
SWSS_LOG_ENTER();

std::lock_guard<std::mutex> lock(m_mutex);

if (selectable == nullptr)
{
SWSS_LOG_ERROR("Invalid Selectable:Selectable is NULL.");

return false;
}

if (eventHandler == nullptr)
{
SWSS_LOG_ERROR("Event handler for Selectable with fd: %d is NULL.",
selectable->getFd());

return false;
}

int fd = selectable->getFd();

if (m_selectableFdToEventHandlerMap.count(fd) != 0)
{
SWSS_LOG_ERROR("Selectable with fd %d is already in use.", fd);

return false;
}

SWSS_LOG_INFO("Adding the Selectable with fd: %d.", fd);
m_selectableFdToEventHandlerMap[fd] = eventHandler;

return true;
}

bool SelectablesTracker::removeSelectableFromTracker(
_In_ swss::Selectable *selectable)
{
SWSS_LOG_ENTER();

std::lock_guard<std::mutex> lock(m_mutex);

if (selectable == nullptr)
{
SWSS_LOG_ERROR("Invalid Selectable:Selectable is NULL.");

return false;
}

int fd = selectable->getFd();

SWSS_LOG_INFO("Removing the Selectable with fd: %d.", fd);

if (m_selectableFdToEventHandlerMap.erase(fd) == 0)
{
SWSS_LOG_ERROR("Selectable with fd %d is not present in the map!", fd);

return false;
}

return true;
}

bool SelectablesTracker::selectableIsTracked(
_In_ swss::Selectable *selectable) const
{
SWSS_LOG_ENTER();

std::lock_guard<std::mutex> lock(m_mutex);

if ((selectable == nullptr) ||
(m_selectableFdToEventHandlerMap.count(selectable->getFd()) == 0))
{
return false;
}

return true;
}

std::shared_ptr<SelectableEventHandler> SelectablesTracker::getEventHandlerForSelectable(
_In_ swss::Selectable *selectable) const
{
SWSS_LOG_ENTER();

std::lock_guard<std::mutex> lock(m_mutex);

if (selectable == nullptr)
{
SWSS_LOG_ERROR("Invalid Selectable:Selectable is NULL.");

return nullptr;
}

int fd = selectable->getFd();
auto it = m_selectableFdToEventHandlerMap.find(fd);

if (it == m_selectableFdToEventHandlerMap.end())
{
SWSS_LOG_ERROR("Selectable with fd %d is not present in the map!", fd);

return nullptr;
}

return it->second;
}
59 changes: 59 additions & 0 deletions syncd/SelectablesTracker.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#pragma once

#include <memory>
#include <mutex>
#include <unordered_map>

#include "SelectableEventHandler.h"
#include "swss/sal.h"
#include "swss/selectable.h"
#include "swss/selectabletimer.h"

namespace syncd
{
// This class keeps track of Selectable being used by an entity and their
// corresponding EventHandler objects.
class SelectablesTracker
{
private:

// Not copyable or movable.
SelectablesTracker(const SelectablesTracker &) = delete;
SelectablesTracker(SelectablesTracker &&) = delete;
SelectablesTracker &operator=(const SelectablesTracker &) = delete;
SelectablesTracker &operator=(SelectablesTracker &&) = delete;

public:

SelectablesTracker() = default;

virtual ~SelectablesTracker() = default;

// Adds the mapping of Selectable and its corresponding EventHandler object.
virtual bool addSelectableToTracker(
_In_ swss::Selectable *selectable,
_In_ std::shared_ptr<SelectableEventHandler> eventHandler);

// Removes a Selectable from the map.
virtual bool removeSelectableFromTracker(
_In_ swss::Selectable *selectable);

// Checks if Selectable is present in the tracker map.
virtual bool selectableIsTracked(
_In_ swss::Selectable *selectable) const;

// Gets the EventHandler for a Selectable.
virtual std::shared_ptr<SelectableEventHandler> getEventHandlerForSelectable(
_In_ swss::Selectable *selectable) const;

private:

using SelectableFdToEventHandlerMap =
std::unordered_map<int, std::shared_ptr<SelectableEventHandler>>;

mutable std::mutex m_mutex;

SelectableFdToEventHandlerMap m_selectableFdToEventHandlerMap;
};

} // namespace syncd
1 change: 1 addition & 0 deletions tests/aspell.en.pws
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ config
const
CONST
consts
copyable
counterName
countOnly
cout
Expand Down
1 change: 1 addition & 0 deletions unittest/syncd/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ tests_SOURCES = main.cpp \
TestNotificationHandler.cpp \
TestMdioIpcServer.cpp \
TestPortStateChangeHandler.cpp \
TestSelectablesTracker.cpp \
TestWorkaround.cpp \
TestSyncd.cpp \
TestVendorSai.cpp \
Expand Down
31 changes: 31 additions & 0 deletions unittest/syncd/MockSelectablesTracker.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#pragma once

#include <memory>

#include "SelectablesTracker.h"
#include "gmock/gmock.h"

namespace syncd
{

class MockSelectablesTracker : public SelectablesTracker
{
public:

MockSelectablesTracker() : SelectablesTracker() {}

~MockSelectablesTracker() override {}

MOCK_METHOD2(addSelectableToTracker, bool(swss::Selectable *selectable,
std::shared_ptr<SelectableEventHandler> eventHandler));

MOCK_METHOD1(removeSelectableFromTracker,
bool(swss::Selectable *selectable));

MOCK_CONST_METHOD1(selectableIsTracked,
bool(swss::Selectable *selectable));

MOCK_CONST_METHOD1(getEventHandlerForSelectable,
std::shared_ptr<SelectableEventHandler>(swss::Selectable *selectable));
};
} // namespace syncd
Loading
Loading