1 19 20 package org.netbeans.modules.masterfs.filebasedfs.fileobjects; 21 22 23 import org.openide.util.WeakSet; 24 25 import java.io.IOException ; 26 import java.lang.ref.Reference ; 27 import java.lang.ref.WeakReference ; 28 import java.util.Collections ; 29 import java.util.Map ; 30 import java.util.WeakHashMap ; 31 import org.netbeans.modules.masterfs.filebasedfs.utils.FSException; 32 33 public final class MutualExclusionSupport { 34 private static final MutualExclusionSupport DEFAULT = new MutualExclusionSupport(); 35 private static final Map exclusive = Collections.synchronizedMap(new WeakHashMap ()); 36 private static final Map shared = Collections.synchronizedMap(new WeakHashMap ()); 37 38 public static MutualExclusionSupport getDefault() { 39 return MutualExclusionSupport.DEFAULT; 40 } 41 42 private MutualExclusionSupport() { 43 } 44 45 public synchronized Closeable addResource(final Object key, final boolean isShared) throws IOException { 46 boolean isInUse = true; 47 final Map unexpected = (isShared) ? MutualExclusionSupport.exclusive : MutualExclusionSupport.shared; 48 final Map expected = (isShared) ? MutualExclusionSupport.shared : MutualExclusionSupport.exclusive; 49 50 final WeakSet unexpectedCounter = (WeakSet) unexpected.get(key); 51 WeakSet expectedCounter = (WeakSet) expected.get(key);; 52 53 for (int i = 0; i < 10 && isInUse; i++) { 54 isInUse = unexpectedCounter != null && unexpectedCounter.size() > 0; 55 56 if (!isInUse) { 57 if (expectedCounter == null) { 58 expectedCounter = new WeakSet(); 59 expected.put(key, expectedCounter); 60 } 61 isInUse = !isShared && expectedCounter.size() > 0; 62 } 63 64 if (isInUse) { 65 try { 66 wait(200); 67 } catch (InterruptedException e) { 68 break; 69 } 70 } 71 } 72 73 if (isInUse) { 74 if (isShared) { 75 FSException.io("EXC_CannotGetSharedAccess", key.toString()); } else { 77 FSException.io("EXC_CannotGetExclusiveAccess", key.toString()); } 79 } 80 81 82 final Closeable retVal = new Closeable(key, isShared); 83 expectedCounter.add(retVal); 84 return retVal; 85 } 86 87 private synchronized void removeResource(final Object key, final Object value, final boolean isShared) { 88 final Map expected = (isShared) ? MutualExclusionSupport.shared : MutualExclusionSupport.exclusive; 89 90 final WeakSet expectedCounter = (WeakSet) expected.get(key); 91 if (expectedCounter != null) { 92 expectedCounter.remove(value); 93 } 94 } 95 96 97 public final class Closeable { 98 private final boolean isShared; 99 private final Reference keyRef; 100 private boolean isClosed = false; 101 102 private Closeable(final Object key, final boolean isShared) { 103 this.isShared = isShared; 104 this.keyRef = new WeakReference (key); 105 } 106 107 108 public final void close() { 109 if (!isClosed()) { 110 isClosed = true; 111 final Object key = keyRef.get(); 112 if (key != null) { 113 removeResource(key, this, isShared); 114 } 115 } 116 } 117 118 public final boolean isClosed() { 119 return isClosed; 120 } 121 } 122 } 123 | Popular Tags |