libbluray | branch: master | hpi1 <[email protected]> | 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) { + } + } + } + } + } } _______________________________________________ libbluray-devel mailing list [email protected] https://mailman.videolan.org/listinfo/libbluray-devel
