destroy threads after job done (#7083)

diff --git a/mgmt/ProcessManager.cc b/mgmt/ProcessManager.cc
index 897cef1..e3c9bac 100644
--- a/mgmt/ProcessManager.cc
+++ b/mgmt/ProcessManager.cc
@@ -82,11 +82,12 @@
 }
 
 void
-ProcessManager::start(std::function<void()> const &cb)
+ProcessManager::start(std::function<TSThread()> const &cb_init, std::function<void(TSThread)> const &cb_destroy)
 {
   Debug("pmgmt", "starting process manager");
 
-  init = cb;
+  init    = cb_init;
+  destroy = cb_destroy;
 
   ink_release_assert(running == 0);
   ink_atomic_increment(&running, 1);
@@ -153,7 +154,7 @@
   }
 
   if (pmgmt->init) {
-    pmgmt->init();
+    pmgmt->managerThread = pmgmt->init();
   }
 
   // Start pumping messages between the local process and the process
@@ -178,6 +179,11 @@
     }
   }
 
+  if (pmgmt->destroy && pmgmt->managerThread != nullptr) {
+    pmgmt->destroy(pmgmt->managerThread);
+    pmgmt->managerThread = nullptr;
+  }
+
   return ret;
 }
 
diff --git a/mgmt/ProcessManager.h b/mgmt/ProcessManager.h
index fdf555d..c19b14c 100644
--- a/mgmt/ProcessManager.h
+++ b/mgmt/ProcessManager.h
@@ -28,6 +28,8 @@
 #include <functional>
 #include <string_view>
 
+#include <ts/apidefs.h>
+
 #include "MgmtUtils.h"
 #include "BaseManager.h"
 #include "tscore/ink_sock.h"
@@ -49,7 +51,8 @@
   // Start a thread for the process manager. If @a cb is set then it
   // is called after the thread is started and before any messages are
   // processed.
-  void start(std::function<void()> const &cb = std::function<void()>());
+  void start(std::function<TSThread()> const &cb_init        = std::function<TSThread()>(),
+             std::function<void(TSThread)> const &cb_destroy = std::function<void(TSThread)>());
 
   // Stop the process manager, dropping any unprocessed messages.
   void stop();
@@ -94,7 +97,9 @@
 
   /// Thread initialization callback.
   /// This allows @c traffic_server and @c traffic_manager to perform different initialization in the thread.
-  std::function<void()> init;
+  std::function<TSThread()> init;
+  std::function<void(TSThread)> destroy;
+  TSThread managerThread = nullptr;
 
   int local_manager_sockfd;
 #if HAVE_EVENTFD
diff --git a/src/traffic_server/traffic_server.cc b/src/traffic_server/traffic_server.cc
index 80ba310..c86fd0d 100644
--- a/src/traffic_server/traffic_server.cc
+++ b/src/traffic_server/traffic_server.cc
@@ -662,8 +662,8 @@
   pmgmt = new ProcessManager(remote_management_flag);
 
   // Lifecycle callbacks can potentially be invoked from this thread, so force thread initialization
-  // to make the TS API work. Use a lambda to avoid dealing with compiler dependent casting issues.
-  pmgmt->start([]() -> void { TSThreadInit(); });
+  // to make the TS API work.
+  pmgmt->start(TSThreadInit, TSThreadDestroy);
 
   RecProcessInitMessage(remote_management_flag ? RECM_CLIENT : RECM_STAND_ALONE);
   pmgmt->reconfigure();