#include <mutex>
#include <atomic>
#include <memory>
#include <thread>
#include <utility>
#include <chrono>
#include <iostream>
class Worker {
std::unique_ptr<std::atomic<bool>> finished{ std::make_unique<std::atomic<bool>>(false) };
std::thread thread;
public:
template<typename F>
Worker(F&& f) :
thread{[finished = finished.get(),
f = std::forward<F>(f)]{
f();
finished->store(true, std::memory_order_relaxed);
}}
{
}
Worker() = default;
Worker(Worker&& o) noexcept
: finished{std::exchange(o.finished, {})},
thread{std::exchange(o.thread, {})}
{
}
Worker& operator=(Worker&& o) noexcept
{
if (&o == this) {
return *this;
}
std::swap(o.finished, finished);
std::swap(o.thread, thread);
return *this;
}
bool try_join()
{
if ( finished->load(std::memory_order_relaxed) ) {
thread.join();
return true;
}
return false;
}
void join()
{
thread.join();
}
~Worker()
{
if ( thread.joinable() ) {
thread.join();
}
}
};
int
main()
{
Worker w{ []{
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
}};
for ( ;; ) {
if ( w.try_join() ) {
std::cout << "joined\n";
break;
}
std::cout << "not joined let's wait again\n";
}
return 0;
}