Skip to content

Merge develop to main #13

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

Merged
merged 3 commits into from
Jun 15, 2024
Merged
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
4 changes: 4 additions & 0 deletions .github/workflows/build_run_unit_test_cmake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
name: CMake build and run unit test matrix

on:
pull_request:
types:
- opened
- reopened
push:
branches:
- main
Expand Down
50 changes: 40 additions & 10 deletions include/queue/wait_queue.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,11 +309,14 @@ class wait_queue {
* external @c std::stop_token was passed in.
*
*/
bool request_stop() noexcept {
auto request_stop() noexcept
-> bool {

if (m_stop_src) {
return (*m_stop_src).request_stop();
}
return false;

}

/**
Expand All @@ -327,14 +330,17 @@ class wait_queue {
* @return @c true if successful, @c false if the @c wait_queue has been
* requested to stop.
*/
bool push(const T& val) /* noexcept(std::is_nothrow_copy_constructible<T>::value) */ {
auto push(const T& val) /* noexcept(std::is_nothrow_copy_constructible<T>::value) */
-> bool {

if (m_stop_tok.stop_requested()) {
return false;
}
lock_guard lk{m_mut};
m_data_queue.push_back(val);
m_data_cond.notify_one();
return true;

}

/**
Expand All @@ -343,14 +349,17 @@ class wait_queue {
* This method has the same semantics as the other @c push, except that the value will
* be moved (if possible) instead of copied.
*/
bool push(T&& val) /* noexcept(std::is_nothrow_move_constructible<T>::value) */ {
auto push(T&& val) /* noexcept(std::is_nothrow_move_constructible<T>::value) */
-> bool {

if (m_stop_tok.stop_requested()) {
return false;
}
lock_guard lk{m_mut};
m_data_queue.push_back(std::move(val));
m_data_cond.notify_one();
return true;

}

/**
Expand All @@ -367,14 +376,17 @@ class wait_queue {
* to stop.
*/
template <typename ... Args>
bool emplace_push(Args &&... args) /* noexcept(std::is_nothrow_constructible<T, Args...>::value)*/ {
auto emplace_push(Args &&... args) /* noexcept(std::is_nothrow_constructible<T, Args...>::value)*/
-> bool {

if (m_stop_tok.stop_requested()) {
return false;
}
lock_guard lk{m_mut};
m_data_queue.emplace_back(std::forward<Args>(args)...);
m_data_cond.notify_one();
return true;

}

/**
Expand All @@ -388,14 +400,17 @@ class wait_queue {
* @return A value from the @c wait_queue (if non-empty). If the @c std::optional is empty,
* the @c wait_queue has been requested to be stopped.
*/
std::optional<T> wait_and_pop() /* noexcept(std::is_nothrow_constructible<T>::value) */ {
auto wait_and_pop() /* noexcept(std::is_nothrow_constructible<T>::value) */
-> std::optional<T> {

std::unique_lock<std::mutex> lk{m_mut};
if (!m_data_cond.wait ( lk, m_stop_tok, [this] { return !m_data_queue.empty(); } )) {
return std::optional<T> {}; // queue was request to stop, no data available
}
std::optional<T> val {std::move_if_noexcept(m_data_queue.front())}; // move construct if possible
m_data_queue.pop_front();
return val;

}

/**
Expand All @@ -406,7 +421,9 @@ class wait_queue {
* available in the @c wait_queue or if the @c wait_queue has been requested to be
* stopped .
*/
std::optional<T> try_pop() /* noexcept(std::is_nothrow_constructible<T>::value) */ {
auto try_pop() /* noexcept(std::is_nothrow_constructible<T>::value) */
-> std::optional<T> {

if (m_stop_tok.stop_requested()) {
return std::optional<T> {};
}
Expand All @@ -417,6 +434,7 @@ class wait_queue {
std::optional<T> val {std::move_if_noexcept(m_data_queue.front())}; // move construct if possible
m_data_queue.pop_front();
return val;

}

// non-modifying methods
Expand Down Expand Up @@ -447,11 +465,14 @@ class wait_queue {
* same @c wait_queue since it results in recursive mutex locks.
*/
template <typename F>
void apply(F&& func) const /* noexcept(std::is_nothrow_invocable<F&&, const T&>::value) */ {
auto apply(F&& func) const /* noexcept(std::is_nothrow_invocable<F&&, const T&>::value) */
-> void {

lock_guard lk{m_mut};
for (const T& elem : m_data_queue) {
func(elem);
}

}

/**
Expand All @@ -460,28 +481,37 @@ class wait_queue {
*
* @return @c true if the @c stop_requested has been called.
*/
bool stop_requested() const noexcept {
auto stop_requested() const noexcept
-> bool {

return m_stop_tok.stop_requested();

}

/**
* Query whether the @c wait_queue is empty or not.
*
* @return @c true if the @c wait_queue is empty.
*/
bool empty() const /* noexcept */ {
auto empty() const /* noexcept */
-> bool {

lock_guard lk{m_mut};
return m_data_queue.empty();

}

/**
* Get the number of elements in the @c wait_queue.
*
* @return Number of elements in the @c wait_queue.
*/
size_type size() const /* noexcept */ {
auto size() const /* noexcept */
-> size_type {

lock_guard lk{m_mut};
return m_data_queue.size();

}

};
Expand Down
2 changes: 1 addition & 1 deletion test/wait_queue_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,10 +164,10 @@ bool threaded_test(Q& wq, int num_readers, int num_writers, int slice, const T&
std::this_thread::sleep_for(std::chrono::seconds(1));
std::lock_guard<std::mutex> lk(mut);
if (s.size() == tot) {
wq.request_stop(); // tell the readers it's done
done = true;
}
}
wq.request_stop(); // tell the readers it's done

// join readers; since wait queue is stopped they should all join immediately
for (auto& thr : rd_thrs) {
Expand Down