1.1 --- a/openide.util/nbproject/project.properties Fri Sep 25 14:02:54 2009 +0200
1.2 +++ b/openide.util/nbproject/project.properties Wed Sep 30 19:03:18 2009 +0200
1.3 @@ -42,7 +42,7 @@
1.4 module.jar.dir=lib
1.5 cp.extra=${nb_all}/apisupport.harness/external/openjdk-javac-6-b12.jar
1.6
1.7 -spec.version.base=7.28.0
1.8 +spec.version.base=7.29.0
1.9
1.10 # For XMLSerializer, needed for XMLUtil.write to work w/ namespaces under JDK 1.4:
1.11
2.1 --- a/openide.util/src/org/openide/util/lookup/MetaInfServicesLookup.java Fri Sep 25 14:02:54 2009 +0200
2.2 +++ b/openide.util/src/org/openide/util/lookup/MetaInfServicesLookup.java Wed Sep 30 19:03:18 2009 +0200
2.3 @@ -113,15 +113,24 @@
2.4 protected final void beforeLookup(Lookup.Template t) {
2.5 Class c = t.getType();
2.6
2.7 + Collection<AbstractLookup.Pair<?>> toAdd = null;
2.8 + synchronized (this) {
2.9 + if (classes.get(c) == null) { // NOI18N
2.10 + toAdd = new ArrayList<Pair<?>>();
2.11 + } else {
2.12 + // ok, nothing needs to be done
2.13 + return;
2.14 + }
2.15 + }
2.16 + if (toAdd != null) {
2.17 + search(c, toAdd);
2.18 + }
2.19 synchronized (this) {
2.20 if (classes.put(c, "") == null) { // NOI18N
2.21 // Added new class, search for it.
2.22 LinkedHashSet<AbstractLookup.Pair<?>> arr = getPairsAsLHS();
2.23 - search(c, arr);
2.24 + arr.addAll(toAdd);
2.25 setPairs(arr, RP);
2.26 - } else {
2.27 - // ok, nothing needs to be done
2.28 - return;
2.29 }
2.30 }
2.31 }
3.1 --- a/openide.util/test/unit/src/org/openide/util/lookup/MetaInfServicesLookupTest.java Fri Sep 25 14:02:54 2009 +0200
3.2 +++ b/openide.util/test/unit/src/org/openide/util/lookup/MetaInfServicesLookupTest.java Wed Sep 30 19:03:18 2009 +0200
3.3 @@ -72,6 +72,7 @@
3.4 import org.bar.Comparator2;
3.5 import org.netbeans.junit.MockServices;
3.6 import org.netbeans.junit.NbTestCase;
3.7 +import org.openide.util.Exceptions;
3.8 import org.openide.util.Lookup;
3.9 import org.openide.util.LookupEvent;
3.10 import org.openide.util.LookupListener;
3.11 @@ -439,4 +440,56 @@
3.12 fail("Collections are different:\nFirst: " + col1 + "\nLast: " + col3);
3.13 }
3.14 }
3.15 +
3.16 + public void testContentionWhenLoadingMetainfServices() throws Exception {
3.17 + class My extends ClassLoader implements Runnable {
3.18 + Lookup query;
3.19 + Integer value;
3.20 +
3.21 + public void run() {
3.22 + value = query.lookup(Integer.class);
3.23 + }
3.24 +
3.25 +
3.26 + @Override
3.27 + protected URL findResource(String name) {
3.28 + waitForTask(name);
3.29 + return super.findResource(name);
3.30 + }
3.31 +
3.32 + @Override
3.33 + protected Enumeration<URL> findResources(String name) throws IOException {
3.34 + waitForTask(name);
3.35 + return super.findResources(name);
3.36 + }
3.37 +
3.38 + private synchronized void waitForTask(String name) {
3.39 + if (name.startsWith(prefix()) && Thread.currentThread().getName().contains("block")) {
3.40 + try {
3.41 + wait();
3.42 + } catch (InterruptedException ex) {
3.43 + Exceptions.printStackTrace(ex);
3.44 + }
3.45 + }
3.46 + }
3.47 + }
3.48 +
3.49 + My loader = new My();
3.50 + loader.query = createLookup(loader);
3.51 + Thread t = new Thread(loader, "block when querying");
3.52 + t.start();
3.53 + t.join(1000);
3.54 +
3.55 + // this blocks waiting for the waitForTask to finish
3.56 + // right now
3.57 + Float f = loader.query.lookup(Float.class);
3.58 + assertNull("Nothing found", f);
3.59 +
3.60 + synchronized (loader) {
3.61 + loader.notifyAll();
3.62 + }
3.63 + t.join();
3.64 +
3.65 + assertNull("Nothing found", loader.value);
3.66 + }
3.67 }
4.1 --- a/openide.util/test/unit/src/org/openide/util/test/TestFileUtils.java Fri Sep 25 14:02:54 2009 +0200
4.2 +++ b/openide.util/test/unit/src/org/openide/util/test/TestFileUtils.java Wed Sep 30 19:03:18 2009 +0200
4.3 @@ -53,6 +53,7 @@
4.4 import java.util.zip.CRC32;
4.5 import java.util.zip.ZipEntry;
4.6 import java.util.zip.ZipOutputStream;
4.7 +import junit.framework.Assert;
4.8
4.9 /**
4.10 * Common utility methods for massaging and inspecting files from tests.
4.11 @@ -146,4 +147,24 @@
4.12 os.close();
4.13 }
4.14
4.15 + /**
4.16 + * Make sure the timestamp on a file changes.
4.17 + * @param f a file to touch (make newer)
4.18 + * @param ref if not null, make f newer than this file; else make f newer than it was before
4.19 + */
4.20 + public static void touch(File f, File ref) throws IOException, InterruptedException {
4.21 + long older = f.lastModified();
4.22 + if (ref != null) {
4.23 + older = Math.max(older, ref.lastModified());
4.24 + }
4.25 + for (long pause = 1; pause < 9999; pause *= 2) {
4.26 + Thread.sleep(pause);
4.27 + f.setLastModified(System.currentTimeMillis());
4.28 + if (f.lastModified() > older) {
4.29 + return;
4.30 + }
4.31 + }
4.32 + Assert.fail("Did not manage to touch " + f);
4.33 + }
4.34 +
4.35 }