From 6613c1ec801ebf79eb0de76e9d29e75fa4b1f482 Mon Sep 17 00:00:00 2001
From: Glauber Costa <glommer@cloudius-systems.com>
Date: Mon, 28 Apr 2014 17:59:47 +0200
Subject: [PATCH] sched: provide thread exit notifiers

Functions to be run when a thread finishes.

Signed-off-by: Glauber Costa <glommer@cloudius-systems.com>
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
---
 core/sched.cc        | 12 ++++++++++++
 include/osv/sched.hh | 12 ++++++++++++
 2 files changed, 24 insertions(+)

diff --git a/core/sched.cc b/core/sched.cc
index a301591ee..35b4174cb 100644
--- a/core/sched.cc
+++ b/core/sched.cc
@@ -652,6 +652,14 @@ thread::thread(std::function<void ()> func, attr attr, bool main)
     }
 }
 
+static std::list<std::function<void (thread *)>> exit_notifiers;
+void thread::register_exit_notifier(std::function<void (thread *)> &&n)
+{
+    WITH_LOCK(thread_map_mutex) {
+        exit_notifiers.push_front(std::move(n));
+    }
+}
+
 thread::~thread()
 {
     cancel_this_thread_alarm();
@@ -662,6 +670,10 @@ thread::~thread()
     WITH_LOCK(thread_map_mutex) {
         thread_map.erase(_id);
         total_app_time_exited += _total_cpu_time;
+
+        for (auto& notifier : exit_notifiers) {
+            notifier(this);
+        }
     }
     if (_attr._stack.deleter) {
         _attr._stack.deleter(_attr._stack);
diff --git a/include/osv/sched.hh b/include/osv/sched.hh
index c51981aaf..d8079f128 100644
--- a/include/osv/sched.hh
+++ b/include/osv/sched.hh
@@ -585,6 +585,18 @@ public:
     static thread *find_by_id(unsigned int id);
 
     static int numthreads();
+    /**
+     * Registers an std::function that will be called when a thread is torn
+     * down.  This is useful, for example, to run code that needs to cleanup
+     * resources acquired by a given thread, about which the thread has no
+     * knowledge about
+     *
+     * In general, this will not run in the same context as the dying thread,
+     * but rather from special scheduler methods. Therefore, one needs to be
+     * careful about stack usage in here. Do not register notifiers that use a
+     * lot of stack
+     */
+    static void register_exit_notifier(std::function<void (thread *)> &&n);
 private:
     class reaper;
     friend class reaper;
-- 
GitLab