From: Tom Tromey <tom@tromey.com>
To: gdb-patches@sourceware.org
Cc: Tom Tromey <tom@tromey.com>
Subject: [PATCH] Add lock_guard to thread_pool::thread_count
Date: Thu, 12 Mar 2026 16:46:04 -0600 [thread overview]
Message-ID: <20260312224604.1070829-1-tom@tromey.com> (raw)
I think there's a possible race when calling thread_pool::thread_count
from a worker thread, if the main thread changes the number of threads
at the same time.
When this code was initially written, we didn't worry about this,
because this was only accessed from the main thread. This is no
longer the case, though.
This patch fixes any potential problem by adding a lock_guard to the
method. This doesn't seem too harmful because this is not called very
much and because I doubt this lock is highly contended.
While doing this I noticed that thread_pool::do_post_task could access
m_sized_at_least_once and m_thread_count without holding the lock.
This patch changes this method as well.
---
gdbsupport/thread-pool.cc | 47 +++++++++++++++++++++++++++++----------
gdbsupport/thread-pool.h | 9 +-------
2 files changed, 36 insertions(+), 20 deletions(-)
diff --git a/gdbsupport/thread-pool.cc b/gdbsupport/thread-pool.cc
index 6940773d58a..4dc72e56642 100644
--- a/gdbsupport/thread-pool.cc
+++ b/gdbsupport/thread-pool.cc
@@ -148,6 +148,17 @@ thread_pool::~thread_pool ()
case -- see the comment by the definition of g_thread_pool. */
}
+size_t
+thread_pool::thread_count ()
+{
+#if CXX_STD_THREAD
+ std::lock_guard<std::mutex> guard (m_tasks_mutex);
+ return m_thread_count;
+#else
+ return 0;
+#endif
+}
+
void
thread_pool::set_thread_count (size_t num_threads)
{
@@ -197,21 +208,33 @@ thread_pool::set_thread_count (size_t num_threads)
void
thread_pool::do_post_task (std::packaged_task<void ()> &&func)
{
- /* This assert is here to check that no tasks are posted to the pool between
- its initialization and sizing. */
- gdb_assert (m_sized_at_least_once);
- std::packaged_task<void ()> t (std::move (func));
+ /* This is a bit strange but we don't want to hold the lock when
+ calling FUNC in the case where it must be called immediately.
+ Although that seems pathological, there are some weird cases (a
+ moribund worker thread or FUNC itself submitting a task) and it
+ seemed best to be safe. */
+ bool call_immediately = false;
- if (m_thread_count != 0)
- {
- std::lock_guard<std::mutex> guard (m_tasks_mutex);
- m_tasks.emplace (std::move (t));
- m_tasks_cv.notify_one ();
- }
- else
+ {
+ std::lock_guard<std::mutex> guard (m_tasks_mutex);
+
+ /* This assert is here to check that no tasks are posted to the
+ pool between its initialization and sizing. */
+ gdb_assert (m_sized_at_least_once);
+
+ if (m_thread_count != 0)
+ {
+ m_tasks.emplace (std::move (func));
+ m_tasks_cv.notify_one ();
+ }
+ else
+ call_immediately = true;
+ }
+
+ if (call_immediately)
{
/* Just execute it now. */
- t ();
+ func ();
}
}
diff --git a/gdbsupport/thread-pool.h b/gdbsupport/thread-pool.h
index 50b7a064d7e..a9188d1e107 100644
--- a/gdbsupport/thread-pool.h
+++ b/gdbsupport/thread-pool.h
@@ -50,14 +50,7 @@ class thread_pool
void set_thread_count (size_t num_threads);
/* Return the number of executing threads. */
- size_t thread_count () const
- {
-#if CXX_STD_THREAD
- return m_thread_count;
-#else
- return 0;
-#endif
- }
+ size_t thread_count ();
/* Post a task to the thread pool. A future is returned, which can
be used to wait for the result. */
--
2.49.0
next reply other threads:[~2026-03-12 22:46 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-12 22:46 Tom Tromey [this message]
2026-03-19 22:52 ` Kevin Buettner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260312224604.1070829-1-tom@tromey.com \
--to=tom@tromey.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox