From e9f87ad9a52bb14c842e12fe16c135f04050fa6d Mon Sep 17 00:00:00 2001 From: Alexey Kudravtsev Date: Wed, 12 Sep 2012 12:52:49 +0400 Subject: [PATCH] removed obsolete concurrency primitives --- .../reference/RefManagerImpl.java | 5 +- .../concurrency/readwrite/AbstractWaiter.java | 60 ---- .../concurrency/readwrite/ActiveRunnable.java | 21 -- .../readwrite/ActiveRunnableWrapper.java | 52 --- .../concurrency/readwrite/CommandWaiter.java | 51 --- .../readwrite/WriteActionWaiter.java | 59 --- .../readwrite/WriteActionWorker.java | 90 ----- .../vfs/newvfs/persistent/FSRecords.java | 28 +- .../application/options/PathMacrosImpl.java | 5 +- platform/util/src/com/intellij/Patches.java | 7 - .../com/intellij/openapi/util/FieldCache.java | 10 +- .../util/concurrency/DefaultLockAdapter.java | 38 -- .../DefaultReentrantReadWriteLockAdapter.java | 46 --- .../com/intellij/util/concurrency/JBLock.java | 25 -- .../concurrency/JBReentrantReadWriteLock.java | 29 -- .../util/concurrency/LockFactory.java | 35 -- .../util/concurrency/ReadWriteLock.java | 84 ----- ...eentrantWriterPreferenceReadWriteLock.java | 233 ------------ .../com/intellij/util/concurrency/Sync.java | 340 ------------------ .../util/concurrency/SyncAdapterLock.java | 41 --- ...nchronizedBasedReentrantReadWriteLock.java | 44 --- .../WriterPreferenceReadWriteLock.java | 315 ---------------- .../containers/LockPoolSynchronizedMap.java | 58 +-- .../StripedJBReentrantReadWriteLocks.java | 40 --- 24 files changed, 58 insertions(+), 1658 deletions(-) delete mode 100644 platform/platform-api/src/com/intellij/util/concurrency/readwrite/AbstractWaiter.java delete mode 100644 platform/platform-api/src/com/intellij/util/concurrency/readwrite/ActiveRunnable.java delete mode 100644 platform/platform-api/src/com/intellij/util/concurrency/readwrite/ActiveRunnableWrapper.java delete mode 100644 platform/platform-api/src/com/intellij/util/concurrency/readwrite/CommandWaiter.java delete mode 100644 platform/platform-api/src/com/intellij/util/concurrency/readwrite/WriteActionWaiter.java delete mode 100644 platform/platform-api/src/com/intellij/util/concurrency/readwrite/WriteActionWorker.java delete mode 100644 platform/util/src/com/intellij/util/concurrency/DefaultLockAdapter.java delete mode 100644 platform/util/src/com/intellij/util/concurrency/DefaultReentrantReadWriteLockAdapter.java delete mode 100644 platform/util/src/com/intellij/util/concurrency/JBLock.java delete mode 100644 platform/util/src/com/intellij/util/concurrency/JBReentrantReadWriteLock.java delete mode 100644 platform/util/src/com/intellij/util/concurrency/LockFactory.java delete mode 100644 platform/util/src/com/intellij/util/concurrency/ReadWriteLock.java delete mode 100644 platform/util/src/com/intellij/util/concurrency/ReentrantWriterPreferenceReadWriteLock.java delete mode 100644 platform/util/src/com/intellij/util/concurrency/Sync.java delete mode 100644 platform/util/src/com/intellij/util/concurrency/SyncAdapterLock.java delete mode 100644 platform/util/src/com/intellij/util/concurrency/SynchronizedBasedReentrantReadWriteLock.java delete mode 100644 platform/util/src/com/intellij/util/concurrency/WriterPreferenceReadWriteLock.java delete mode 100644 platform/util/src/com/intellij/util/containers/StripedJBReentrantReadWriteLocks.java diff --git a/platform/lang-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java b/platform/lang-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java index e5b1a24a19fa..ff4ec6e20672 100644 --- a/platform/lang-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInspection/reference/RefManagerImpl.java @@ -48,14 +48,13 @@ import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.impl.light.LightElement; -import com.intellij.util.concurrency.JBReentrantReadWriteLock; -import com.intellij.util.concurrency.LockFactory; import com.intellij.util.containers.ContainerUtil; import gnu.trove.THashMap; import org.jdom.Element; import org.jetbrains.annotations.Nullable; import java.util.*; +import java.util.concurrent.locks.ReentrantReadWriteLock; public class RefManagerImpl extends RefManager { private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.reference.RefManager"); @@ -80,7 +79,7 @@ public class RefManagerImpl extends RefManager { private final Map myExtensions = new HashMap(); private final HashMap myLanguageExtensions = new HashMap(); - private final JBReentrantReadWriteLock myLock = LockFactory.createReadWriteLock(); + private final ReentrantReadWriteLock myLock = new ReentrantReadWriteLock(); public RefManagerImpl(Project project, AnalysisScope scope, GlobalInspectionContextImpl context) { myDeclarationsFound = false; diff --git a/platform/platform-api/src/com/intellij/util/concurrency/readwrite/AbstractWaiter.java b/platform/platform-api/src/com/intellij/util/concurrency/readwrite/AbstractWaiter.java deleted file mode 100644 index adda8f80d897..000000000000 --- a/platform/platform-api/src/com/intellij/util/concurrency/readwrite/AbstractWaiter.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.util.concurrency.readwrite; - -import com.intellij.openapi.application.ApplicationManager; - -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; - -public class AbstractWaiter implements Runnable { - - private boolean myFinishedFlag; - - public void setFinished(boolean aFinishedFlag) { - myFinishedFlag = aFinishedFlag; - } - - private boolean finished() { - return myFinishedFlag; - } - - public void run() { - while (!finished()) { - try { - Thread.sleep(10); - } - catch (InterruptedException e) { - return; - } - } - } - - public void waitForCompletion() { - waitForCompletion(0); - } - - public void waitForCompletion(long aTimeout) { - try { - final Future future = ApplicationManager.getApplication().executeOnPooledThread(this); - if (aTimeout > 0) future.get(aTimeout, TimeUnit.MILLISECONDS); - else future.get(); - } - catch (Exception e) { - return; - } - } -} diff --git a/platform/platform-api/src/com/intellij/util/concurrency/readwrite/ActiveRunnable.java b/platform/platform-api/src/com/intellij/util/concurrency/readwrite/ActiveRunnable.java deleted file mode 100644 index 5cbc64dd9171..000000000000 --- a/platform/platform-api/src/com/intellij/util/concurrency/readwrite/ActiveRunnable.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.util.concurrency.readwrite; - -public interface ActiveRunnable { - - Object run() throws Throwable; -} diff --git a/platform/platform-api/src/com/intellij/util/concurrency/readwrite/ActiveRunnableWrapper.java b/platform/platform-api/src/com/intellij/util/concurrency/readwrite/ActiveRunnableWrapper.java deleted file mode 100644 index e376b0c69fc5..000000000000 --- a/platform/platform-api/src/com/intellij/util/concurrency/readwrite/ActiveRunnableWrapper.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.util.concurrency.readwrite; - -public abstract class ActiveRunnableWrapper implements Runnable { - - private Object myResult; - - private Throwable myException; - - public void run() { - try { - myResult = doRun(); - } - catch (Throwable aThrowable) { - myException = aThrowable; - } - } - - public Object getResult() { - return myResult; - } - - private Throwable getException() { - return myException; - } - - private boolean hasException() { - return null != getException(); - } - - public void throwException() throws Throwable { - if (hasException()) { - throw getException(); - } - } - - public abstract Object doRun() throws Throwable; -} diff --git a/platform/platform-api/src/com/intellij/util/concurrency/readwrite/CommandWaiter.java b/platform/platform-api/src/com/intellij/util/concurrency/readwrite/CommandWaiter.java deleted file mode 100644 index cb1aa9678498..000000000000 --- a/platform/platform-api/src/com/intellij/util/concurrency/readwrite/CommandWaiter.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.util.concurrency.readwrite; - -import com.intellij.openapi.command.CommandEvent; -import com.intellij.openapi.command.CommandListener; -import com.intellij.openapi.command.CommandProcessor; - -public class CommandWaiter extends AbstractWaiter implements CommandListener { - - private final Runnable myCommandRunnable; - - public CommandWaiter(Runnable aCommandRunnable) { - myCommandRunnable = aCommandRunnable; - - setFinished(false); - CommandProcessor.getInstance().addCommandListener(this); - } - - public void beforeCommandFinished(CommandEvent event) { - } - - public void commandFinished(CommandEvent event) { - if (event.getCommand() == myCommandRunnable) { - CommandProcessor.getInstance().removeCommandListener(this); - setFinished(true); - } - } - - public void commandStarted(CommandEvent event) { - } - - public void undoTransparentActionStarted() { - } - - public void undoTransparentActionFinished() { - } -} diff --git a/platform/platform-api/src/com/intellij/util/concurrency/readwrite/WriteActionWaiter.java b/platform/platform-api/src/com/intellij/util/concurrency/readwrite/WriteActionWaiter.java deleted file mode 100644 index 6fdb69147408..000000000000 --- a/platform/platform-api/src/com/intellij/util/concurrency/readwrite/WriteActionWaiter.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.util.concurrency.readwrite; - -import com.intellij.openapi.application.ApplicationListener; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.wm.IdeFrame; - -public class WriteActionWaiter extends AbstractWaiter implements ApplicationListener { - - private final Runnable myActionRunnable; - - public WriteActionWaiter(Runnable aActionRunnable) { - myActionRunnable = aActionRunnable; - - setFinished(false); - ApplicationManager.getApplication().addApplicationListener(this); - } - - public void writeActionFinished(Object aRunnable) { - if (aRunnable == myActionRunnable) { - setFinished(true); - - ApplicationManager.getApplication().removeApplicationListener(this); - } - } - - public void applicationExiting() { - } - - public void beforeWriteActionStart(Object action) { - } - - public boolean canExitApplication() { - return true; - } - - public void writeActionStarted(Object action) { - } - - public void applicationActivated(IdeFrame ideFrame) { - } - - public void applicationDeactivated(IdeFrame ideFrame) { - } -} diff --git a/platform/platform-api/src/com/intellij/util/concurrency/readwrite/WriteActionWorker.java b/platform/platform-api/src/com/intellij/util/concurrency/readwrite/WriteActionWorker.java deleted file mode 100644 index 3724cbe93951..000000000000 --- a/platform/platform-api/src/com/intellij/util/concurrency/readwrite/WriteActionWorker.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.util.concurrency.readwrite; - -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.command.CommandProcessor; -import com.intellij.openapi.project.Project; - -import javax.swing.*; -import java.awt.*; - - -public abstract class WriteActionWorker extends ActiveRunnableWrapper { - - private void start() { - WriteActionWaiter waiter = new WriteActionWaiter(this); - - if (EventQueue.isDispatchThread()) { - ApplicationManager.getApplication().runWriteAction(WriteActionWorker.this); - } else { - SwingUtilities.invokeLater(new Runnable() { - public void run() { - ApplicationManager.getApplication().runWriteAction(WriteActionWorker.this); - } - }); - } - - waiter.waitForCompletion(); - } - - public static Object run(final ActiveRunnable aActiveRunnable) throws Throwable { - WriteActionWorker worker = new WriteActionWorker() { - public Object doRun() throws Throwable { - return aActiveRunnable.run(); - } - }; - - worker.start(); - worker.throwException(); - - return worker.getResult(); - } - - private static class CommandWrapper extends ActiveRunnableWrapper { - - private final ActiveRunnable myWriteActionRunnable; - - public CommandWrapper(ActiveRunnable aWriteActionRunnable) { - myWriteActionRunnable = aWriteActionRunnable; - } - - public Object doRun() throws Throwable { - return WriteActionWorker.run(myWriteActionRunnable); - } - } - - public static Object runInCommand(final Project project, final ActiveRunnable aActiveRunnable, final String aCommandName) throws Throwable { - final CommandWrapper commandWrapper = new CommandWrapper(aActiveRunnable); - - CommandWaiter commandWaiter = new CommandWaiter(commandWrapper); - - if (EventQueue.isDispatchThread()) { - CommandProcessor.getInstance().executeCommand(project, commandWrapper, aCommandName, null); - } else { - SwingUtilities.invokeLater(new Runnable() { - public void run() { - CommandProcessor.getInstance().executeCommand(project, commandWrapper, aCommandName, null); - } - }); - } - - commandWaiter.waitForCompletion(); - commandWrapper.throwException(); - - return commandWrapper.getResult(); - } -} diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java index 312cea787b75..0e4cb302c64f 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/FSRecords.java @@ -30,9 +30,6 @@ import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream; import com.intellij.openapi.util.io.ByteSequence; import com.intellij.openapi.util.io.FileUtil; import com.intellij.util.ArrayUtil; -import com.intellij.util.concurrency.JBLock; -import com.intellij.util.concurrency.JBReentrantReadWriteLock; -import com.intellij.util.concurrency.LockFactory; import com.intellij.util.containers.IntArrayList; import com.intellij.util.io.*; import com.intellij.util.io.DataOutputStream; @@ -46,6 +43,7 @@ import javax.swing.*; import java.awt.*; import java.io.*; import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.locks.ReentrantReadWriteLock; @SuppressWarnings({"PointlessArithmeticExpression", "HardCodedStringLiteral"}) public class FSRecords implements Forceable { @@ -87,8 +85,8 @@ public class FSRecords implements Forceable { private static final String CHILDREN_ATT = "FsRecords.DIRECTORY_CHILDREN"; - private static final JBLock r; - private static final JBLock w; + private static final ReentrantReadWriteLock.ReadLock r; + private static final ReentrantReadWriteLock.WriteLock w; private static volatile int ourLocalModificationCount = 0; private static volatile boolean ourIsDisposed; @@ -100,12 +98,12 @@ public class FSRecords implements Forceable { //noinspection ConstantConditions assert HEADER_SIZE <= RECORD_SIZE; - JBReentrantReadWriteLock lock = LockFactory.createReadWriteLock(); + ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); r = lock.readLock(); w = lock.writeLock(); } - private static class DbConnection { + static class DbConnection { private static boolean ourInitialized; private static final TObjectIntHashMap myAttributeIds = new TObjectIntHashMap(); @@ -411,7 +409,7 @@ public class FSRecords implements Forceable { myRecords.putInt(HEADER_CONNECTION_STATUS_OFFSET, SAFELY_CLOSED_MAGIC); } - public static void cleanRecord(final int id) { + static void cleanRecord(int id) { myRecords.put(id * RECORD_SIZE, ZEROES, 0, RECORD_SIZE); } @@ -615,7 +613,7 @@ public class FSRecords implements Forceable { } } - private static void addToFreeRecordsList(int id) { + static void addToFreeRecordsList(int id) { DbConnection.addFreeRecord(id); setFlags(id, FREE_RECORD_FLAG, false); } @@ -1409,14 +1407,14 @@ public class FSRecords implements Forceable { final IntArrayList validAttributeIds) { int parentId = getParent(id); assert parentId >= 0 && parentId < recordCount; - if (parentId > 0) { - final int parentFlags = getFlags(parentId); - assert (parentFlags & FREE_RECORD_FLAG) == 0; - assert (parentFlags & PersistentFS.IS_DIRECTORY_FLAG) != 0; + if (parentId > 0 && getParent(parentId) > 0) { + int parentFlags = getFlags(parentId); + assert (parentFlags & FREE_RECORD_FLAG) == 0 : parentId + ": "+Integer.toHexString(parentFlags); + assert (parentFlags & PersistentFS.IS_DIRECTORY_FLAG) != 0 : parentId + ": "+Integer.toHexString(parentFlags); } String name = getName(id); - LOG.assertTrue(parentId == 0 || name.length() > 0, "File with empty name found under " + getName(parentId) + ", id=" + id); + LOG.assertTrue(parentId == 0 || !name.isEmpty(), "File with empty name found under " + getName(parentId) + ", id=" + id); checkContentsStorageSanity(id); checkAttributesStorageSanity(id, usedAttributeRecordIds, validAttributeIds); @@ -1460,7 +1458,7 @@ public class FSRecords implements Forceable { assert !usedAttributeRecordIds.contains(attDataRecordId); usedAttributeRecordIds.add(attDataRecordId); if (!validAttributeIds.contains(attId)) { - assert getNames().valueOf(attId).length() > 0; + assert !getNames().valueOf(attId).isEmpty(); validAttributeIds.add(attId); } getAttributesStorage().checkSanity(attDataRecordId); diff --git a/platform/projectModel-impl/src/com/intellij/application/options/PathMacrosImpl.java b/platform/projectModel-impl/src/com/intellij/application/options/PathMacrosImpl.java index 759b72f101e1..9f0c20cb8eed 100644 --- a/platform/projectModel-impl/src/com/intellij/application/options/PathMacrosImpl.java +++ b/platform/projectModel-impl/src/com/intellij/application/options/PathMacrosImpl.java @@ -28,8 +28,6 @@ import com.intellij.openapi.util.WriteExternalException; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.SystemProperties; -import com.intellij.util.concurrency.JBReentrantReadWriteLock; -import com.intellij.util.concurrency.LockFactory; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashMap; import gnu.trove.THashSet; @@ -38,6 +36,7 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import java.util.*; +import java.util.concurrent.locks.ReentrantReadWriteLock; /** * @author dsl @@ -46,7 +45,7 @@ public class PathMacrosImpl extends PathMacros implements ApplicationComponent, private static final Logger LOG = Logger.getInstance("#com.intellij.application.options.PathMacrosImpl"); private final Map myLegacyMacros = new HashMap(); private final Map myMacros = new HashMap(); - private final JBReentrantReadWriteLock myLock = LockFactory.createReadWriteLock(); + private final ReentrantReadWriteLock myLock = new ReentrantReadWriteLock(); private final List myIgnoredMacros = ContainerUtil.createEmptyCOWList(); @NonNls diff --git a/platform/util/src/com/intellij/Patches.java b/platform/util/src/com/intellij/Patches.java index f932d503afec..6e19ea18878a 100644 --- a/platform/util/src/com/intellij/Patches.java +++ b/platform/util/src/com/intellij/Patches.java @@ -74,13 +74,6 @@ public class Patches { */ public static final boolean APPLE_BUG_ID_3716835 = SystemInfo.isMac && !SystemInfo.isJavaVersionAtLeast("1.4.2.5"); - /** - * Use of JDK1.5 ReentrantReadWriteLock API eventually leads to JVM lock-up or core dump crashes. - * With this flag true, API is wrapped with alternative implementation via early days Doug Lea's API. - * @see com.intellij.util.concurrency.LockFactory - */ - public static final boolean APPLE_BUG_ID_5359442 = SystemInfo.isMac && (!SystemInfo.isMacOSLeopard || !SystemInfo.isJavaVersionAtLeast("1.5.0_16")); - /** * Lion eAWT FullScreen mode leads to visual artifacts. */ diff --git a/platform/util/src/com/intellij/openapi/util/FieldCache.java b/platform/util/src/com/intellij/openapi/util/FieldCache.java index 886efe5f1fe7..f60890f73d4b 100644 --- a/platform/util/src/com/intellij/openapi/util/FieldCache.java +++ b/platform/util/src/com/intellij/openapi/util/FieldCache.java @@ -16,17 +16,15 @@ package com.intellij.openapi.util; -import com.intellij.util.concurrency.JBLock; -import com.intellij.util.concurrency.JBReentrantReadWriteLock; -import com.intellij.util.concurrency.LockFactory; +import java.util.concurrent.locks.ReentrantReadWriteLock; public abstract class FieldCache { private static final RecursionGuard ourGuard = RecursionManager.createGuard("fieldCache"); - private final JBLock r; - private final JBLock w; + private final ReentrantReadWriteLock.ReadLock r; + private final ReentrantReadWriteLock.WriteLock w; protected FieldCache() { - JBReentrantReadWriteLock ourLock = LockFactory.createReadWriteLock(); + ReentrantReadWriteLock ourLock = new ReentrantReadWriteLock(); r = ourLock.readLock(); w = ourLock.writeLock(); } diff --git a/platform/util/src/com/intellij/util/concurrency/DefaultLockAdapter.java b/platform/util/src/com/intellij/util/concurrency/DefaultLockAdapter.java deleted file mode 100644 index 2b8dbe0d9d43..000000000000 --- a/platform/util/src/com/intellij/util/concurrency/DefaultLockAdapter.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @author max - */ -package com.intellij.util.concurrency; - -import java.util.concurrent.locks.Lock; - -public class DefaultLockAdapter implements JBLock { - private final Lock myAdaptee; - - public DefaultLockAdapter(final Lock adaptee) { - myAdaptee = adaptee; - } - - public void lock() { - myAdaptee.lock(); - } - - public void unlock() { - myAdaptee.unlock(); - } -} \ No newline at end of file diff --git a/platform/util/src/com/intellij/util/concurrency/DefaultReentrantReadWriteLockAdapter.java b/platform/util/src/com/intellij/util/concurrency/DefaultReentrantReadWriteLockAdapter.java deleted file mode 100644 index 5ddf7fb39c62..000000000000 --- a/platform/util/src/com/intellij/util/concurrency/DefaultReentrantReadWriteLockAdapter.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @author max - */ -package com.intellij.util.concurrency; - -import java.util.concurrent.locks.ReentrantReadWriteLock; - -public class DefaultReentrantReadWriteLockAdapter implements JBReentrantReadWriteLock { - private final DefaultLockAdapter myReadLock; - private final DefaultLockAdapter myWriteLock; - private final ReentrantReadWriteLock myAdaptee; - - public DefaultReentrantReadWriteLockAdapter() { - myAdaptee = new ReentrantReadWriteLock(); - myReadLock = new DefaultLockAdapter(myAdaptee.readLock()); - myWriteLock = new DefaultLockAdapter(myAdaptee.writeLock()); - } - - public JBLock readLock() { - return myReadLock; - } - - public JBLock writeLock() { - return myWriteLock; - } - - public boolean isWriteLockedByCurrentThread() { - return myAdaptee.isWriteLockedByCurrentThread(); - } -} \ No newline at end of file diff --git a/platform/util/src/com/intellij/util/concurrency/JBLock.java b/platform/util/src/com/intellij/util/concurrency/JBLock.java deleted file mode 100644 index 398f9874b90b..000000000000 --- a/platform/util/src/com/intellij/util/concurrency/JBLock.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @author max - */ -package com.intellij.util.concurrency; - -public interface JBLock { - void lock(); - void unlock(); -} \ No newline at end of file diff --git a/platform/util/src/com/intellij/util/concurrency/JBReentrantReadWriteLock.java b/platform/util/src/com/intellij/util/concurrency/JBReentrantReadWriteLock.java deleted file mode 100644 index 9430087e6a3e..000000000000 --- a/platform/util/src/com/intellij/util/concurrency/JBReentrantReadWriteLock.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @author max - */ -package com.intellij.util.concurrency; - -/** - * @see LockFactory - */ -public interface JBReentrantReadWriteLock { - JBLock readLock(); - JBLock writeLock(); - boolean isWriteLockedByCurrentThread(); -} \ No newline at end of file diff --git a/platform/util/src/com/intellij/util/concurrency/LockFactory.java b/platform/util/src/com/intellij/util/concurrency/LockFactory.java deleted file mode 100644 index 668ee58f59ca..000000000000 --- a/platform/util/src/com/intellij/util/concurrency/LockFactory.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @author max - */ -package com.intellij.util.concurrency; - -import com.intellij.Patches; - -public class LockFactory { - private LockFactory() {} - - public static JBReentrantReadWriteLock createReadWriteLock() { - if (Patches.APPLE_BUG_ID_5359442) { - return new SynchronizedBasedReentrantReadWriteLock(); - } - else { - return new DefaultReentrantReadWriteLockAdapter(); - } - } -} \ No newline at end of file diff --git a/platform/util/src/com/intellij/util/concurrency/ReadWriteLock.java b/platform/util/src/com/intellij/util/concurrency/ReadWriteLock.java deleted file mode 100644 index d98473dcb400..000000000000 --- a/platform/util/src/com/intellij/util/concurrency/ReadWriteLock.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -package com.intellij.util.concurrency; - -/** - * ReadWriteLocks maintain a pair of associated locks. - * The readLock may be held simultanously by multiple - * reader threads, so long as there are no writers. The writeLock - * is exclusive. ReadWrite locks are generally preferable to - * plain Sync locks or synchronized methods in cases where: - *
    - *
  • The methods in a class can be cleanly separated into - * those that only access (read) data vs those that - * modify (write). - *
  • Target applications generally have more readers than writers. - *
  • The methods are relatively time-consuming (as a rough - * rule of thumb, exceed more than a hundred instructions), so it - * pays to introduce a bit more overhead associated with - * ReadWrite locks compared to simple synchronized methods etc - * in order to allow concurrency among reader threads. - * - *
- * Different implementation classes differ in policies surrounding - * which threads to prefer when there is - * contention. By far, the most commonly useful policy is - * WriterPreferenceReadWriteLock. The other implementations - * are targeted for less common, niche applications. - *

- * Standard usage: - *

- * class X {
- *   ReadWriteLock rw;
- *   // ...
- *
- *   public void read() throws InterruptedException { 
- *     rw.readLock().acquire();
- *     try {
- *       // ... do the read
- *     }
- *     finally {
- *       rw.readlock().release()
- *     }
- *   }
- *
- *
- *   public void write() throws InterruptedException { 
- *     rw.writeLock().acquire();
- *     try {
- *       // ... do the write
- *     }
- *     finally {
- *       rw.writelock().release()
- *     }
- *   }
- * }
- * 
- * @see Sync - *

[ Introduction to this package. ] - -**/ - -public interface ReadWriteLock { - /** get the readLock **/ - Sync readLock(); - - /** get the writeLock **/ - Sync writeLock(); -} - diff --git a/platform/util/src/com/intellij/util/concurrency/ReentrantWriterPreferenceReadWriteLock.java b/platform/util/src/com/intellij/util/concurrency/ReentrantWriterPreferenceReadWriteLock.java deleted file mode 100644 index 25f8349816b8..000000000000 --- a/platform/util/src/com/intellij/util/concurrency/ReentrantWriterPreferenceReadWriteLock.java +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.intellij.util.concurrency; - -import gnu.trove.TIntArrayList; - -import java.util.ArrayList; - -/** - * A writer-preference ReadWriteLock that allows both readers and - * writers to reacquire - * read or write locks in the style of a ReentrantLock. - * Readers are not allowed until all write locks held by - * the writing thread have been released. - * Among other applications, reentrancy can be useful when - * write locks are held during calls or callbacks to methods that perform - * reads under read locks. - *

- * Sample usage. Here is a code sketch showing how to exploit - * reentrancy to perform lock downgrading after updating a cache: - *

- * class CachedData {
- *   Object data;
- *   volatile boolean cacheValid;
- *   ReentrantWriterPreferenceReadWriteLock rwl = ...
- *
- *   void processCachedData() {
- *     rwl.readLock().acquire();
- *     if (!cacheValid) {
- *
- *        // upgrade lock:
- *        rwl.readLock().release();   // must release first to obtain writelock
- *        rwl.writeLock().acquire();
- *        if (!cacheValid) { // recheck
- *          data = ...
- *          cacheValid = true;
- *        }
- *        // downgrade lock
- *        rwl.readLock().acquire();  // reacquire read without giving up lock
- *        rwl.writeLock().release(); // release write, still hold read
- *     }
- *
- *     use(data);
- *     rwl.readLock().release();
- *   }
- * }
- * 
- * - * - *

[ Introduction to this package. ] - **/ - -public class ReentrantWriterPreferenceReadWriteLock extends WriterPreferenceReadWriteLock { - - /** Number of acquires on write lock by activeWriter_ thread **/ - private long writeHolds_ = 0; - - private final ThreadToCountMap readers_ = new ThreadToCountMap(); - - private final ThreadLocal hasReadLock = new ThreadLocal() { - @Override - protected Boolean initialValue() { - return Boolean.FALSE; - } - }; - - private final ThreadLocal hasWriteLock = new ThreadLocal() { - @Override - protected Boolean initialValue() { - return Boolean.FALSE; - } - }; - - public boolean isReadLockAcquired() { - return hasReadLock.get(); - } - - public boolean isWriteLockAcquired() { - return hasWriteLock.get(); - } - - public synchronized boolean isReadLockAcquired(Thread thread){ - return readers_.get(thread) > 0; - } - - public synchronized boolean isWriteLockAcquired(Thread thread){ - return activeWriter_ == thread; - } - - protected boolean allowReader() { - // [Valentin] Changed policy so that readers are allowed while there are waiting writers - // [cdr]: No more! - return (activeWriter_ == null && waitingWriters_ == 0) || - activeWriter_ == Thread.currentThread(); - } - - protected synchronized boolean startRead() { - Thread t = Thread.currentThread(); - int c = readers_.get(t); - if (c > 0) { // already held -- just increment hold count - readers_.put(t, c + 1); - ++activeReaders_; - return true; - } - else if (allowReader()) { - hasReadLock.set(true); - readers_.put(t, 1); - ++activeReaders_; - return true; - } - else - return false; - } - - protected synchronized boolean startWrite() { - if (activeWriter_ == Thread.currentThread()) { // already held; re-acquire - ++writeHolds_; - return true; - } - else if (writeHolds_ == 0) { - if (activeReaders_ == 0 || - (readers_.size() == 1 && - readers_.get(Thread.currentThread()) > 0)) { - activeWriter_ = Thread.currentThread(); - hasWriteLock.set(true); - writeHolds_ = 1; - return true; - } - else - return false; - } - else - return false; - } - - - protected synchronized Signaller endRead() { - --activeReaders_; - Thread t = Thread.currentThread(); - int c = readers_.get(t); - if (c != 1) { // more than one hold; decrement count - readers_.put(t, c - 1); - return null; - } - else { - readers_.put(t, 0); - hasReadLock.set(false); - - if (writeHolds_ > 0) { // a write lock is still held by current thread - return null; - } - else if (/*activeReaders_ == 0 && */activeReaders_ <= 1 && waitingWriters_ > 0) { - // [Valentin] commented out check for activeReaders == 0 - it's incorrect when waiting writer is already a reader!! - return writerLock_; - } - else{ - return null; - } - } - } - - protected synchronized Signaller endWrite() { - --writeHolds_; - if (writeHolds_ > 0) // still being held - return null; - else { - activeWriter_ = null; - hasWriteLock.set(false); - if (waitingReaders_ > 0 && allowReader()) - return readerLock_; - else if (waitingWriters_ > 0) - return writerLock_; - else - return null; - } - } - - private static final class ThreadToCountMap{ - private final ArrayList myThreads = new ArrayList(); - private final TIntArrayList myCounters = new TIntArrayList(); - - private Thread myLastThread = null; // optimization - private int myLastCounter; - - public int get(Thread thread){ - if (thread == myLastThread) return myLastCounter; - int index = myThreads.indexOf(thread); - int result = index >= 0 ? myCounters.getQuick(index) : 0; - myLastThread = thread; - myLastCounter = result; - return result; - } - - public void put(Thread thread, int count){ - myLastThread = null; - int index = myThreads.indexOf(thread); - if (index >= 0){ - if (count == 0){ - myThreads.remove(index); - myCounters.remove(index); - } - else{ - myCounters.setQuick(index, count); - } - } - else{ - if (count != 0){ - myThreads.add(thread); - myCounters.add(count); - } - } - } - - public int size(){ - return myThreads.size(); - } - } -} - diff --git a/platform/util/src/com/intellij/util/concurrency/Sync.java b/platform/util/src/com/intellij/util/concurrency/Sync.java deleted file mode 100644 index af4a413d62e3..000000000000 --- a/platform/util/src/com/intellij/util/concurrency/Sync.java +++ /dev/null @@ -1,340 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.intellij.util.concurrency; - -/** - * Main interface for locks, gates, and conditions. - *

- * Sync objects isolate waiting and notification for particular - * logical states, resource availability, events, and the like that are - * shared across multiple threads. Use of Syncs sometimes - * (but by no means always) adds flexibility and efficiency - * compared to the use of plain java monitor methods - * and locking, and are sometimes (but by no means always) - * simpler to program with. - *

- * - * Most Syncs are intended to be used primarily (although - * not exclusively) in before/after constructions such as: - *

- * class X {
- *   Sync gate;
- *   // ...
- *
- *   public void m() { 
- *     try {
- *       gate.acquire();  // block until condition holds
- *       try {
- *         // ... method body
- *       }
- *       finally {
- *         gate.release()
- *       }
- *     }
- *     catch (InterruptedException ex) {
- *       // ... evasive action
- *     }
- *   }
- *
- *   public void m2(Sync cond) { // use supplied condition
- *     try {
- *       if (cond.attempt(10)) {         // try the condition for 10 ms
- *         try {
- *           // ... method body
- *         }
- *         finally {
- *           cond.release()
- *         }
- *       }
- *     }
- *     catch (InterruptedException ex) {
- *       // ... evasive action
- *     }
- *   }
- * }
- * 
- * Syncs may be used in somewhat tedious but more flexible replacements - * for built-in Java synchronized blocks. For example: - *
- * class HandSynched {          
- *   private double state_ = 0.0; 
- *   private final Sync lock;  // use lock type supplied in constructor
- *   public HandSynched(Sync l) { lock = l; } 
- *
- *   public void changeState(double d) {
- *     try {
- *       lock.acquire(); 
- *       try     { state_ = updateFunction(d); } 
- *       finally { lock.release(); }
- *     } 
- *     catch(InterruptedException ex) { }
- *   }
- *
- *   public double getState() {
- *     double d = 0.0;
- *     try {
- *       lock.acquire(); 
- *       try     { d = accessFunction(state_); }
- *       finally { lock.release(); }
- *     } 
- *     catch(InterruptedException ex){}
- *     return d;
- *   }
- *   private double updateFunction(double d) { ... }
- *   private double accessFunction(double d) { ... }
- * }
- * 
- * If you have a lot of such methods, and they take a common - * form, you can standardize this using wrappers. Some of these - * wrappers are standardized in LockedExecutor, but you can make others. - * For example: - *
- * class HandSynchedV2 {          
- *   private double state_ = 0.0; 
- *   private final Sync lock;  // use lock type supplied in constructor
- *   public HandSynchedV2(Sync l) { lock = l; } 
- *
- *   protected void runSafely(Runnable r) {
- *     try {
- *       lock.acquire();
- *       try { r.run(); }
- *       finally { lock.release(); }
- *     }
- *     catch (InterruptedException ex) { // propagate without throwing
- *       Thread.currentThread().interrupt();
- *     }
- *   }
- *
- *   public void changeState(double d) {
- *     runSafely(new Runnable() {
- *       public void run() { state_ = updateFunction(d); } 
- *     });
- *   }
- *   // ...
- * }
- * 
- *

- * One reason to bother with such constructions is to use deadlock- - * avoiding back-offs when dealing with locks involving multiple objects. - * For example, here is a Cell class that uses attempt to back-off - * and retry if two Cells are trying to swap values with each other - * at the same time. - *

- * class Cell {
- *   long value;
- *   Sync lock = ... // some sync implementation class
- *   void swapValue(Cell other) {
- *     for (;;) { 
- *       try {
- *         lock.acquire();
- *         try {
- *           if (other.lock.attempt(100)) {
- *             try { 
- *               long t = value; 
- *               value = other.value;
- *               other.value = t;
- *               return;
- *             }
- *             finally { other.lock.release(); }
- *           }
- *         }
- *         finally { lock.release(); }
- *       } 
- *       catch (InterruptedException ex) { return; }
- *     }
- *   }
- * }
- *
- *

- * Here is an even fancier version, that uses lock re-ordering - * upon conflict: - *

- * class Cell { 
- *   long value;
- *   Sync lock = ...;
- *   private static boolean trySwap(Cell a, Cell b) {
- *     a.lock.acquire();
- *     try {
- *       if (!b.lock.attempt(0)) 
- *         return false;
- *       try { 
- *         long t = a.value;
- *         a.value = b.value;
- *         b.value = t;
- *         return true;
- *       }
- *       finally { other.lock.release(); }
- *     }
- *     finally { lock.release(); }
- *     return false;
- *   }
- *
- *  void swapValue(Cell other) {
- *    try {
- *      while (!trySwap(this, other) &&
- *            !tryswap(other, this)) 
- *        Thread.sleep(1);
- *    }
- *    catch (InterruptedException ex) { return; }
- *  }
- *}
- *
- *

- * Interruptions are in general handled as early as possible. - * Normally, InterruptionExceptions are thrown - * in acquire and attempt(msec) if interruption - * is detected upon entry to the method, as well as in any - * later context surrounding waits. - * However, interruption status is ignored in release(); - *

- * Timed versions of attempt report failure via return value. - * If so desired, you can transform such constructions to use exception - * throws via - *

- *   if (!c.attempt(timeval)) throw new TimeoutException(timeval);
- * 
- *

- * The TimoutSync wrapper class can be used to automate such usages. - *

- * All time values are expressed in milliseconds as longs, which have a maximum - * value of Long.MAX_VALUE, or almost 300,000 centuries. It is not - * known whether JVMs actually deal correctly with such extreme values. - * For convenience, some useful time values are defined as static constants. - *

- * All implementations of the three Sync methods guarantee to - * somehow employ Java synchronized methods or blocks, - * and so entail the memory operations described in JLS - * chapter 17 which ensure that variables are loaded and flushed - * within before/after constructions. - *

- * Syncs may also be used in spinlock constructions. Although - * it is normally best to just use acquire(), various forms - * of busy waits can be implemented. For a simple example - * (but one that would probably never be preferable to using acquire()): - *

- * class X {
- *   Sync lock = ...
- *   void spinUntilAcquired() throws InterruptedException {
- *     // Two phase. 
- *     // First spin without pausing.
- *     int purespins = 10; 
- *     for (int i = 0; i < purespins; ++i) {
- *       if (lock.attempt(0))
- *         return true;
- *     }
- *     // Second phase - use timed waits
- *     long waitTime = 1; // 1 millisecond
- *     for (;;) {
- *       if (lock.attempt(waitTime))
- *         return true;
- *       else 
- *         waitTime = waitTime * 3 / 2 + 1; // increase 50% 
- *     }
- *   }
- * }
- * 
- *

- * In addition pure synchronization control, Syncs - * may be useful in any context requiring before/after methods. - * For example, you can use an ObservableSync - * (perhaps as part of a LayeredSync) in order to obtain callbacks - * before and after each method invocation for a given class. - *

- - *

[ Introduction to this package. ] -**/ - - -public interface Sync { - - /** - * Wait (possibly forever) until successful passage. - * Fail only upon interuption. Interruptions always result in - * `clean' failures. On failure, you can be sure that it has not - * been acquired, and that no - * corresponding release should be performed. Conversely, - * a normal return guarantees that the acquire was successful. - **/ - - void acquire() throws InterruptedException; - - /** - * Wait at most msecs to pass; report whether passed. - *

- * The method has best-effort semantics: - * The msecs bound cannot - * be guaranteed to be a precise upper bound on wait time in Java. - * Implementations generally can only attempt to return as soon as possible - * after the specified bound. Also, timers in Java do not stop during garbage - * collection, so timeouts can occur just because a GC intervened. - * So, msecs arguments should be used in - * a coarse-grained manner. Further, - * implementations cannot always guarantee that this method - * will return at all without blocking indefinitely when used in - * unintended ways. For example, deadlocks may be encountered - * when called in an unintended context. - *

- * @param msecs the number of milleseconds to wait. - * An argument less than or equal to zero means not to wait at all. - * However, this may still require - * access to a synchronization lock, which can impose unbounded - * delay if there is a lot of contention among threads. - * @return true if acquired - **/ - - boolean attempt(long msecs) throws InterruptedException; - - /** - * Potentially enable others to pass. - *

- * Because release does not raise exceptions, - * it can be used in `finally' clauses without requiring extra - * embedded try/catch blocks. But keep in mind that - * as with any java method, implementations may - * still throw unchecked exceptions such as Error or NullPointerException - * when faced with uncontinuable errors. However, these should normally - * only be caught by higher-level error handlers. - **/ - - void release(); - - /** One second, in milliseconds; convenient as a time-out value **/ - long ONE_SECOND = 1000; - - /** One minute, in milliseconds; convenient as a time-out value **/ - long ONE_MINUTE = 60 * ONE_SECOND; - - /** One hour, in milliseconds; convenient as a time-out value **/ - long ONE_HOUR = 60 * ONE_MINUTE; - - /** One day, in milliseconds; convenient as a time-out value **/ - long ONE_DAY = 24 * ONE_HOUR; - - /** One week, in milliseconds; convenient as a time-out value **/ - long ONE_WEEK = 7 * ONE_DAY; - - /** One year in milliseconds; convenient as a time-out value **/ - // Not that it matters, but there is some variation across - // standard sources about value at msec precision. - // The value used is the same as in java.util.GregorianCalendar - long ONE_YEAR = (long)(365.2425 * ONE_DAY); - - /** One century in milliseconds; convenient as a time-out value **/ - long ONE_CENTURY = 100 * ONE_YEAR; -} - - diff --git a/platform/util/src/com/intellij/util/concurrency/SyncAdapterLock.java b/platform/util/src/com/intellij/util/concurrency/SyncAdapterLock.java deleted file mode 100644 index 66d4d9690257..000000000000 --- a/platform/util/src/com/intellij/util/concurrency/SyncAdapterLock.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @author max - */ -package com.intellij.util.concurrency; - -public class SyncAdapterLock implements JBLock { - private final Sync myAdaptee; - - public SyncAdapterLock(final Sync adaptee) { - myAdaptee = adaptee; - } - - public void lock() { - try { - myAdaptee.acquire(); - } - catch (InterruptedException e) { - throw new RuntimeException(e); - } - } - - public void unlock() { - myAdaptee.release(); - } -} \ No newline at end of file diff --git a/platform/util/src/com/intellij/util/concurrency/SynchronizedBasedReentrantReadWriteLock.java b/platform/util/src/com/intellij/util/concurrency/SynchronizedBasedReentrantReadWriteLock.java deleted file mode 100644 index 7b5d2ab30fd3..000000000000 --- a/platform/util/src/com/intellij/util/concurrency/SynchronizedBasedReentrantReadWriteLock.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @author max - */ -package com.intellij.util.concurrency; - -public class SynchronizedBasedReentrantReadWriteLock implements JBReentrantReadWriteLock { - private final SyncAdapterLock myReadLock; - private final SyncAdapterLock myWriteLock; - private final ReentrantWriterPreferenceReadWriteLock myAdaptee; - - public SynchronizedBasedReentrantReadWriteLock() { - myAdaptee = new ReentrantWriterPreferenceReadWriteLock(); - myReadLock = new SyncAdapterLock(myAdaptee.readLock()); - myWriteLock = new SyncAdapterLock(myAdaptee.writeLock()); - } - - public JBLock readLock() { - return myReadLock; - } - - public JBLock writeLock() { - return myWriteLock; - } - - public boolean isWriteLockedByCurrentThread() { - return myAdaptee.isWriteLockAcquired(Thread.currentThread()); - } -} \ No newline at end of file diff --git a/platform/util/src/com/intellij/util/concurrency/WriterPreferenceReadWriteLock.java b/platform/util/src/com/intellij/util/concurrency/WriterPreferenceReadWriteLock.java deleted file mode 100644 index 66cb459bc99f..000000000000 --- a/platform/util/src/com/intellij/util/concurrency/WriterPreferenceReadWriteLock.java +++ /dev/null @@ -1,315 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.intellij.util.concurrency; - -/** - * A ReadWriteLock that prefers waiting writers over - * waiting readers when there is contention. This class - * is adapted from the versions described in CPJ, improving - * on the ones there a bit by segregating reader and writer - * wait queues, which is typically more efficient. - *

- * The locks are NOT reentrant. In particular, - * even though it may appear to usually work OK, - * a thread holding a read lock should not attempt to - * re-acquire it. Doing so risks lockouts when there are - * also waiting writers. - *

[ Introduction to this package. ] - **/ - -public class WriterPreferenceReadWriteLock implements ReadWriteLock { - - protected long activeReaders_ = 0; - protected Thread activeWriter_ = null; - protected long waitingReaders_ = 0; - protected long waitingWriters_ = 0; - - - protected final ReaderLock readerLock_ = new ReaderLock(); - protected final WriterLock writerLock_ = new WriterLock(); - - public Sync writeLock() { return writerLock_; } - public Sync readLock() { return readerLock_; } - - /* - A bunch of small synchronized methods are needed - to allow communication from the Lock objects - back to this object, that serves as controller - */ - - - protected synchronized void cancelledWaitingReader() { --waitingReaders_; } - protected synchronized void cancelledWaitingWriter() { --waitingWriters_; } - - - /** Override this method to change to reader preference **/ - protected boolean allowReader() { - return activeWriter_ == null && waitingWriters_ == 0; - } - - - protected synchronized boolean startRead() { - boolean allowRead = allowReader(); - if (allowRead) ++activeReaders_; - return allowRead; - } - - protected synchronized boolean startWrite() { - - // The allowWrite expression cannot be modified without - // also changing startWrite, so is hard-wired - - boolean allowWrite = activeWriter_ == null && activeReaders_ == 0; - if (allowWrite) activeWriter_ = Thread.currentThread(); - return allowWrite; - } - - - /* - Each of these variants is needed to maintain atomicity - of wait counts during wait loops. They could be - made faster by manually inlining each other. We hope that - compilers do this for us though. - */ - - protected synchronized boolean startReadFromNewReader() { - boolean pass = startRead(); - if (!pass) ++waitingReaders_; - return pass; - } - - protected synchronized boolean startWriteFromNewWriter() { - boolean pass = startWrite(); - if (!pass) ++waitingWriters_; - return pass; - } - - protected synchronized boolean startReadFromWaitingReader() { - boolean pass = startRead(); - if (pass) --waitingReaders_; - return pass; - } - - protected synchronized boolean startWriteFromWaitingWriter() { - boolean pass = startWrite(); - if (pass) --waitingWriters_; - return pass; - } - - /** - * Called upon termination of a read. - * Returns the object to signal to wake up a waiter, or null if no such - **/ - protected synchronized Signaller endRead() { - if (--activeReaders_ == 0 && waitingWriters_ > 0) - return writerLock_; - else - return null; - } - - - /** - * Called upon termination of a write. - * Returns the object to signal to wake up a waiter, or null if no such - **/ - protected synchronized Signaller endWrite() { - activeWriter_ = null; - if (waitingReaders_ > 0 && allowReader()) - return readerLock_; - else if (waitingWriters_ > 0) - return writerLock_; - else - return null; - } - - - /** - * Reader and Writer requests are maintained in two different - * wait sets, by two different objects. These objects do not - * know whether the wait sets need notification since they - * don't know preference rules. So, each supports a - * method that can be selected by main controlling object - * to perform the notifications. This base class simplifies mechanics. - **/ - - protected abstract static class Signaller { // base for ReaderLock and WriterLock - abstract void signalWaiters(); - } - - protected class ReaderLock extends Signaller implements Sync { - - public void acquire() throws InterruptedException { - //TODO: [not sure why this is necessary but very inperformant] if (Thread.interrupted()) throw new InterruptedException(); - InterruptedException ie = null; - synchronized(this) { - if (!startReadFromNewReader()) { - for (;;) { - try { - wait(); - if (startReadFromWaitingReader()) - return; - } - catch(InterruptedException ex){ - cancelledWaitingReader(); - ie = ex; - break; - } - } - } - } - if (ie != null) { - // fall through outside synch on interrupt. - // This notification is not really needed here, - // but may be in plausible subclasses - writerLock_.signalWaiters(); - throw ie; - } - } - - - public void release() { - Signaller s = endRead(); - if (s != null) s.signalWaiters(); - } - - - synchronized void signalWaiters() { - notifyAll(); } - - public boolean attempt(long msecs) throws InterruptedException { - //TODO: [not sure why this is necessary but very inperformant] if (Thread.interrupted()) throw new InterruptedException(); - InterruptedException ie = null; - synchronized(this) { - if (msecs <= 0) - return startRead(); - else if (startReadFromNewReader()) - return true; - else { - long waitTime = msecs; - long start = System.currentTimeMillis(); - for (;;) { - try { - wait(waitTime); } - catch(InterruptedException ex){ - cancelledWaitingReader(); - ie = ex; - break; - } - if (startReadFromWaitingReader()) - return true; - else { - waitTime = msecs - (System.currentTimeMillis() - start); - if (waitTime <= 0) { - cancelledWaitingReader(); - break; - } - } - } - } - } - // safeguard on interrupt or timeout: - writerLock_.signalWaiters(); - if (ie != null) throw ie; - else return false; // timed out - } - - } - - protected class WriterLock extends Signaller implements Sync { - - public void acquire() throws InterruptedException { - if (Thread.interrupted()) throw new InterruptedException(); - InterruptedException ie = null; - synchronized(this) { - if (!startWriteFromNewWriter()) { - for (;;) { - try { - wait(); - if (startWriteFromWaitingWriter()) - return; - } - catch(InterruptedException ex){ - cancelledWaitingWriter(); - notify(); - ie = ex; - break; - } - } - } - } - if (ie != null) { - // Fall through outside synch on interrupt. - // On exception, we may need to signal readers. - // It is not worth checking here whether it is strictly necessary. - readerLock_.signalWaiters(); - throw ie; - } - } - - public void release(){ - Signaller s = endWrite(); - if (s != null) s.signalWaiters(); - } - - synchronized void signalWaiters() { - notify(); } - - public boolean attempt(long msecs) throws InterruptedException { - if (Thread.interrupted()) throw new InterruptedException(); - InterruptedException ie = null; - synchronized(this) { - if (msecs <= 0) - return startWrite(); - else if (startWriteFromNewWriter()) - return true; - else { - long waitTime = msecs; - long start = System.currentTimeMillis(); - for (;;) { - try { - wait(waitTime); } - catch(InterruptedException ex){ - cancelledWaitingWriter(); - notify(); - ie = ex; - break; - } - if (startWriteFromWaitingWriter()) - return true; - else { - waitTime = msecs - (System.currentTimeMillis() - start); - if (waitTime <= 0) { - cancelledWaitingWriter(); - notify(); - break; - } - } - } - } - } - - readerLock_.signalWaiters(); - if (ie != null) throw ie; - else return false; // timed out - } - - } - - - -} - diff --git a/platform/util/src/com/intellij/util/containers/LockPoolSynchronizedMap.java b/platform/util/src/com/intellij/util/containers/LockPoolSynchronizedMap.java index b00920a8dbfc..d8bc568e3cf4 100644 --- a/platform/util/src/com/intellij/util/containers/LockPoolSynchronizedMap.java +++ b/platform/util/src/com/intellij/util/containers/LockPoolSynchronizedMap.java @@ -20,21 +20,30 @@ package com.intellij.util.containers; import com.intellij.openapi.util.Comparing; -import com.intellij.util.concurrency.JBLock; -import com.intellij.util.concurrency.JBReentrantReadWriteLock; import gnu.trove.THashMap; +import org.jetbrains.annotations.NotNull; import java.util.Collection; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantReadWriteLock; public class LockPoolSynchronizedMap extends THashMap implements ConcurrentMap { - private final JBLock r; - private final JBLock w; + private final Lock r; + private final Lock w; + + private static final StripedLockHolder LOCKS = new StripedLockHolder(ReentrantReadWriteLock.class) { + @NotNull + @Override + protected ReentrantReadWriteLock create() { + return new ReentrantReadWriteLock(); + } + }; { - final JBReentrantReadWriteLock mutex = StripedJBReentrantReadWriteLocks.getInstance().allocateLock(); + final ReentrantReadWriteLock mutex = LOCKS.allocateLock(); r = mutex.readLock(); w = mutex.writeLock(); } @@ -49,6 +58,7 @@ public class LockPoolSynchronizedMap extends THashMap implements Con super(initialCapacity, loadFactor); } + @Override public int size() { r.lock(); try { @@ -59,6 +69,7 @@ public class LockPoolSynchronizedMap extends THashMap implements Con } } + @Override public boolean isEmpty() { r.lock(); try { @@ -69,6 +80,7 @@ public class LockPoolSynchronizedMap extends THashMap implements Con } } + @Override public boolean containsKey(Object key) { r.lock(); try { @@ -79,6 +91,7 @@ public class LockPoolSynchronizedMap extends THashMap implements Con } } + @Override public boolean containsValue(Object value) { r.lock(); try { @@ -89,6 +102,7 @@ public class LockPoolSynchronizedMap extends THashMap implements Con } } + @Override public V get(Object key) { r.lock(); try { @@ -99,6 +113,7 @@ public class LockPoolSynchronizedMap extends THashMap implements Con } } + @Override public V put(K key, V value) { w.lock(); try { @@ -109,6 +124,7 @@ public class LockPoolSynchronizedMap extends THashMap implements Con } } + @Override public V remove(Object key) { w.lock(); try { @@ -119,6 +135,7 @@ public class LockPoolSynchronizedMap extends THashMap implements Con } } + @Override public void putAll(Map map) { w.lock(); try { @@ -129,6 +146,7 @@ public class LockPoolSynchronizedMap extends THashMap implements Con } } + @Override public void clear() { w.lock(); try { @@ -139,6 +157,7 @@ public class LockPoolSynchronizedMap extends THashMap implements Con } } + @Override public LockPoolSynchronizedMap clone() { r.lock(); try { @@ -149,6 +168,7 @@ public class LockPoolSynchronizedMap extends THashMap implements Con } } + @Override public Set keySet() { r.lock(); try { @@ -159,6 +179,7 @@ public class LockPoolSynchronizedMap extends THashMap implements Con } } + @Override public Set> entrySet() { r.lock(); try { @@ -169,6 +190,7 @@ public class LockPoolSynchronizedMap extends THashMap implements Con } } + @Override public Collection values() { r.lock(); try { @@ -179,7 +201,8 @@ public class LockPoolSynchronizedMap extends THashMap implements Con } } - public boolean replace(K key, V oldValue, V newValue) { + @Override + public boolean replace(@NotNull K key, @NotNull V oldValue, @NotNull V newValue) { w.lock(); try { V prev = get(key); @@ -187,12 +210,7 @@ public class LockPoolSynchronizedMap extends THashMap implements Con return false; } - if (newValue == null) { - remove(key); - } - else { - put(key, newValue); - } + put(key, newValue); return true; } finally { @@ -200,17 +218,13 @@ public class LockPoolSynchronizedMap extends THashMap implements Con } } - public V replace(K key, V newValue) { + @Override + public V replace(@NotNull K key, @NotNull V newValue) { w.lock(); try { V prev = get(key); - if (newValue == null) { - remove(key); - } - else { - put(key, newValue); - } + put(key, newValue); return prev; } finally { @@ -218,7 +232,8 @@ public class LockPoolSynchronizedMap extends THashMap implements Con } } - public V putIfAbsent(K key, V value) { + @Override + public V putIfAbsent(@NotNull K key, V value) { w.lock(); try { V prev = get(key); @@ -235,7 +250,8 @@ public class LockPoolSynchronizedMap extends THashMap implements Con } } - public boolean remove(Object key, Object oldValue) { + @Override + public boolean remove(@NotNull Object key, Object oldValue) { w.lock(); try { V currentValue = get(key); diff --git a/platform/util/src/com/intellij/util/containers/StripedJBReentrantReadWriteLocks.java b/platform/util/src/com/intellij/util/containers/StripedJBReentrantReadWriteLocks.java deleted file mode 100644 index eb23e7a5bf20..000000000000 --- a/platform/util/src/com/intellij/util/containers/StripedJBReentrantReadWriteLocks.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2000-2010 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.util.containers; - -import com.intellij.util.concurrency.JBReentrantReadWriteLock; -import com.intellij.util.concurrency.LockFactory; -import org.jetbrains.annotations.NotNull; - -/** - * User: cdr - */ -public final class StripedJBReentrantReadWriteLocks extends StripedLockHolder { - private StripedJBReentrantReadWriteLocks() { - super(JBReentrantReadWriteLock.class); - } - - @NotNull - @Override - protected JBReentrantReadWriteLock create() { - return LockFactory.createReadWriteLock(); - } - - private static final StripedJBReentrantReadWriteLocks INSTANCE = new StripedJBReentrantReadWriteLocks(); - public static StripedJBReentrantReadWriteLocks getInstance() { - return INSTANCE; - } -}