# This patch file was generated by NetBeans IDE
# This patch can be applied using context Tools: Apply Diff Patch action on respective folder.
# It uses platform neutral UTF-8 encoding.
# Above lines and this line are ignored by the patching process.
Index: openide/util/apichanges.xml
--- openide/util/apichanges.xml Base (1.27)
+++ openide/util/apichanges.xml Locally Modified (Based On 1.27)
@@ -49,6 +49,24 @@
Actions API
+
+
+ Mutex made pluggable
+
+
+
+
+
+
+ Added new constructor
+ Mutex(Priviledged, Executor)
+ that allows creators of the mutex to intercept and wrap posted actions
+ with custom code.
+
+
+
+
+ Obsolete method Utilities.isLargeFrameIcons deprecated.
Index: openide/util/src/org/openide/util/Mutex.java
--- openide/util/src/org/openide/util/Mutex.java Base (1.19)
+++ openide/util/src/org/openide/util/Mutex.java Locally Modified (Based On 1.19)
@@ -48,6 +48,7 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.Executor;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -176,6 +177,9 @@
/** protects internal data structures */
private /*final*/ Object LOCK;
+ /** wrapper, if any */
+ private final Executor wrapper;
+
/** threads that - owns or waits for this mutex */
private /*final*/ Map registeredThreads;
@@ -200,12 +204,14 @@
*/
public Mutex(Object lock) {
init(lock);
+ this.wrapper = null;
}
/** Default constructor.
*/
public Mutex() {
init(new InternalLock());
+ this.wrapper = null;
}
/** @param privileged can enter privileged states of this Mutex
@@ -218,8 +224,28 @@
init(new InternalLock());
privileged.setParent(this);
}
+ this.wrapper = null;
}
+ /** Constructor for those who wish to do some custom additional tasks
+ * whenever an action or runnable is executed in the {@link Mutex}. This
+ * may be useful for wrapping all the actions with custom {@link ThreadLocal}
+ * value, etc. Just implement the {@link Executor}'s execute(Runnable)
+ * method and do pre and post initialization tasks before running the runnable.
+ *
+ * The {@link Executor#execute} method shall return only when the passed in
+ * {@link Runnable} is finished, otherwise methods like {@link Mutex#readAccess(Action)} and co.
+ * might not return proper result.
+ *
+ * @param privileged can enter privileged states of this Mutex
+ * @param executor allows to wrap the work of the mutex with a custom code
+ * @since 7.12
+ */
+ public Mutex(Privileged privileged, Executor executor) {
+ LOCK = new Mutex(privileged);
+ this.wrapper = executor;
+ }
+
/** Initiates this Mutex */
private void init(Object lock) {
this.LOCK = lock;
@@ -236,7 +262,7 @@
* @param action the action to perform
* @return the object returned from {@link Mutex.Action#run}
*/
- public T readAccess(Action action) {
+ public T readAccess(final Action action) {
if (this == EVENT) {
try {
return doEventAccess(action);
@@ -244,6 +270,13 @@
throw (InternalError) new InternalError("Exception from non-Exception Action").initCause(e.getException()); // NOI18N
}
}
+ if (wrapper != null) {
+ try {
+ return doWrapperAccess(action, null, true);
+ } catch (MutexException e) {
+ throw (InternalError) new InternalError("Exception from non-Exception Action").initCause(e.getException()); // NOI18N
+ }
+ }
Thread t = Thread.currentThread();
readEnter(t);
@@ -279,10 +312,13 @@
* @exception RuntimeException if any runtime exception is thrown from the run method
* @see #readAccess(Mutex.Action)
*/
- public T readAccess(ExceptionAction action) throws MutexException {
+ public T readAccess(final ExceptionAction action) throws MutexException {
if (this == EVENT) {
return doEventAccess(action);
}
+ if (wrapper != null) {
+ return doWrapperAccess(action, null, true);
+ }
Thread t = Thread.currentThread();
readEnter(t);
@@ -310,6 +346,14 @@
return;
}
+ if (wrapper != null) {
+ try {
+ doWrapperAccess(null, action, true);
+ return;
+ } catch (MutexException ex) {
+ throw (IllegalStateException)new IllegalStateException().initCause(ex);
+ }
+ }
Thread t = Thread.currentThread();
readEnter(t);
@@ -335,6 +379,13 @@
throw (InternalError) new InternalError("Exception from non-Exception Action").initCause(e.getException()); // NOI18N
}
}
+ if (wrapper != null) {
+ try {
+ return doWrapperAccess(action, null, false);
+ } catch (MutexException e) {
+ throw (InternalError) new InternalError("Exception from non-Exception Action").initCause(e.getException()); // NOI18N
+ }
+ }
Thread t = Thread.currentThread();
writeEnter(t);
@@ -371,6 +422,9 @@
if (this == EVENT) {
return doEventAccess(action);
}
+ if (wrapper != null) {
+ return doWrapperAccess(action, null, false);
+ }
Thread t = Thread.currentThread();
writeEnter(t);
@@ -399,6 +453,14 @@
return;
}
+ if (wrapper != null) {
+ try {
+ doWrapperAccess(null, action, false);
+ } catch (MutexException ex) {
+ throw (IllegalStateException)new IllegalStateException().initCause(ex);
+ }
+ return;
+ }
Thread t = Thread.currentThread();
writeEnter(t);
@@ -431,6 +493,10 @@
if (this == EVENT) {
return javax.swing.SwingUtilities.isEventDispatchThread();
}
+ if (wrapper != null) {
+ Mutex m = (Mutex)LOCK;
+ return m.isReadAccess();
+ }
Thread t = Thread.currentThread();
ThreadInfo info;
@@ -460,6 +526,10 @@
if (this == EVENT) {
return javax.swing.SwingUtilities.isEventDispatchThread();
}
+ if (wrapper != null) {
+ Mutex m = (Mutex)LOCK;
+ return m.isWriteAccess();
+ }
Thread t = Thread.currentThread();
ThreadInfo info;
@@ -492,7 +562,7 @@
* @param run runnable to run
*/
public void postReadRequest(final Runnable run) {
- postRequest(S, run);
+ postRequest(S, run, null);
}
/** Posts a write request. This request runs immediately iff
@@ -509,7 +579,7 @@
* @param run runnable to run
*/
public void postWriteRequest(Runnable run) {
- postRequest(X, run);
+ postRequest(X, run, null);
}
/** toString */
@@ -1128,14 +1198,19 @@
* @param mutexMode mutex mode for which the action is rquested
* @param run the action
*/
- private void postRequest(int mutexMode, Runnable run) {
+ private void postRequest(final int mutexMode, final Runnable run, Executor exec) {
if (this == EVENT) {
doEventRequest(run);
return;
}
+ if (wrapper != null) {
+ Mutex m = (Mutex)LOCK;
+ m.postRequest(mutexMode, run, wrapper);
+ return;
+ }
- Thread t = Thread.currentThread();
+ final Thread t = Thread.currentThread();
ThreadInfo info;
synchronized (LOCK) {
@@ -1156,8 +1231,22 @@
// this mutex is not held
if (info == null) {
+ if (exec != null) {
+ class Exec implements Runnable {
+ public void run() {
enter(mutexMode, t, true);
+ try {
+ run.run();
+ } finally {
+ leave(t);
+ }
+ }
+ }
+ exec.execute(new Exec());
+ return;
+ }
+ enter(mutexMode, t, true);
try {
run.run();
} finally {
@@ -1193,6 +1282,49 @@
return (threadGranted == S) && (requested == X) && (readersNo == 1);
}
+ // -------------------------------- WRAPPERS --------------------------------
+
+ private T doWrapperAccess(
+ final ExceptionAction action, final Runnable runnable, final boolean readOnly
+ ) throws MutexException {
+ class R implements Runnable {
+ T ret;
+ MutexException e;
+
+ public void run() {
+ Mutex m = (Mutex)LOCK;
+ try {
+ if (readOnly) {
+ if (action != null) {
+ ret = m.readAccess(action);
+ } else {
+ m.readAccess(runnable);
+ }
+ } else {
+ if (action != null) {
+ ret = m.writeAccess(action);
+ } else {
+ m.writeAccess(runnable);
+ }
+ }
+ } catch (MutexException ex) {
+ this.e = ex;
+ }
+ }
+ }
+ R run = new R();
+ Mutex m = (Mutex)LOCK;
+ if (m.isWriteAccess() || m.isReadAccess()) {
+ run.run();
+ } else {
+ wrapper.execute(run);
+ }
+ if (run.e != null) {
+ throw run.e;
+ }
+ return run.ret;
+ }
+
// ------------------------------- EVENT METHODS ----------------------------
/** Runs the runnable in event queue, either immediatelly,
Index: openide/util/test/unit/src/org/openide/util/MutexWrapTest.java
--- openide/util/test/unit/src/org/openide/util/MutexWrapTest.java No Base Revision
+++ openide/util/test/unit/src/org/openide/util/MutexWrapTest.java Locally New
@@ -0,0 +1,225 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * The Original Software is NetBeans. The Initial Developer of the Original
+ * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
+ * Microsystems, Inc. All Rights Reserved.
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ */
+
+package org.openide.util;
+
+import java.util.concurrent.Executor;
+import junit.framework.Test;
+import org.netbeans.junit.NbTestCase;
+import org.netbeans.junit.NbTestSuite;
+import org.openide.util.Mutex.Action;
+import org.openide.util.Mutex.ExceptionAction;
+
+
+public class MutexWrapTest extends NbTestCase implements Executor {
+ Mutex.Privileged p;
+ Mutex m;
+ ThreadLocal