The existing function sched::thread::find_by_id() efficiently finds a
sched::thread object given a numerical id. However, if this call races
with the thread's exit, the returned thread pointer may no longer be
valid and using it might result in a crash.

This patch adds a safer function, sched::with_thread_by_id() which runs
a given function on the thread with the given id - while holding a mutex
which prevents threads (including this one) from exiting. Because it holds
this mutex, the function should typically be very short - e.g., test
something about this thread.

Signed-off-by: Nadav Har'El <n...@scylladb.com>
---
 include/osv/sched.hh | 12 ++++++++++++
 core/sched.cc        |  6 ++++++
 2 files changed, 18 insertions(+)

diff --git a/include/osv/sched.hh b/include/osv/sched.hh
index f678ba2..3a19247 100644
--- a/include/osv/sched.hh
+++ b/include/osv/sched.hh
@@ -1329,6 +1329,18 @@ inline void migrate_enable()
 // this function should be used sparingly, e.g., for debugging.
 void with_all_threads(std::function<void(sched::thread &)>);
 
+// with_thread_by_id(id, f) finds the thread with the given id, and calls
+// the given function f() for it. A pointer to the thread is passed, or a
+// null pointer if a thread with that id does not exist.
+// The implementation is safe, in that it is guaranteed that while f is
+// operating on the thread, the thread object will not be concurrently
+// destroyed.
+// NOTE: The current implementation holds a mutex (thread_map_mutex) during
+// the entire with_thread_by_id() run. This blocks, among other things,
+// thread creation and destruction. For this reason, the given function
+// should return quickly.
+void with_thread_by_id(unsigned id, std::function<void(sched::thread *)>);
+
 }
 
 #endif /* SCHED_HH_ */
diff --git a/core/sched.cc b/core/sched.cc
index 306fc8e..7ee1fe2 100644
--- a/core/sched.cc
+++ b/core/sched.cc
@@ -1779,6 +1779,12 @@ void with_all_threads(std::function<void(thread &)> f) {
     }
 }
 
+void with_thread_by_id(unsigned id, std::function<void(thread *)> f) {
+    WITH_LOCK(thread_map_mutex) {
+        f(thread::find_by_id(id));
+    }
+}
+
 
 }
 
-- 
2.9.3

-- 
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to osv-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to