Skip to content

Commit

Permalink
iox-eclipse-iceoryx#261 Replace std::terminate with Expects in iceory…
Browse files Browse the repository at this point in the history
…x_utils

Signed-off-by: Simon Hoinkis <simon.hoinkis@apex.ai>
  • Loading branch information
mossmaurice committed Apr 21, 2021
1 parent 4ce5310 commit 220b8d2
Show file tree
Hide file tree
Showing 20 changed files with 107 additions and 182 deletions.
4 changes: 2 additions & 2 deletions doc/design/error-handling.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ RouDi may continue but applications may be compromised or the functionality redu
A message queue is overflowing and messages are lost. RouDi can continue but lost data may affect applications.

#### FATAL
RouDi cannot continue and will shut down. Leads to an error log entry (``LogFatal``), assert and calls ``std::terminate``, terminating execution in debug and release mode.
RouDi cannot continue and will shut down. Leads to an error log entry (``LogFatal``), assert and calls ``std::terminate``, terminating execution in debug and release mode.
Before calling terminate, a callback is invoked (if configured), which can execute specific error handling code (e.g. call a 3rd party error handler).
The handler is not required to return here (since this may not be always possible or reasonable). The reporting code should still try to proceed to a safe state if possible in order to improve testability in case of such errors.

Expand Down Expand Up @@ -135,7 +135,7 @@ All the methods presented (``cxx::expected``, ``Expects`` and ``Ensures`` and th

Error logging is currently done by calls to ``std::cerr``. In the future those might be redirected to the logger.

The error handler cannot be used in utils.
The error handler cannot be used in utils.

Whether it is appropriate to use ``cxx::expected`` even if STL compatibility is broken by doing so depends on the circumstances and needs to be decided on a case-by-case basis. If the function has no STL counterpart ``cxx::expected`` can be used freely to communicate potential failure to the caller.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

#include "iceoryx_posh/internal/roudi/roudi.hpp"
#include "iceoryx_posh/roudi/iceoryx_roudi_components.hpp"
#include "iceoryx_utils/cxx/helplets.hpp"
#include "iceoryx_utils/cxx/make_scoped_static.hpp"
#include "iceoryx_utils/cxx/optional.hpp"

namespace iox
Expand Down
2 changes: 0 additions & 2 deletions iceoryx_utils/include/iceoryx_utils/cxx/algorithm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
#ifndef IOX_UTILS_CXX_ALGORITHM_HPP
#define IOX_UTILS_CXX_ALGORITHM_HPP

#include "iceoryx_utils/cxx/vector.hpp"

#include <cstdint>
#include <type_traits>

Expand Down
2 changes: 2 additions & 0 deletions iceoryx_utils/include/iceoryx_utils/cxx/forward_list.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
#ifndef IOX_UTILS_CXX_FORWARD_LIST_HPP
#define IOX_UTILS_CXX_FORWARD_LIST_HPP

#include "iceoryx_utils/cxx/helplets.hpp"

#include <cstdint>
#include <iostream>

Expand Down
1 change: 1 addition & 0 deletions iceoryx_utils/include/iceoryx_utils/cxx/function_ref.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#ifndef IOX_UTILS_CXX_FUNCTION_REF_HPP
#define IOX_UTILS_CXX_FUNCTION_REF_HPP

#include "iceoryx_utils/cxx/helplets.hpp"
#include "iceoryx_utils/cxx/type_traits.hpp"

#include <cstddef>
Expand Down
1 change: 1 addition & 0 deletions iceoryx_utils/include/iceoryx_utils/cxx/generic_raii.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ namespace iox
{
namespace cxx
{

/// @brief The GenericRAII class is a simple helper class to apply the C++ RAII
/// idiom quickly. You set 2 functions, one which is called in the
/// constructor and another function is called in the destructor
Expand Down
18 changes: 2 additions & 16 deletions iceoryx_utils/include/iceoryx_utils/cxx/helplets.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,14 @@
#ifndef IOX_UTILS_CXX_HELPLETS_HPP
#define IOX_UTILS_CXX_HELPLETS_HPP

#include "iceoryx_utils/cxx/generic_raii.hpp"
#include "iceoryx_utils/platform/platform_correction.hpp"

#include <assert.h>
#include <cstdint>
#include <iostream>
#include <limits>
#include <type_traits>

#include "iceoryx_utils/platform/platform_correction.hpp"

namespace iox
{
namespace cxx
Expand Down Expand Up @@ -181,19 +180,6 @@ constexpr size_t maxSize()
return sizeof(T) > maxSize<Args...>() ? sizeof(T) : maxSize<Args...>();
}

/// @todo better name
/// create a GenericRAII object to cleanup a static optional object at the end of the scope
/// @param [in] T memory container which has emplace(...) and reset
/// @param [in] CTorArgs ctor types for the object to construct
/// @param [in] memory is a reference to a memory container, e.g. cxx::optional
/// @param [in] ctorArgs ctor arguments for the object to construct
/// @return cxx::GenericRAII
template <typename T, typename... CTorArgs>
GenericRAII makeScopedStatic(T& memory, CTorArgs&&... ctorArgs)
{
memory.emplace(std::forward<CTorArgs>(ctorArgs)...);
return GenericRAII([] {}, [&memory] { memory.reset(); });
}
/// Convert Enum class type to string
template <typename T, typename Enumeration>
const char* convertEnumToString(T port, const Enumeration source)
Expand Down
2 changes: 2 additions & 0 deletions iceoryx_utils/include/iceoryx_utils/cxx/list.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
#ifndef IOX_UTILS_CXX_LIST_HPP
#define IOX_UTILS_CXX_LIST_HPP

#include "iceoryx_utils/cxx/helplets.hpp"

#include <cstdint>
#include <iostream>

Expand Down
42 changes: 42 additions & 0 deletions iceoryx_utils/include/iceoryx_utils/cxx/make_scoped_static.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright (c) 2019 by Robert Bosch GmbH. All rights reserved.
// Copyright (c) 2021 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_UTILS_CXX_MAKE_SCOPED_STATIC_HPP
#define IOX_UTILS_CXX_MAKE_SCOPED_STATIC_HPP

#include "iceoryx_utils/cxx/generic_raii.hpp"

namespace iox
{
namespace cxx
{
/// @todo better name
/// create a GenericRAII object to cleanup a static optional object at the end of the scope
/// @param [in] T memory container which has emplace(...) and reset
/// @param [in] CTorArgs ctor types for the object to construct
/// @param [in] memory is a reference to a memory container, e.g. cxx::optional
/// @param [in] ctorArgs ctor arguments for the object to construct
/// @return cxx::GenericRAII
template <typename T, typename... CTorArgs>
GenericRAII makeScopedStatic(T& memory, CTorArgs&&... ctorArgs)
{
memory.emplace(std::forward<CTorArgs>(ctorArgs)...);
return GenericRAII([] {}, [&memory] { memory.reset(); });
}
} // namespace cxx
} // namespace iox

#endif // IOX_UTILS_CXX_MAKE_SCOPED_STATIC_HPP
2 changes: 2 additions & 0 deletions iceoryx_utils/include/iceoryx_utils/cxx/vector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
#ifndef IOX_UTILS_CXX_VECTOR_HPP
#define IOX_UTILS_CXX_VECTOR_HPP

#include "iceoryx_utils/cxx/helplets.hpp"

#include <algorithm>
#include <cstdint>
#include <cstdio>
Expand Down
49 changes: 9 additions & 40 deletions iceoryx_utils/include/iceoryx_utils/internal/cxx/forward_list.inl
Original file line number Diff line number Diff line change
Expand Up @@ -324,15 +324,15 @@ template <typename T, uint64_t Capacity>
inline T& forward_list<T, Capacity>::front() noexcept
{
auto iter = begin();
handleInvalidElement(iter.m_iterListNodeIdx);
IOX_DISCARD_RESULT(handleInvalidElement(iter.m_iterListNodeIdx));
return *iter;
}

template <typename T, uint64_t Capacity>
inline const T& forward_list<T, Capacity>::front() const noexcept
{
auto citer = cbegin();
handleInvalidElement(citer.m_iterListNodeIdx);
IOX_DISCARD_RESULT(handleInvalidElement(citer.m_iterListNodeIdx));
return *citer;
}

Expand Down Expand Up @@ -545,11 +545,7 @@ inline void forward_list<T, Capacity>::setNextIdx(const size_type idx, const siz
template <typename T, uint64_t Capacity>
inline const T* forward_list<T, Capacity>::getDataPtrFromIdx(const size_type idx) const noexcept
{
if (handleInvalidElement(idx))
{
// error handling in call to handleInvalidElement()
return nullptr;
}
IOX_DISCARD_RESULT(handleInvalidElement(idx));

return &(reinterpret_cast<const T*>(&m_data)[idx]);
}
Expand Down Expand Up @@ -585,51 +581,24 @@ template <typename T, uint64_t Capacity>
inline bool forward_list<T, Capacity>::handleInvalidElement(const size_type idx) const noexcept
{
// freeList / invalid elements will have the 'invalidElement' flag set to true
if (isValidElementIdx(idx))
{
return false;
}
else
{
errorMessage(__PRETTY_FUNCTION__, " invalid list element ");
std::terminate();

return true;
}
cxx::Expects(isValidElementIdx(idx) && "Invalid list element");
return false;
}

template <typename T, uint64_t Capacity>
inline bool forward_list<T, Capacity>::handleInvalidIterator(const const_iterator& iter) const noexcept
{
// iterator's member m_iterListNodeIdx and nextIndex are not checked here to be <= END_INDEX as this
// should (can) never happen though normal list operations.
if (!isInvalidElement(iter.m_iterListNodeIdx))
{
return false;
}
else
{
errorMessage(__PRETTY_FUNCTION__, " invalidated iterator ");
std::terminate();

return true;
}
cxx::Expects(!isInvalidElement(iter.m_iterListNodeIdx) && "invalidated iterator");
return false;
}

template <typename T, uint64_t Capacity>
inline bool forward_list<T, Capacity>::isInvalidIterOrDifferentLists(const const_iterator& iter) const noexcept
{
if (this != iter.m_list)
{
errorMessage(__PRETTY_FUNCTION__, " iterator of other list can't be used ");
std::terminate();

return true;
}
else
{
return handleInvalidIterator(iter);
}
cxx::Expects(this == iter.m_list && "iterator of other list can't be used");
return handleInvalidIterator(iter);
}

template <typename T, uint64_t Capacity>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,8 @@ function_ref<ReturnType(ArgTypes...)>::operator=(function_ref<ReturnType(ArgType
template <class ReturnType, class... ArgTypes>
inline ReturnType function_ref<ReturnType(ArgTypes...)>::operator()(ArgTypes... args) const noexcept
{
if (!m_pointerToCallable)
{
// Callable was called without user having assigned one beforehand
std::cerr << "Empty function_ref invoked" << std::endl;
std::terminate();
}
// Expect that a callable was assigned beforehand
cxx::Expects(m_pointerToCallable != nullptr && "Empty function_ref invoked");
return m_functionPointer(m_pointerToCallable, std::forward<ArgTypes>(args)...);
}

Expand Down
53 changes: 11 additions & 42 deletions iceoryx_utils/include/iceoryx_utils/internal/cxx/list.inl
Original file line number Diff line number Diff line change
Expand Up @@ -323,31 +323,31 @@ template <typename T, uint64_t Capacity>
inline T& list<T, Capacity>::front() noexcept
{
auto iter = begin();
handleInvalidElement(iter.m_iterListNodeIdx);
IOX_DISCARD_RESULT(handleInvalidElement(iter.m_iterListNodeIdx));
return *iter;
}

template <typename T, uint64_t Capacity>
inline const T& list<T, Capacity>::front() const noexcept
{
auto citer = cbegin();
handleInvalidElement(citer.m_iterListNodeIdx);
IOX_DISCARD_RESULT(handleInvalidElement(citer.m_iterListNodeIdx));
return *citer;
}

template <typename T, uint64_t Capacity>
inline T& list<T, Capacity>::back() noexcept
{
auto iter = end();
handleInvalidElement((--iter).m_iterListNodeIdx);
IOX_DISCARD_RESULT(handleInvalidElement((--iter).m_iterListNodeIdx));
return *iter;
}

template <typename T, uint64_t Capacity>
inline const T& list<T, Capacity>::back() const noexcept
{
auto citer = cend();
handleInvalidElement((--citer).m_iterListNodeIdx);
IOX_DISCARD_RESULT(handleInvalidElement((--citer).m_iterListNodeIdx));
return *citer;
}

Expand Down Expand Up @@ -637,11 +637,7 @@ inline void list<T, Capacity>::setNextIdx(const size_type idx, const size_type n
template <typename T, uint64_t Capacity>
inline const T* list<T, Capacity>::getDataPtrFromIdx(const size_type idx) const noexcept
{
if (handleInvalidElement(idx))
{
// error handling in call to handleInvalidElement()
return nullptr;
}
IOX_DISCARD_RESULT(handleInvalidElement(idx));

return &(reinterpret_cast<const T*>(&m_data)[idx]);
}
Expand All @@ -665,17 +661,8 @@ template <typename T, uint64_t Capacity>
inline bool list<T, Capacity>::handleInvalidElement(const size_type idx) const noexcept
{
// freeList / invalid elements will have the 'prevIdx' set to INVALID_INDEX
if (isValidElementIdx(idx))
{
return false;
}
else
{
errorMessage(__PRETTY_FUNCTION__, " invalid list element ");
std::terminate();

return true;
}
cxx::Expects(isValidElementIdx(idx) && "invalid list element");
return false;
}

template <typename T, uint64_t Capacity>
Expand All @@ -684,33 +671,15 @@ inline bool list<T, Capacity>::handleInvalidIterator(const const_iterator& iter)
// freeList / invalid elements will have the prevIdx set to INVALID_INDEX
// additional check on e.g. nextIdx or m_iterListNodeIdx (<INVALID_INDEX) are omitted as this
// should (can) never happen though normal list operations.
if (getPrevIdx(iter) < INVALID_INDEX)
{
return false;
}
else
{
errorMessage(__PRETTY_FUNCTION__, " invalidated iterator ");
std::terminate();

return true;
}
cxx::Expects(getPrevIdx(iter) < INVALID_INDEX && "invalidated iterator");
return false;
}

template <typename T, uint64_t Capacity>
inline bool list<T, Capacity>::isInvalidIterOrDifferentLists(const const_iterator& iter) const noexcept
{
if (this != iter.m_list)
{
errorMessage(__PRETTY_FUNCTION__, " iterator of other list can't be used ");
std::terminate();

return true;
}
else
{
return handleInvalidIterator(iter);
}
cxx::Expects(this == iter.m_list && "iterator of other list can't be used");
return handleInvalidIterator(iter);
}

template <typename T, uint64_t Capacity>
Expand Down
Loading

0 comments on commit 220b8d2

Please sign in to comment.