diff --git a/gdb/finish-thread-state.h b/gdb/finish-thread-state.h new file mode 100644 index 00000000000..60cd9be2b44 --- /dev/null +++ b/gdb/finish-thread-state.h @@ -0,0 +1,71 @@ +/* Copyright (C) 2025 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#ifndef GDB_FINISH_THREAD_STATE_H +#define GDB_FINISH_THREAD_STATE_H + +#include "gdbsupport/gdb-checked-static-cast.h" +#include "gdbsupport/scope-exit.h" +#include "gdbthread.h" +#include "target.h" +#include "process-stratum-target.h" + +namespace detail +{ + +/* Policy class for use with scope_exit_base. Calls finish_thread_state on + scope exit, unless release() is called to disengage. The release + mechanism is supplied by scope_exit_base. */ + +struct scoped_finish_thread_state_policy +{ + /* Store TARG and PTID for a later call to finish_thread_state. For the + meaning of these arguments, see the comments on finish_thread_state. */ + explicit scoped_finish_thread_state_policy (process_stratum_target *targ, + ptid_t ptid) + : m_ptid (ptid) + { + if (targ != nullptr) + m_target_ref = target_ops_ref::new_reference (targ); + } + + /* Called on scope exit unless release was called, see scope_exit_base + for details. Calls finish_thread_state with stored target and ptid. */ + void on_exit () + { + target_ops *t = m_target_ref.get (); + process_stratum_target *p_target + = gdb::checked_static_cast (t); + finish_thread_state (p_target, m_ptid); + } + +private: + + /* The process and target passed through to finish_thread_state. For + their use see the comments on that function. */ + ptid_t m_ptid; + target_ops_ref m_target_ref; +}; + +} + +/* Calls finish_thread_state on scope exit, unless release() is called to + disengage. */ +using scoped_finish_thread_state + = scope_exit_base; + +#endif /* GDB_FINISH_THREAD_STATE_H */ diff --git a/gdb/gdbthread.h b/gdb/gdbthread.h index 8ab5702d804..015da36ca71 100644 --- a/gdb/gdbthread.h +++ b/gdb/gdbthread.h @@ -859,11 +859,6 @@ extern bool threads_are_executing (process_stratum_target *targ); Notifications are only emitted if the thread state did change. */ extern void finish_thread_state (process_stratum_target *targ, ptid_t ptid); -/* Calls finish_thread_state on scope exit, unless release() is called - to disengage. */ -using scoped_finish_thread_state - = FORWARD_SCOPE_EXIT (finish_thread_state); - /* Commands with a prefix of `thread'. */ extern struct cmd_list_element *thread_cmd_list; diff --git a/gdb/infcmd.c b/gdb/infcmd.c index 5862b3e43ec..862cef6c1bb 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -57,6 +57,7 @@ #include "source.h" #include "cli/cli-style.h" #include "gdbsupport/selftest.h" +#include "finish-thread-state.h" /* Local functions: */ diff --git a/gdb/infrun.c b/gdb/infrun.c index f1ce7195530..6bcd8ec5cc0 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -75,6 +75,7 @@ #include "extension.h" #include "disasm.h" #include "interps.h" +#include "finish-thread-state.h" /* Prototypes for local functions */ diff --git a/gdb/remote.c b/gdb/remote.c index 8581d7d0a3b..1358e1c06b9 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -84,6 +84,7 @@ #include "cli/cli-style.h" #include "gdbsupport/remote-args.h" #include "gdbsupport/gdb_argv_vec.h" +#include "finish-thread-state.h" /* The remote target. */