Skip to content

Commit

Permalink
Update pipeline, static checks
Browse files Browse the repository at this point in the history
  • Loading branch information
asherikov committed Jul 16, 2024
1 parent 00e3d88 commit 9e86558
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 56 deletions.
36 changes: 23 additions & 13 deletions .github/workflows/master.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,36 +9,46 @@ jobs:
runs-on: ubuntu-20.04

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- run: make install_ubuntu_test_deps
- run: make test

jammy_test:
runs-on: ubuntu-22.04

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- run: make install_ubuntu_test_deps
- run: make test

jammy_scanbuild:
runs-on: ubuntu-22.04

steps:
- uses: actions/checkout@v3
- run: sudo apt update
- run: make install_ubuntu_test_deps
- run: $APT_INSTALL clang-tidy-13
- run: make clangcheck SCANBUILD=scan-build-13

deb:
runs-on: ubuntu-20.04
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- run: make deb_install_deps
- run: make deb_any
- run: sudo dpkg -i build/thread_supervisor-*-any.deb

ccws:
runs-on: ubuntu-22.04

steps:
- name: ccws
uses: actions/checkout@v4
with:
repository: "asherikov/ccws"
path: "ccws"
- run: mkdir -p ccws/src/.ccws
- name: main
uses: actions/checkout@v4
with:
path: "ccws/src/thread_supervisor"
- run: echo 'set(thread_supervisor_TESTS "ON" CACHE STRING "" FORCE)' > "ccws/src/.ccws/toolchain.cmake"
- run: cd ccws; make bp_install_build BUILD_PROFILE=static_checks
- run: cd ccws; make bp_install_build BUILD_PROFILE=scan_build
- run: cd ccws; make BUILD_PROFILE=static_checks
- run: cd ccws; make dep_install PKG=thread_supervisor
- run: cd ccws; make thread_supervisor BUILD_PROFILE=scan_build
2 changes: 1 addition & 1 deletion .github/workflows/tag.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ jobs:
deb_cloudsmith:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- run: make deb_install_deps_cloudsmith
- run: env CLOUDSMITH_API_KEY=${{ secrets.CLOUDSMITH_API_KEY }} make deb_cloudsmith_any
7 changes: 4 additions & 3 deletions .make/common.mk
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ APT_INSTALL=sudo apt install -y --no-install-recommends
PIP_INSTALL=sudo python3 -m pip install
GEM_INSTALL=sudo gem install

CLANG_FORMAT?=clang-format13
SCANBUILD?=scan-build-13
CLANG_FORMAT?=clang-format15
SCANBUILD?=scan-build-15


help:
Expand All @@ -34,8 +34,8 @@ update_version_cmake:

cppcheck:
# --inconclusive
find ./ -type f -iname '*.hpp' -or -iname "*.cpp" -or -iname "*.h" | xargs --max-procs=1 --no-run-if-empty -I {} \
cppcheck \
./ \
--relative-paths \
--quiet --verbose --force \
--template='[{file}:{line}] {severity} {id} {message}' \
Expand All @@ -51,6 +51,7 @@ cppcheck:
--suppress=constStatement \
--inline-suppr \
-i ${BUILD_ROOT} \
{} \
3>&1 1>&2 2>&3 | tee cppcheck.err
test 0 -eq `cat cppcheck.err | wc -l && rm cppcheck.err`

Expand Down
10 changes: 10 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,17 @@ if (CCWS_CXX_FLAGS)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CCWS_CXX_FLAGS}")
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${CCWS_LINKER_FLAGS}")
#add_definitions(-DCCWS_DEBUG=${CCWS_DEBUG})
else()
set(CMAKE_VERBOSE_MAKEFILE ON)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic -Werror)
endif()
endif()

# ---


Expand Down
71 changes: 38 additions & 33 deletions include/thread_supervisor/supervisor.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ namespace tut
void log(const t_Arg &arg, t_Args &&...args) const
{
std::cerr << arg;
// cppcheck-suppress ignoredReturnValue
log(std::forward<t_Args>(args)...);
}

Expand Down Expand Up @@ -77,23 +78,23 @@ namespace tut
std::size_t sleep_ms_; /// delay between attempts

public:
explicit Restart(const std::size_t attempts = 0, const std::size_t sleep_ms = 0)
explicit Restart(const std::size_t attempts = 0, const std::size_t sleep_ms = 0) // NOLINT
{
attempts_ = attempts;
sleep_ms_ = sleep_ms;
}

bool isUnlimited() const
[[nodiscard]] bool isUnlimited() const
{
return (0 == attempts_);
}

bool isOk(const std::size_t attempt) const
[[nodiscard]] bool isOk(const std::size_t attempt) const
{
return (isUnlimited() or attempt < attempts_);
}

bool isEnabled() const
[[nodiscard]] bool isEnabled() const
{
return (isOk(1));
}
Expand All @@ -115,8 +116,8 @@ namespace tut

public:
explicit Scheduling(
const int priority = 0,
const int policy = SCHED_FIFO,
const int priority = 0, // NOLINT
const int policy = SCHED_FIFO, // NOLINT
const bool ignore_failures = true)
{
priority_ = priority;
Expand All @@ -125,7 +126,7 @@ namespace tut
}


bool apply(const std::thread::native_handle_type &&handle) const
bool apply(const std::thread::native_handle_type &&handle) const // NOLINT return value can be ignored
{
if (SCHED_FIFO != policy_ or 0 != priority_) // custom parameters
{
Expand Down Expand Up @@ -157,34 +158,34 @@ namespace tut

public:
template <class... t_Args>
Parameters(const Restart &&restart, t_Args &&...args) : Parameters(std::forward<t_Args>(args)...)
Parameters(const Restart &&restart, t_Args &&...args) // NOLINT noexplicit
: Parameters(std::forward<t_Args>(args)...)
{
restart_ = restart;
}

template <class... t_Args>
Parameters(const Scheduling &&scheduling, t_Args &&...args) : Parameters(std::forward<t_Args>(args)...)
Parameters(const Scheduling &&scheduling, t_Args &&...args) // NOLINT noexplicit
: Parameters(std::forward<t_Args>(args)...)
{
scheduling_ = scheduling;
}

template <class... t_Args>
Parameters(const TerminationPolicy termination_policy, t_Args &&...args)
Parameters(const TerminationPolicy termination_policy, t_Args &&...args) // NOLINT noexplicit
: Parameters(std::forward<t_Args>(args)...)
{
termination_policy_ = termination_policy;
}

template <class... t_Args>
Parameters(const ExceptionPolicy exception_policy, t_Args &&...args)
Parameters(const ExceptionPolicy exception_policy, t_Args &&...args) // NOLINT noexplicit
: Parameters(std::forward<t_Args>(args)...)
{
exception_policy_ = exception_policy;
}

Parameters()
{
}
Parameters() = default;
};


Expand Down Expand Up @@ -250,14 +251,12 @@ namespace tut
{
break;
}
else
{
supervisor->log(
"Supervisor / restarting thread: ",
attempt + 1,
" / ",
parameters_.restart_.isUnlimited() ? 0 : parameters_.restart_.attempts_);
}

supervisor->log(
"Supervisor / restarting thread: ",
attempt + 1,
" / ",
parameters_.restart_.isUnlimited() ? 0 : parameters_.restart_.attempts_);
}
else
{
Expand Down Expand Up @@ -357,17 +356,17 @@ namespace tut
{
const std::size_t sleep_ms = 10;

std::size_t counter = 0;
{
std::lock_guard<std::mutex> lock(threads_mutex_);
const std::lock_guard<std::mutex> lock(threads_mutex_);
std::size_t counter = 0;
for (;;)
{
if (counter * sleep_ms < wait_ms)
{
{
std::lock_guard<std::mutex> terminated_lock(terminated_threads_mutex_);
const std::lock_guard<std::mutex> terminated_lock(terminated_threads_mutex_);

for (Thread::Reference &thread_ref : terminated_threads_)
for (const Thread::Reference &thread_ref : terminated_threads_)
{
thread_ref->join();
threads_.erase(thread_ref);
Expand All @@ -387,6 +386,7 @@ namespace tut
}
else
{
// cppcheck-suppress ignoredReturnValue
log("Threads did not terminate in the given time after request.");
return (false);
}
Expand All @@ -397,14 +397,14 @@ namespace tut

bool empty()
{
std::lock_guard<std::mutex> lock(threads_mutex_);
const std::lock_guard<std::mutex> lock(threads_mutex_);
return (threads_.empty());
}


void drop(const std::list<Thread>::iterator &item)
{
std::lock_guard<std::mutex> lock(terminated_threads_mutex_);
const std::lock_guard<std::mutex> lock(terminated_threads_mutex_);
terminated_threads_.push_back(item);
}

Expand All @@ -421,19 +421,21 @@ namespace tut

~Supervisor()
{
if (false == isInterrupted())
if (not isInterrupted())
{
// - throwing in destructor -> terminate(), unless noexcept(false) is set.
// - noexcept(false) however interferes with other stuff in derived classes.
// - this check is intended to detect API misuse and should not fail under
// normal conditions.
// cppcheck-suppress ignoredReturnValue
log("Destructor of Supervisor is reached with 'interrupted_ = false',"
"which means that terminate() method was not called.");
std::terminate();
}

if (not empty())
{
// cppcheck-suppress ignoredReturnValue
log("Destructor of Supervisor is reached with some threads still running.");
std::terminate();
}
Expand All @@ -448,7 +450,7 @@ namespace tut


/// Check if interrupted, child threads should stop when true (pass supervisor as a parameter).
bool isInterrupted() const
[[nodiscard]] bool isInterrupted() const
{
return (interrupted_);
}
Expand All @@ -468,12 +470,13 @@ namespace tut
{
if (isInterrupted())
{
// cppcheck-suppress ignoredReturnValue
log("Addition of a thread attempted after interrupt.");
std::terminate();
}
else
{
std::lock_guard<std::mutex> lock(threads_mutex_);
const std::lock_guard<std::mutex> lock(threads_mutex_);
threads_.emplace_back();
threads_.back().start(this, --threads_.end(), std::forward<t_Args>(args)...);
}
Expand All @@ -489,9 +492,11 @@ namespace tut
protected:
Supervisor<t_Logger> thread_supervisor_;

protected:
~InheritableSupervisor() = default;

public:
const Supervisor<t_Logger> &getThreadSupervisor() const
[[nodiscard]] const Supervisor<t_Logger> &getThreadSupervisor() const
{
return (thread_supervisor_);
}
Expand Down Expand Up @@ -521,7 +526,7 @@ namespace tut


/// Should be checked by threaded class methods
bool isThreadSupervisorInterrupted() const
[[nodiscard]] bool isThreadSupervisorInterrupted() const
{
return (getThreadSupervisor().isInterrupted());
}
Expand Down
8 changes: 4 additions & 4 deletions include/thread_supervisor/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
/// Class definitions that prevent copying
#define THREAD_SUPERVISOR_DISABLE_CLASS_COPY(Class) \
public: \
Class(const Class &) = delete; \
Class &operator=(const Class &) = delete; \
Class(Class &&) = delete; \
Class &operator=(Class &&) = delete;
Class(const Class &) = delete; /* NOLINT */ \
Class &operator=(const Class &) = delete; /* NOLINT */ \
Class(Class &&) = delete; /* NOLINT */ \
Class &operator=(Class &&) = delete; /* NOLINT */
3 changes: 2 additions & 1 deletion package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
<maintainer email="[email protected]">Alexander Sherikov</maintainer>
<author email="[email protected]">Alexander Sherikov</author>
<license>Apache 2.0</license>
<buildtool_depend>catkin</buildtool_depend>
<export>
<build_type>cmake</build_type>
</export>

<test_depend>boost</test_depend>
</package>
3 changes: 3 additions & 0 deletions qa/scspell.dict
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ apache
cppcheck
joinable
killall
nodiscard
noexcept
noexplicit
nolint
pthread
setschedparam
sherikov
Expand Down
2 changes: 1 addition & 1 deletion test/supervisor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ namespace
counter_ = 0;
}

~TestThreadSupervisor()
virtual ~TestThreadSupervisor()
{
stopSupervisedThreads();
}
Expand Down

0 comments on commit 9e86558

Please sign in to comment.