From e635dce083e968ed54f8c7b7b059ce8c3c9ee717 Mon Sep 17 00:00:00 2001
From: eapen <zhangyipeng7@huawei.com>
Date: Fri, 16 Dec 2022 16:00:25 +0800
Subject: [PATCH 32/33] I68TO2: Fix the crash that occurs when the process exits due to
 the mixed use of GCTrimNativeHeap and UseAsyncGCLog
---
 hotspot/src/share/vm/runtime/java.cpp           |  6 +++++
 hotspot/src/share/vm/runtime/logAsyncWriter.cpp | 35 ++++++++++++++++++++++++-
 hotspot/src/share/vm/runtime/logAsyncWriter.hpp |  4 +++
 3 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/hotspot/src/share/vm/runtime/java.cpp b/hotspot/src/share/vm/runtime/java.cpp
index 54b980d..e2194dd 100644
--- a/hotspot/src/share/vm/runtime/java.cpp
+++ b/hotspot/src/share/vm/runtime/java.cpp
@@ -54,6 +54,7 @@
 #include "runtime/init.hpp"
 #include "runtime/interfaceSupport.hpp"
 #include "runtime/java.hpp"
+#include "runtime/logAsyncWriter.hpp"
 #include "runtime/memprofiler.hpp"
 #include "runtime/sharedRuntime.hpp"
 #include "runtime/statSampler.hpp"
@@ -515,6 +516,11 @@ void before_exit(JavaThread * thread) {
   // Stop concurrent GC threads
   Universe::heap()->stop();

+  // Stop async log writer thread
+  if (UseAsyncGCLog) {
+    AsyncLogWriter::instance()->stop();
+  }
+
   // Print GC/heap related information.
   if (PrintGCDetails) {
     Universe::print();
diff --git a/hotspot/src/share/vm/runtime/logAsyncWriter.cpp b/hotspot/src/share/vm/runtime/logAsyncWriter.cpp
index 750a23f..7722020 100644
--- a/hotspot/src/share/vm/runtime/logAsyncWriter.cpp
+++ b/hotspot/src/share/vm/runtime/logAsyncWriter.cpp
@@ -63,7 +63,7 @@ void AsyncLogWriter::enqueue(const char* msg) {
 AsyncLogWriter::AsyncLogWriter()
   : NamedThread(),
   _lock(1), _sem(0), _io_sem(1),
-  _initialized(false),
+  _initialized(false),_should_terminate(false),_has_terminated(false),
   _buffer_max_size(AsyncLogBufferSize / sizeof(AsyncLogMessage)) {
   if (os::create_thread(this, os::asynclog_thread)) {
     _initialized = true;
@@ -124,6 +124,11 @@ void AsyncLogWriter::run() {
     // The value of a semphore cannot be negative. Therefore, the current thread falls asleep
     // when its value is zero. It will be waken up when new messages are enqueued.
     _sem.wait();
+    if (_should_terminate) {
+      write();
+      terminate();
+      break;
+    }
     write();
   }
 }
@@ -162,3 +167,32 @@ void AsyncLogWriter::print_on(outputStream* st) const{
   Thread::print_on(st);
   st->cr();
 }
+
+void AsyncLogWriter::stop() {
+  {
+    MutexLockerEx ml(Terminator_lock);
+    _should_terminate = true;
+  }
+  {
+    _sem.signal();
+  }
+  {
+    MutexLockerEx ml(Terminator_lock);
+    while (!_has_terminated) {
+      Terminator_lock->wait();
+    }
+  }
+}
+
+void AsyncLogWriter::terminate() {
+  // Signal that it is terminated
+  {
+    MutexLockerEx mu(Terminator_lock,
+                     Mutex::_no_safepoint_check_flag);
+    _has_terminated = true;
+    Terminator_lock->notify();
+  }
+
+  // Thread destructor usually does this..
+  ThreadLocalStorage::set_thread(NULL);
+}
diff --git a/hotspot/src/share/vm/runtime/logAsyncWriter.hpp b/hotspot/src/share/vm/runtime/logAsyncWriter.hpp
index 5242426..54e5d48 100644
--- a/hotspot/src/share/vm/runtime/logAsyncWriter.hpp
+++ b/hotspot/src/share/vm/runtime/logAsyncWriter.hpp
@@ -136,6 +136,8 @@ class AsyncLogWriter : public NamedThread {
   Semaphore _io_sem;

   volatile bool _initialized;
+  volatile bool _should_terminate;
+  volatile bool _has_terminated;
   AsyncLogBuffer _buffer;

   const size_t _buffer_max_size;
@@ -153,6 +155,8 @@ class AsyncLogWriter : public NamedThread {
   static void flush();
   // Printing
   void print_on(outputStream* st) const;
+  void stop();
+  void terminate();

 };

--
1.8.3.1
