aboutsummaryrefslogtreecommitdiffstats
path: root/plugin/icedteanp/java/sun/applet
diff options
context:
space:
mode:
authorAndrew John Hughes <[email protected]>2011-04-18 18:44:40 +0100
committerAndrew John Hughes <[email protected]>2011-04-18 18:44:40 +0100
commit885d877ae21a62a166b8ad2daa8274f8fec34094 (patch)
treed48ea450ec8e18a7437920cf1bf1c531efda2f82 /plugin/icedteanp/java/sun/applet
parent1568f22abe7ddef75816830af5b92951330e3daf (diff)
Switch to explicit locks and condition queues in PluginAppletViewer
2010-04-14 Andrew John Hughes <[email protected]> * plugin/icedteanp/java/sun/applet/PluginAppletViewer.java, (PluginAppletPanelFactory.createPanel(PluginStreamHandler, int,long,int,int,URL,Hashtable)): Remove duplication of wait for panel.isAlive(). (PluginAppletViewer.panelLock): New lock used to track panel creation. (PluginAppletViewer.panelLive): Condition queue for panel creation. (PluginAppletViewer.appletsLock): New lock used to track additions to the applets map. (PluginAppletViewer.appletAdded): Condition queue for applet addition. (PluginAppletViewer.statusLock): New lock for status changes. (PluginAppletViewer.initComplete): Condition queue for initialisation completion. (PluginAppletViewer.framePanel(int,long,NetxPanel)): Replace synchronized block with use of appletsLock and notification on appletAdded condition queue. (AppletEventListener.appletStateChanged(AppletEvent)): Signal the panelLive condition queue that the panel is live. (PluginAppletViewer.handleMessage(int,int,String)): Wait on appletAdded condition queue for applet to be added to the applets map. (PluginAppletViewer.updateStatus(Int,PAV_INIT_STATUS)): Signal when a status change occurs using the initComplete condition queue. (PluginAppletViewer.waitForAppletInit(NetxPanel)): Wait on the panelLive condition queue until the panel is created. (PluginAppletViewer.handleMessage(int,String)): Wait on the initComplete condition queue until initialisation is complete. Wait on the panelLive signal until panel is created. (waitTillTimeout(ReentrantLock,Condition,long)): Convert to use ReentrantLock and Condition. Add assertion to check the lock is held. Avoid conversion between milliseconds and nanoseconds.
Diffstat (limited to 'plugin/icedteanp/java/sun/applet')
-rw-r--r--plugin/icedteanp/java/sun/applet/PluginAppletViewer.java142
1 files changed, 74 insertions, 68 deletions
diff --git a/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java b/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java
index 2dee29b..486bab1 100644
--- a/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java
+++ b/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java
@@ -97,8 +97,13 @@ import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Vector;
+
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.TimeUnit;
+
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
import javax.swing.SwingUtilities;
@@ -139,25 +144,7 @@ class PluginAppletPanelFactory {
// Start the applet
initEventQueue(panel);
- // Wait for panel to come alive
- // Wait implemented the long way so that
- // PluginAppletViewer.waitTillTimeout() needn't be exposed.
- long maxTimeToSleep = PluginAppletViewer.APPLET_TIMEOUT/1000000; // ns -> ms
-
- synchronized(panel) {
- while (!panel.isAlive() && maxTimeToSleep > 0) {
- long sleepStart = System.nanoTime();
-
- try {
- panel.wait(maxTimeToSleep);
- } catch (InterruptedException e) {} // Just loop back
-
- maxTimeToSleep -= (System.nanoTime() - sleepStart)/1000000; // ns -> ms
- }
- }
-
// Wait for the panel to initialize
- // (happens in a separate thread)
PluginAppletViewer.waitForAppletInit(panel);
Applet a = panel.getApplet();
@@ -287,12 +274,17 @@ public class PluginAppletViewer extends XEmbeddedFrame
* The panel in which the applet is being displayed.
*/
private NetxPanel panel;
-
+ static final ReentrantLock panelLock = new ReentrantLock();
+ // CONDITION PREDICATE: panel.isAlive()
+ static final Condition panelLive = panelLock.newCondition();
private int identifier;
// Instance identifier -> PluginAppletViewer object.
private static ConcurrentMap<Integer, PluginAppletViewer> applets =
new ConcurrentHashMap<Integer, PluginAppletViewer>();
+ private static final ReentrantLock appletsLock = new ReentrantLock();
+ // CONDITION PREDICATE: !applets.containsKey(identifier)
+ private static final Condition appletAdded = appletsLock.newCondition();
private static PluginStreamHandler streamhandler;
@@ -300,6 +292,9 @@ public class PluginAppletViewer extends XEmbeddedFrame
private static ConcurrentMap<Integer, PAV_INIT_STATUS> status =
new ConcurrentHashMap<Integer, PAV_INIT_STATUS>();
+ private static final ReentrantLock statusLock = new ReentrantLock();
+ // CONDITION PREDICATE: !status.get(identifier).equals(PAV_INIT_STATUS.INIT_COMPLETE)
+ private static final Condition initComplete = statusLock.newCondition();
private WindowListener windowEventListener = null;
private AppletEventListener appletEventListener = null;
@@ -333,11 +328,10 @@ public class PluginAppletViewer extends XEmbeddedFrame
appletFrame.appletEventListener = new AppletEventListener(appletFrame, appletFrame);
panel.addAppletListener(appletFrame.appletEventListener);
-
- synchronized(applets) {
- applets.put(identifier, appletFrame);
- applets.notifyAll();
- }
+ appletsLock.lock();
+ applets.put(identifier, appletFrame);
+ appletAdded.signalAll();
+ appletsLock.unlock();
PluginDebug.debug(panel, " framed");
}
@@ -388,9 +382,9 @@ public class PluginAppletViewer extends XEmbeddedFrame
public void appletStateChanged(AppletEvent evt) {
AppletPanel src = (AppletPanel) evt.getSource();
- synchronized (src) {
- src.notifyAll();
- }
+ panelLock.lock();
+ panelLive.signalAll();
+ panelLock.unlock();
switch (evt.getID()) {
case AppletPanel.APPLET_RESIZE: {
@@ -484,12 +478,17 @@ public class PluginAppletViewer extends XEmbeddedFrame
new URL(documentBase));
long maxTimeToSleep = APPLET_TIMEOUT;
- synchronized(applets) {
+ appletsLock.lock();
+ try {
while (!applets.containsKey(identifier) &&
maxTimeToSleep > 0) { // Map is populated only by reFrame
- maxTimeToSleep -= waitTillTimeout(applets, maxTimeToSleep);
+ maxTimeToSleep -= waitTillTimeout(appletsLock, appletAdded,
+ maxTimeToSleep);
}
}
+ finally {
+ appletsLock.unlock();
+ }
// If wait exceeded maxWait, we timed out. Throw an exception
if (maxTimeToSleep <= 0)
@@ -576,11 +575,11 @@ public class PluginAppletViewer extends XEmbeddedFrame
}
// Else set to given status
-
- synchronized(status) {
- status.put(identifier, newStatus);
- status.notifyAll();
- }
+
+ statusLock.lock();
+ status.put(identifier, newStatus);
+ initComplete.signalAll();
+ statusLock.unlock();
return prev;
}
@@ -634,7 +633,7 @@ public class PluginAppletViewer extends XEmbeddedFrame
/**
* Function to block until applet initialization is complete.
- *
+ *
* This function will return if the wait is longer than {@link #APPLET_TIMEOUT}
*
* @param panel the instance to wait for.
@@ -644,14 +643,18 @@ public class PluginAppletViewer extends XEmbeddedFrame
// Wait till initialization finishes
long maxTimeToSleep = APPLET_TIMEOUT;
- synchronized(panel) {
+ panelLock.lock();
+ try {
while (panel.getApplet() == null &&
panel.isAlive() &&
maxTimeToSleep > 0) {
PluginDebug.debug("Waiting for applet panel ", panel, " to initialize...");
- maxTimeToSleep -= waitTillTimeout(panel, maxTimeToSleep);
+ maxTimeToSleep -= waitTillTimeout(panelLock, panelLive, maxTimeToSleep);
}
}
+ finally {
+ panelLock.unlock();
+ }
PluginDebug.debug("Applet panel ", panel, " initialized");
}
@@ -661,12 +664,17 @@ public class PluginAppletViewer extends XEmbeddedFrame
// Wait for panel to come alive
long maxTimeToSleep = APPLET_TIMEOUT;
- synchronized(status) {
+ statusLock.lock();
+ try {
while (!status.get(identifier).equals(PAV_INIT_STATUS.INIT_COMPLETE) &&
maxTimeToSleep > 0) {
- maxTimeToSleep -= waitTillTimeout(status, maxTimeToSleep);
+ maxTimeToSleep -= waitTillTimeout(statusLock, initComplete,
+ maxTimeToSleep);
}
}
+ finally {
+ statusLock.unlock();
+ }
// 0 => width, 1=> width_value, 2 => height, 3=> height_value
String[] dimMsg = message.split(" ");
@@ -715,21 +723,18 @@ public class PluginAppletViewer extends XEmbeddedFrame
// FIXME: how do we determine what security context this
// object should belong to?
Object o;
-
- // First, wait for panel to instantiate
- int waited = 0;
- while (panel == null && waited < APPLET_TIMEOUT) {
- try {
- Thread.sleep(50);
- waited += 50;
- } catch (InterruptedException ie) {} // discard, loop back
- }
+ // First, wait for panel to instantiate
// Next, wait for panel to come alive
long maxTimeToSleep = APPLET_TIMEOUT;
- synchronized(panel) {
- while (!panel.isAlive())
- maxTimeToSleep -= waitTillTimeout(panel, maxTimeToSleep);
+ panelLock.lock();
+ try {
+ while (panel == null || !panel.isAlive())
+ maxTimeToSleep -= waitTillTimeout(panelLock, panelLive,
+ maxTimeToSleep);
+ }
+ finally {
+ panelLock.unlock();
}
// Wait for the panel to initialize
@@ -1394,7 +1399,7 @@ public class PluginAppletViewer extends XEmbeddedFrame
/**
* Decodes the string (converts html escapes into proper characters)
- *
+ *
* @param toDecode The string to decode
* @return The decoded string
*/
@@ -1409,7 +1414,7 @@ public class PluginAppletViewer extends XEmbeddedFrame
return toDecode;
}
-
+
/**
* System parameters.
*/
@@ -1595,7 +1600,7 @@ public class PluginAppletViewer extends XEmbeddedFrame
public void run() {
ClassLoader cl = p.applet.getClass().getClassLoader();
- // Since we want to deal with JNLPClassLoader, extract it if this
+ // Since we want to deal with JNLPClassLoader, extract it if this
// is a codebase loader
if (cl instanceof JNLPClassLoader.CodeBaseClassLoader)
cl = ((JNLPClassLoader.CodeBaseClassLoader) cl).getParentJNLPClassLoader();
@@ -2084,34 +2089,35 @@ public class PluginAppletViewer extends XEmbeddedFrame
}
/**
- * Waits on a given object until timeout.
- *
+ * Waits on a given condition queue until timeout.
+ *
* <b>This function assumes that the monitor lock has already been
* acquired by the caller.</b>
- *
- * If the given object is null, this function returns immediately.
- *
- * @param obj The object to wait on
+ *
+ * If the given lock is null, this function returns immediately.
+ *
+ * @param lock the lock that must be held when this method is called.
+ * @param cond the condition queue on which to wait for notifications.
* @param timeout The maximum time to wait (nanoseconds)
* @return Approximate time spent sleeping (not guaranteed to be perfect)
*/
- public static long waitTillTimeout(Object obj, long timeout) {
+ public static long waitTillTimeout(ReentrantLock lock, Condition cond,
+ long timeout) {
// Can't wait on null. Return 0 indicating no wait happened.
- if (obj == null)
+ if (lock == null)
return 0;
-
+
+ assert lock.isHeldByCurrentThread();
+
// Record when we started sleeping
long sleepStart = 0L;
- // Convert timeout to ms since wait() takes ms
- timeout = timeout >= 1000000 ? timeout/1000000 : 1;
-
try {
sleepStart = System.nanoTime();
- obj.wait(timeout);
+ cond.await(timeout, TimeUnit.NANOSECONDS);
} catch (InterruptedException ie) {} // Discarded, time to return
-
+
// Return the difference
return System.nanoTime() - sleepStart;
}