7021531: lock ordering problems after fix for 6354181
authornever
Tue, 22 Feb 2011 15:26:36 -0800
changeset 8333 11a7f6fc6419
parent 8332 3320859e937a
child 8334 9c373a57eb31
child 8488 d117c146849e
7021531: lock ordering problems after fix for 6354181 Reviewed-by: kvn, jrose
hotspot/src/share/vm/ci/ciEnv.cpp
hotspot/src/share/vm/utilities/ostream.cpp
hotspot/src/share/vm/utilities/ostream.hpp
--- a/hotspot/src/share/vm/ci/ciEnv.cpp	Wed Feb 09 15:02:23 2011 -0800
+++ b/hotspot/src/share/vm/ci/ciEnv.cpp	Tue Feb 22 15:26:36 2011 -0800
@@ -413,6 +413,7 @@
   }
   KlassHandle found_klass;
   {
+    ttyUnlocker ttyul;  // release tty lock to avoid ordering problems
     MutexLocker ml(Compile_lock);
     klassOop kls;
     if (!require_local) {
--- a/hotspot/src/share/vm/utilities/ostream.cpp	Wed Feb 09 15:02:23 2011 -0800
+++ b/hotspot/src/share/vm/utilities/ostream.cpp	Tue Feb 22 15:26:36 2011 -0800
@@ -699,6 +699,17 @@
   defaultStream::instance->release(holder);
 }
 
+bool ttyLocker::release_tty_if_locked() {
+  intx thread_id = os::current_thread_id();
+  if (defaultStream::instance->writer() == thread_id) {
+    // release the lock and return true so callers know if was
+    // previously held.
+    release_tty(thread_id);
+    return true;
+  }
+  return false;
+}
+
 void ttyLocker::break_tty_lock_for_safepoint(intx holder) {
   if (defaultStream::instance != NULL &&
       defaultStream::instance->writer() == holder) {
--- a/hotspot/src/share/vm/utilities/ostream.hpp	Wed Feb 09 15:02:23 2011 -0800
+++ b/hotspot/src/share/vm/utilities/ostream.hpp	Tue Feb 22 15:26:36 2011 -0800
@@ -123,18 +123,36 @@
 
 // advisory locking for the shared tty stream:
 class ttyLocker: StackObj {
+  friend class ttyUnlocker;
  private:
   intx _holder;
 
  public:
   static intx  hold_tty();                // returns a "holder" token
   static void  release_tty(intx holder);  // must witness same token
+  static bool  release_tty_if_locked();   // returns true if lock was released
   static void  break_tty_lock_for_safepoint(intx holder);
 
   ttyLocker()  { _holder = hold_tty(); }
   ~ttyLocker() { release_tty(_holder); }
 };
 
+// Release the tty lock if it's held and reacquire it if it was
+// locked.  Used to avoid lock ordering problems.
+class ttyUnlocker: StackObj {
+ private:
+  bool _was_locked;
+ public:
+  ttyUnlocker()  {
+    _was_locked = ttyLocker::release_tty_if_locked();
+  }
+  ~ttyUnlocker() {
+    if (_was_locked) {
+      ttyLocker::hold_tty();
+    }
+  }
+};
+
 // for writing to strings; buffer will expand automatically
 class stringStream : public outputStream {
  protected: