xref: /netbsd-src/external/gpl3/gdb/dist/gdbsupport/task-group.cc (revision f8cf1a9151c7af1cb0bd8b09c13c66bca599c027)
1 /* Task group
2 
3    Copyright (C) 2023-2024 Free Software Foundation, Inc.
4 
5    This file is part of GDB.
6 
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19 
20 #include "task-group.h"
21 #include "thread-pool.h"
22 
23 namespace gdb
24 {
25 
26 class task_group::impl : public std::enable_shared_from_this<task_group::impl>
27 {
28 public:
29 
30   explicit impl (std::function<void ()> &&done)
31     : m_done (std::move (done))
32   { }
33   DISABLE_COPY_AND_ASSIGN (impl);
34 
35   ~impl ()
36   {
37     if (m_started)
38       m_done ();
39   }
40 
41   /* Add a task to the task group.  */
42   void add_task (std::function<void ()> &&task)
43   {
44     m_tasks.push_back (std::move (task));
45   };
46 
47   /* Start this task group.  */
48   void start ();
49 
50   /* True if started.  */
51   bool m_started = false;
52   /* The tasks.  */
53   std::vector<std::function<void ()>> m_tasks;
54   /* The 'done' function.  */
55   std::function<void ()> m_done;
56 };
57 
58 void
59 task_group::impl::start ()
60 {
61   std::shared_ptr<impl> shared_this = shared_from_this ();
62   m_started = true;
63   for (size_t i = 0; i < m_tasks.size (); ++i)
64     {
65       gdb::thread_pool::g_thread_pool->post_task ([=] ()
66       {
67 	/* Be sure to capture a shared reference here.  */
68 	shared_this->m_tasks[i] ();
69       });
70     }
71 }
72 
73 task_group::task_group (std::function<void ()> &&done)
74   : m_task (new impl (std::move (done)))
75 {
76 }
77 
78 void
79 task_group::add_task (std::function<void ()> &&task)
80 {
81   gdb_assert (m_task != nullptr);
82   m_task->add_task (std::move (task));
83 }
84 
85 void
86 task_group::start ()
87 {
88   gdb_assert (m_task != nullptr);
89   m_task->start ();
90   m_task.reset ();
91 }
92 
93 } /* namespace gdb */
94