-
Notifications
You must be signed in to change notification settings - Fork 392
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
iox-#27 Add BaseServer for typed and untyped API
- Loading branch information
1 parent
6dcb9ef
commit 601edf6
Showing
3 changed files
with
362 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
155 changes: 155 additions & 0 deletions
155
iceoryx_posh/include/iceoryx_posh/internal/popo/base_server.hpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. | ||
// Copyright (c) 2020 - 2022 by Apex.AI Inc. All rights reserved. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#ifndef IOX_POSH_POPO_BASE_SERVER_HPP | ||
#define IOX_POSH_POPO_BASE_SERVER_HPP | ||
|
||
#include "iceoryx_hoofs/cxx/expected.hpp" | ||
#include "iceoryx_posh/capro/service_description.hpp" | ||
#include "iceoryx_posh/internal/popo/ports/server_port_user.hpp" | ||
#include "iceoryx_posh/popo/server_options.hpp" | ||
#include "iceoryx_posh/popo/trigger_handle.hpp" | ||
#include "iceoryx_posh/runtime/posh_runtime.hpp" | ||
|
||
namespace iox | ||
{ | ||
namespace popo | ||
{ | ||
using uid_t = UniquePortId; | ||
|
||
/// @brief The BaseServer class contains the common implementation for the different server | ||
/// @param[in] Port type of the underlying port, required for testing specializations. | ||
template <typename Port = ServerPortUser> | ||
class BaseServer | ||
{ | ||
public: | ||
virtual ~BaseServer() noexcept; | ||
|
||
BaseServer(const BaseServer& other) = delete; | ||
BaseServer& operator=(const BaseServer&) = delete; | ||
BaseServer(BaseServer&& rhs) = delete; | ||
BaseServer& operator=(BaseServer&& rhs) = delete; | ||
|
||
/// | ||
/// @brief Get the UID of the server. | ||
/// @return The server's UID. | ||
/// | ||
uid_t getUid() const noexcept; | ||
|
||
/// | ||
/// @brief Get the service description of the server. | ||
/// @return The service description. | ||
/// | ||
capro::ServiceDescription getServiceDescription() const noexcept; | ||
|
||
/// | ||
/// @brief Offer the service to be connected to. | ||
/// | ||
void offer() noexcept; | ||
|
||
/// | ||
/// @brief Stop offering the service. | ||
/// | ||
void stopOffer() noexcept; | ||
|
||
/// | ||
/// @brief Check if the server is offering. | ||
/// @return True if service is currently being offered. | ||
/// | ||
bool isOffered() const noexcept; | ||
|
||
/// | ||
/// @brief Check if the server has clients | ||
/// @return True if currently has subscribers to the service. | ||
/// | ||
bool hasClients() const noexcept; | ||
|
||
/// | ||
/// @brief Check if requests are available. | ||
/// @return True if requests are available. | ||
/// | ||
bool hasRequests() const noexcept; | ||
|
||
/// | ||
/// @brief Check if requests has been missed since the last call of this method. | ||
/// @return True if requests has been missed. | ||
/// @details Requests may be missed due to overflowing receive queue. | ||
/// | ||
bool hasMissedRequests() noexcept; | ||
|
||
/// @brief Releases any unread queued requests. | ||
void releaseQueuedRequests() noexcept; | ||
|
||
friend class NotificationAttorney; | ||
|
||
protected: | ||
using SelfType = BaseServer<Port>; | ||
using PortType = Port; | ||
|
||
BaseServer() noexcept = default; // Required for testing. | ||
BaseServer(const capro::ServiceDescription& service, const ServerOptions& serverOptions) noexcept; | ||
|
||
/// @brief Only usable by the WaitSet, not for public use. Invalidates the internal triggerHandle. | ||
/// @param[in] uniqueTriggerId the id of the corresponding trigger | ||
void invalidateTrigger(const uint64_t uniqueTriggerId) noexcept; | ||
|
||
/// @brief Only usable by the WaitSet, not for public use. Attaches the triggerHandle to the internal trigger. | ||
/// @param[in] triggerHandle rvalue reference to the triggerHandle. This class takes the ownership of that handle. | ||
/// @param[in] serverState the state which should be attached | ||
void enableState(iox::popo::TriggerHandle&& triggerHandle, const ServerState serverState) noexcept; | ||
|
||
/// @brief Only usable by the WaitSet, not for public use. Returns method pointer to the event corresponding | ||
/// hasTriggered method callback | ||
/// @param[in] serverState the state to which the hasTriggeredCallback is required | ||
WaitSetIsConditionSatisfiedCallback | ||
getCallbackForIsStateConditionSatisfied(const ServerState serverState) const noexcept; | ||
|
||
/// @brief Only usable by the WaitSet, not for public use. Resets the internal triggerHandle | ||
/// @param[in] serverState the state which should be detached | ||
void disableState(const ServerState serverState) noexcept; | ||
|
||
/// @brief Only usable by the WaitSet, not for public use. Attaches the triggerHandle to the internal trigger. | ||
/// @param[in] triggerHandle rvalue reference to the triggerHandle. This class takes the ownership of that handle. | ||
/// @param[in] serverEvent the event which should be attached | ||
void enableEvent(iox::popo::TriggerHandle&& triggerHandle, const ServerEvent serverEvent) noexcept; | ||
|
||
/// @brief Only usable by the WaitSet, not for public use. Resets the internal triggerHandle | ||
/// @param[in] serverEvent the event which should be detached | ||
void disableEvent(const ServerEvent serverEvent) noexcept; | ||
|
||
/// | ||
/// @brief port | ||
/// @return const accessor of the underlying port | ||
/// | ||
const Port& port() const noexcept; | ||
|
||
/// | ||
/// @brief port | ||
/// @return accessor of the underlying port | ||
/// | ||
Port& port() noexcept; | ||
|
||
Port m_port{nullptr}; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes) | ||
TriggerHandle m_trigger; // NOLINT(cppcoreguidelines-non-private-member-variables-in-classes) | ||
}; | ||
|
||
} // namespace popo | ||
} // namespace iox | ||
|
||
#include "iceoryx_posh/internal/popo/base_server.inl" | ||
|
||
#endif // IOX_POSH_POPO_BASE_SERVER_HPP |
205 changes: 205 additions & 0 deletions
205
iceoryx_posh/include/iceoryx_posh/internal/popo/base_server.inl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,205 @@ | ||
// Copyright (c) 2020 by Robert Bosch GmbH. All rights reserved. | ||
// Copyright (c) 2020 - 2022 by Apex.AI Inc. All rights reserved. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#ifndef IOX_POSH_POPO_BASE_SERVER_INL | ||
#define IOX_POSH_POPO_BASE_SERVER_INL | ||
|
||
#include "iceoryx_posh/internal/popo/base_server.hpp" | ||
|
||
namespace iox | ||
{ | ||
namespace popo | ||
{ | ||
template <typename Port> | ||
inline BaseServer<Port>::BaseServer(const capro::ServiceDescription& service, | ||
const ServerOptions& serverOptions) noexcept | ||
: m_port(*iox::runtime::PoshRuntime::getInstance().getMiddlewareServer(service, serverOptions)) | ||
{ | ||
} | ||
|
||
template <typename Port> | ||
inline BaseServer<Port>::~BaseServer() noexcept | ||
{ | ||
m_port.destroy(); | ||
} | ||
|
||
template <typename Port> | ||
inline uid_t BaseServer<Port>::getUid() const noexcept | ||
{ | ||
return m_port.getUniqueID(); | ||
} | ||
|
||
template <typename Port> | ||
inline capro::ServiceDescription BaseServer<Port>::getServiceDescription() const noexcept | ||
{ | ||
return m_port.getCaProServiceDescription(); | ||
} | ||
|
||
template <typename Port> | ||
inline void BaseServer<Port>::offer() noexcept | ||
{ | ||
m_port.offer(); | ||
} | ||
|
||
template <typename Port> | ||
inline void BaseServer<Port>::stopOffer() noexcept | ||
{ | ||
m_port.stopOffer(); | ||
} | ||
|
||
template <typename Port> | ||
inline bool BaseServer<Port>::isOffered() const noexcept | ||
{ | ||
return m_port.isOffered(); | ||
} | ||
|
||
template <typename Port> | ||
inline bool BaseServer<Port>::hasClients() const noexcept | ||
{ | ||
return m_port.hasClients(); | ||
} | ||
|
||
template <typename Port> | ||
inline bool BaseServer<Port>::hasRequests() const noexcept | ||
{ | ||
return m_port.hasNewRequests(); | ||
} | ||
|
||
template <typename Port> | ||
inline bool BaseServer<Port>::hasMissedRequests() noexcept | ||
{ | ||
return m_port.hasLostRequestsSinceLastCall(); | ||
} | ||
|
||
template <typename Port> | ||
inline void BaseServer<Port>::releaseQueuedRequests() noexcept | ||
{ | ||
m_port.releaseQueuedRequests(); | ||
} | ||
|
||
template <typename Port> | ||
inline void BaseServer<Port>::invalidateTrigger(const uint64_t uniqueTriggerId) noexcept | ||
{ | ||
if (m_trigger.getUniqueId() == uniqueTriggerId) | ||
{ | ||
m_port.unsetConditionVariable(); | ||
m_trigger.invalidate(); | ||
} | ||
} | ||
|
||
template <typename Port> | ||
inline void BaseServer<Port>::enableState(iox::popo::TriggerHandle&& triggerHandle, | ||
const ServerState serverState) noexcept | ||
{ | ||
switch (serverState) | ||
{ | ||
case ServerState::HAS_REQUEST: | ||
if (m_trigger) | ||
{ | ||
LogWarn() | ||
<< "The server is already attached with either the ServerState::HAS_REQUEST or " | ||
"ServerEvent::REQUEST_RECEIVED to a WaitSet/Listener. Detaching it from previous one and " | ||
"attaching it to the new one with ServerState::HAS_REQUEST. Best practice is to call detach first."; | ||
|
||
errorHandler( | ||
Error::kPOPO__BASE_SERVER_OVERRIDING_WITH_STATE_SINCE_HAS_REQUEST_OR_REQUEST_RECEIVED_ALREADY_ATTACHED, | ||
nullptr, | ||
ErrorLevel::MODERATE); | ||
} | ||
m_trigger = std::move(triggerHandle); | ||
m_port.setConditionVariable(*m_trigger.getConditionVariableData(), m_trigger.getUniqueId()); | ||
break; | ||
} | ||
} | ||
|
||
template <typename Port> | ||
inline WaitSetIsConditionSatisfiedCallback | ||
BaseServer<Port>::getCallbackForIsStateConditionSatisfied(const ServerState serverState) const noexcept | ||
{ | ||
switch (serverState) | ||
{ | ||
case ServerState::HAS_REQUEST: | ||
return {*this, &SelfType::hasRequests}; | ||
} | ||
return {}; | ||
} | ||
|
||
template <typename Port> | ||
inline void BaseServer<Port>::disableState(const ServerState serverState) noexcept | ||
{ | ||
switch (serverState) | ||
{ | ||
case ServerState::HAS_REQUEST: | ||
m_trigger.reset(); | ||
m_port.unsetConditionVariable(); | ||
break; | ||
} | ||
} | ||
|
||
template <typename Port> | ||
inline void BaseServer<Port>::enableEvent(iox::popo::TriggerHandle&& triggerHandle, | ||
const ServerEvent serverEvent) noexcept | ||
{ | ||
switch (serverEvent) | ||
{ | ||
case ServerEvent::REQUEST_RECEIVED: | ||
if (m_trigger) | ||
{ | ||
LogWarn() | ||
<< "The server is already attached with either the ServerState::HAS_REQUEST or " | ||
"ServerEvent::REQUEST_RECEIVED to a WaitSet/Listener. Detaching it from previous one and " | ||
"attaching it to the new one with ServerEvent::REQUEST_RECEIVED. Best practice is to call detach " | ||
"first."; | ||
errorHandler( | ||
Error::kPOPO__BASE_SERVER_OVERRIDING_WITH_EVENT_SINCE_HAS_REQUEST_OR_REQUEST_RECEIVED_ALREADY_ATTACHED, | ||
nullptr, | ||
ErrorLevel::MODERATE); | ||
} | ||
m_trigger = std::move(triggerHandle); | ||
m_port.setConditionVariable(*m_trigger.getConditionVariableData(), m_trigger.getUniqueId()); | ||
break; | ||
} | ||
} | ||
|
||
template <typename Port> | ||
inline void BaseServer<Port>::disableEvent(const ServerEvent serverEvent) noexcept | ||
{ | ||
switch (serverEvent) | ||
{ | ||
case ServerEvent::REQUEST_RECEIVED: | ||
m_trigger.reset(); | ||
m_port.unsetConditionVariable(); | ||
break; | ||
} | ||
} | ||
|
||
template <typename Port> | ||
const Port& BaseServer<Port>::port() const noexcept | ||
{ | ||
return m_port; | ||
} | ||
|
||
template <typename Port> | ||
Port& BaseServer<Port>::port() noexcept | ||
{ | ||
return m_port; | ||
} | ||
|
||
} // namespace popo | ||
} // namespace iox | ||
|
||
#endif // IOX_POSH_POPO_BASE_SERVER_INL |