[libbluray-devel] BDJ: log error when Xlet event handler blocks event dispatch thread

hpi1 git at videolan.org
Wed Feb 25 14:33:14 CET 2015


libbluray | branch: master | hpi1 <hpi1 at anonymous.org> | Wed Feb 25 14:59:40 2015 +0200| [d58864cf8720bb677fb65c43e7424f63719a75a2] | committer: hpi1

BDJ: log error when Xlet event handler blocks event dispatch thread

> http://git.videolan.org/gitweb.cgi/libbluray.git/?a=commit;h=d58864cf8720bb677fb65c43e7424f63719a75a2
---

 .../bdj/java/org/videolan/BDJActionQueue.java      |   77 +++++++++++++++++++-
 1 file changed, 74 insertions(+), 3 deletions(-)

diff --git a/src/libbluray/bdj/java/org/videolan/BDJActionQueue.java b/src/libbluray/bdj/java/org/videolan/BDJActionQueue.java
index a2178ca..fc74543 100644
--- a/src/libbluray/bdj/java/org/videolan/BDJActionQueue.java
+++ b/src/libbluray/bdj/java/org/videolan/BDJActionQueue.java
@@ -28,7 +28,7 @@ public class BDJActionQueue implements Runnable {
     public BDJActionQueue(BDJThreadGroup threadGroup, String name) {
         if (threadGroup == null) {
             if (BDJXletContext.getCurrentContext() != null) {
-                Logger.getLogger(BDJActionQueue.class.getName()).error("BDJActionQueue created from wrong context: " + Logger.dumpStack());
+                logger.error("BDJActionQueue created from wrong context: " + Logger.dumpStack());
             }
         }
 
@@ -36,18 +36,22 @@ public class BDJActionQueue implements Runnable {
         thread = new Thread(threadGroup, this, name + ".BDJActionQueue");
         thread.setDaemon(true);
         thread.start();
+
+        watchdog = new Watchdog(name);
     }
 
     public void shutdown() {
+
         synchronized (actions) {
             terminated = true;
             actions.addLast(null);
             actions.notifyAll();
         }
+        watchdog.shutdown();
         try {
             thread.join();
         } catch (Throwable t) {
-            Logger.getLogger(BDJActionQueue.class.getName()).error("Error joining thread: " + t);
+            logger.error("Error joining thread: " + t);
         }
     }
 
@@ -66,7 +70,11 @@ public class BDJActionQueue implements Runnable {
             if (action == null)
                 return;
             try {
+                watchdog.startAction(action);
+
                 ((BDJAction)action).process();
+
+                watchdog.endAction();
             } catch (Throwable e) {
                 System.err.println("action failed: " + e + "\n" + Logger.dumpStack(e));
             }
@@ -80,7 +88,7 @@ public class BDJActionQueue implements Runnable {
                     actions.addLast(action);
                     actions.notifyAll();
                 } else {
-                    Logger.getLogger(BDJActionQueue.class.getName()).error("Action skipped (queue stopped): " + action);
+                    logger.error("Action skipped (queue stopped): " + action);
                     action.abort();
                 }
             }
@@ -90,4 +98,67 @@ public class BDJActionQueue implements Runnable {
     private boolean terminated = false;
     private Thread thread;
     private LinkedList actions = new LinkedList();
+
+    private static final Logger logger = Logger.getLogger(BDJActionQueue.class.getName());
+
+    /*
+     *
+     */
+
+    private Watchdog watchdog = null;
+
+    class Watchdog implements Runnable {
+
+        private Object currentAction = null;
+        private boolean terminate = false;
+
+        Watchdog(String name) {
+            Thread t = new Thread(null, this, name + ".BDJActionQueue.Monitor");
+            t.setDaemon(true);
+            t.start();
+        }
+
+        public synchronized void shutdown() {
+            terminate = true;
+            notifyAll();
+        }
+
+        public synchronized void startAction(Object action) {
+            currentAction = action;
+            notifyAll();
+        }
+
+        public synchronized void endAction() {
+            currentAction = null;
+            notifyAll();
+        }
+
+        public void run() {
+            Object loggedAction = null;
+            synchronized (this) {
+                while (!terminate) {
+
+                    if (loggedAction != null && currentAction != loggedAction) {
+                        loggedAction = null;
+                        logger.info("Callback returned (" + thread + ")");
+                    }
+
+                    try {
+                        if (currentAction == null) {
+                            wait();
+                        } else {
+                            Object cachedAction = currentAction;
+                            wait(5000);
+                            if (currentAction == cachedAction && loggedAction != cachedAction) {
+                                logger.error("Callback timeout in " + thread + ", callback=" + currentAction + "\n" +
+                                             PortingHelper.dumpStack(thread));
+                                loggedAction = cachedAction;
+                            }
+                        }
+                    } catch (InterruptedException e) {
+                    }
+                }
+            }
+        }
+    }
 }



More information about the libbluray-devel mailing list