]> source.dussan.org Git - tigervnc.git/commitdiff
Release queueMutex using finally blocks 703/head
authorPepijn Van Eeckhoudt <pepijn@vaneeckhoudt.net>
Mon, 20 Aug 2018 12:22:37 +0000 (14:22 +0200)
committerGitHub <noreply@github.com>
Mon, 20 Aug 2018 12:22:37 +0000 (14:22 +0200)
Ensure queueMutex is always correctly released by using finally blocks. This is the closest approximation of AutoMutex style automatic release you can get in Java.

java/com/tigervnc/rfb/DecodeManager.java

index 9c7cacbbb2b92dd41bcc2e6507628d67f1f4cec7..d849444615a6138901d086815c342ae617946c3e 100644 (file)
@@ -116,16 +116,18 @@ public class DecodeManager {
     // Wait for an available memory buffer
     queueMutex.lock();
 
-    while (freeBuffers.isEmpty())
-      try {
-      producerCond.await();
-      } catch (InterruptedException e) { }
-
-    // Don't pop the buffer in case we throw an exception
-    // whilst reading
-    bufferStream = freeBuffers.getFirst();
+    try {
+      while (freeBuffers.isEmpty())
+        try {
+        producerCond.await();
+        } catch (InterruptedException e) { }
 
-    queueMutex.unlock();
+      // Don't pop the buffer in case we throw an exception
+      // whilst reading
+      bufferStream = freeBuffers.getFirst();
+    } finally {
+      queueMutex.unlock();
+    }
 
     // First check if any thread has encountered a problem
     throwThreadException();
@@ -151,29 +153,33 @@ public class DecodeManager {
 
     queueMutex.lock();
 
-    // The workers add buffers to the end so it's safe to assume
-    // the front is still the same buffer
-    freeBuffers.removeFirst();
-
-    workQueue.addLast(entry);
+    try {
+      // The workers add buffers to the end so it's safe to assume
+      // the front is still the same buffer
+      freeBuffers.removeFirst();
 
-    // We only put a single entry on the queue so waking a single
-    // thread is sufficient
-    consumerCond.signal();
+      workQueue.addLast(entry);
 
-    queueMutex.unlock();
+      // We only put a single entry on the queue so waking a single
+      // thread is sufficient
+      consumerCond.signal();
+    } finally {
+      queueMutex.unlock();
+    }
   }
 
   public void flush()
   {
     queueMutex.lock();
 
-    while (!workQueue.isEmpty())
-      try {
-      producerCond.await();
-      } catch (InterruptedException e) { }
-
-    queueMutex.unlock();
+    try {
+      while (!workQueue.isEmpty())
+        try {
+        producerCond.await();
+        } catch (InterruptedException e) { }
+    } finally {
+      queueMutex.unlock();
+    }
 
     throwThreadException();
   }
@@ -183,11 +189,15 @@ public class DecodeManager {
     //os::AutoMutex a(queueMutex);
     queueMutex.lock();
 
-    if (threadException != null)
-      return;
+    try {
+      if (threadException != null)
+        return;
 
-    threadException =
-      new Exception("Exception on worker thread: "+e.getMessage());
+      threadException =
+        new Exception("Exception on worker thread: "+e.getMessage());
+    } finally {
+      queueMutex.unlock();
+    }
   }
 
   private void throwThreadException()
@@ -195,14 +205,18 @@ public class DecodeManager {
     //os::AutoMutex a(queueMutex);
     queueMutex.lock();
 
-    if (threadException == null)
-      return;
+    try {
+      if (threadException == null)
+        return;
 
-    Exception e = new Exception(threadException.getMessage());
+      Exception e = new Exception(threadException.getMessage());
 
-    threadException = null;
+      threadException = null;
 
-    throw e;
+      throw e;
+    } finally {
+      queueMutex.unlock();
+    }
   }
 
   private class QueueEntry {
@@ -236,13 +250,17 @@ public class DecodeManager {
       //os::AutoMutex a(manager.queueMutex);
       manager.queueMutex.lock();
 
-      if (!thread.isAlive())
-        return;
+      try {
+        if (!thread.isAlive())
+          return;
 
-      stopRequested = true;
+        stopRequested = true;
 
-      // We can't wake just this thread, so wake everyone
-      manager.consumerCond.signalAll();
+        // We can't wake just this thread, so wake everyone
+        manager.consumerCond.signalAll();
+      } finally {
+        manager.queueMutex.unlock();
+      }
     }
 
     public void run()