Line data Source code
1 : /**
2 : * @file WorkerThread.cpp WorkerThread class definitions
3 : *
4 : * WorkerThread defines a std::jthread which runs the do_work()
5 : * function as well as methods to start and stop that thread.
6 : * This file is intended to help reduce code duplication for the common
7 : * task of starting and stopping threads.
8 : *
9 : * This is part of the DUNE DAQ Application Framework, copyright 2020.
10 : * Licensing/copyright details are in the COPYING file that you should have
11 : * received with this code.
12 : */
13 :
14 : #include "utilities/WorkerThread.hpp"
15 : #include "utilities/Issues.hpp"
16 :
17 : #include <memory>
18 : #include <string>
19 :
20 9 : dunedaq::utilities::WorkerThread::WorkerThread(std::function<void(std::atomic<bool>&)> do_work)
21 9 : : m_thread_running(false)
22 9 : , m_working_thread(nullptr)
23 9 : , m_do_work(do_work)
24 : {
25 9 : }
26 :
27 : void
28 10 : dunedaq::utilities::WorkerThread::start_working_thread(const std::string& name)
29 : {
30 10 : if (thread_running()) {
31 1 : throw ThreadingIssue(ERS_HERE,
32 : "Attempted to start working thread "
33 2 : "when it is already running!");
34 : }
35 9 : m_thread_running = true;
36 18 : m_working_thread = std::make_unique<std::jthread>([&] { m_do_work(std::ref(m_thread_running)); });
37 9 : auto handle = m_working_thread->native_handle();
38 9 : auto rc = pthread_setname_np(handle, name.c_str());
39 9 : if (rc != 0) {
40 1 : std::ostringstream s;
41 1 : s << "The name " << name << " provided for the thread is too long.";
42 1 : ers::warning(ThreadingIssue(ERS_HERE, s.str()));
43 1 : }
44 9 : }
45 :
46 : void
47 9 : dunedaq::utilities::WorkerThread::stop_working_thread()
48 : {
49 9 : if (!thread_running()) {
50 1 : throw ThreadingIssue(ERS_HERE,
51 : "Attempted to stop working thread "
52 2 : "when it is not running!");
53 : }
54 8 : m_thread_running = false;
55 :
56 8 : if (m_working_thread->joinable()) {
57 8 : try {
58 8 : m_working_thread->join();
59 0 : } catch (std::system_error const& e) {
60 0 : throw ThreadingIssue(ERS_HERE, std::string("Error while joining thread, ") + e.what());
61 0 : }
62 : } else {
63 0 : throw ThreadingIssue(ERS_HERE, "Thread not in joinable state during working thread stop!");
64 : }
65 8 : }
|