sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1520259 - in /sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis: internal/jdk8/Function.java internal/jdk8/Supplier.java util/collection/Cache.java
Date Thu, 05 Sep 2013 09:18:14 GMT
Author: desruisseaux
Date: Thu Sep  5 09:18:13 2013
New Revision: 1520259

URL: http://svn.apache.org/r1520259
Log:
Fixed a ClassCastException in Cache.get/put/remove(K).

Added:
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/Supplier.java
  (with props)
Modified:
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/Function.java
    sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/collection/Cache.java

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/Function.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/Function.java?rev=1520259&r1=1520258&r2=1520259&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/Function.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/Function.java
[UTF-8] Thu Sep  5 09:18:13 2013
@@ -18,7 +18,7 @@ package org.apache.sis.internal.jdk8;
 
 
 /**
- * Placeholder for the {@link ava.util.function.Function} interface.
+ * Placeholder for the {@link java.util.function.Function} interface.
  *
  * @param <T> The type of parameters (source type).
  * @param <R> The type of return values (target type).

Added: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/Supplier.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/Supplier.java?rev=1520259&view=auto
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/Supplier.java
(added)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/Supplier.java
[UTF-8] Thu Sep  5 09:18:13 2013
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.sis.internal.jdk8;
+
+
+/**
+ * Placeholder for the {@link java.util.function.Supplier} interface.
+ *
+ * @param <T> The type of results.
+ */
+public interface Supplier<T> {
+    /**
+     * Gets a result.
+     *
+     * @return A result.
+     */
+    T get();
+}

Propchange: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/Supplier.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/Supplier.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/collection/Cache.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/collection/Cache.java?rev=1520259&r1=1520258&r2=1520259&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/collection/Cache.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/collection/Cache.java
[UTF-8] Thu Sep  5 09:18:13 2013
@@ -37,6 +37,9 @@ import org.apache.sis.internal.system.Re
 
 import static org.apache.sis.internal.system.DelayedExecutor.executeDaemonTask;
 
+// Related to JDK8
+import org.apache.sis.internal.jdk8.Supplier;
+
 
 /**
  * A concurrent cache mechanism. This implementation is thread-safe and supports concurrency.
@@ -133,7 +136,7 @@ import static org.apache.sis.internal.sy
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3 (derived from geotk-3.00)
- * @version 0.3
+ * @version 0.4
  * @module
  */
 @ThreadSafe
@@ -141,7 +144,7 @@ public class Cache<K,V> extends Abstract
     /**
      * The map that contains the cached values. If a value is under the process of being
      * calculated, then the value will be a temporary instance of {@link Handler}. The
-     * value may also be weak of soft {@link Reference} objects.
+     * value may also be weak or soft {@link Reference} objects.
      */
     private final ConcurrentMap<K,Object> map;
 
@@ -275,22 +278,11 @@ public class Cache<K,V> extends Abstract
             return ((Reference<V>) value).get();
         }
         if (value instanceof Handler<?>) {
-            final Handler<V> handler = (Handler<V>) value;
-            final ReentrantLock lock = (ReentrantLock) value;
+            return ((Supplier<V>) value).get();
             /*
              * A ClassCastException on the above line would be a bug in this class.
-             * See the comment in Cache.lock(K) method for more explanations.  The
-             * remainder of this block is an adaptation of Cache.Work.get().
+             * See the comment in Cache.lock(K) method for more explanations.
              */
-            if (lock.isHeldByCurrentThread()) {
-                return null;
-            }
-            lock.lock();
-            try {
-                return handler.peek();
-            } finally {
-                lock.unlock();
-            }
         }
         return (V) value;
     }
@@ -444,6 +436,7 @@ public class Cache<K,V> extends Abstract
      */
     public Handler<V> lock(final K key) {
         final Work handler = new Work(key);
+        boolean unlock = true;
         handler.lock.lock();
         Object value;
         try {
@@ -457,15 +450,15 @@ public class Cache<K,V> extends Abstract
                     /*
                      * We succeed in adding the handler in the map (we know that because
all our
                      * map.put(...) or map.replace(...) operations are guaranteed to put
non-null
-                     * values). We are done. But before to leave, lock again for canceling
the
-                     * effect of unlock in the finally clause (we want the lock to still
active).
+                     * values). We are done. But before to leave, declare that we do not
want to
+                     * unlock in the finally clause (we want the lock to still active).
                      */
-                    handler.lock.lock();
+                    unlock = false;
                     return handler;
                 }
                 /*
-                 * If the value is a valid reference (strong, soft or weak), stop the loop
and
-                 * release the lock. We will process that value after the finally block.
+                 * If the value is a strong reference or other handler, stop the loop and
release the lock.
+                 * We will process that value after the finally block.
                  */
                 if (!(value instanceof Reference<?>)) {
                     break;
@@ -493,13 +486,15 @@ public class Cache<K,V> extends Abstract
                  * handler.
                  */
                 if (map.replace(key, ref, handler)) {
-                    handler.lock.lock();
+                    unlock = false;
                     return handler;
                 }
                 // The map content changed. Try again.
             } while (true);
         } finally {
-            handler.lock.unlock();
+            if (unlock) {
+                handler.lock.unlock();
+            }
         }
         /*
          * From this point, we abandon our handler.
@@ -638,7 +633,7 @@ public class Cache<K,V> extends Abstract
      * A handler implementation used for telling to other threads that the current thread
is
      * computing a value.
      */
-    final class Work extends DelayedRunnable.Immediate implements Handler<V> {
+    final class Work extends DelayedRunnable.Immediate implements Handler<V>, Supplier<V>
{
         /**
          * The synchronization lock.
          */
@@ -667,9 +662,10 @@ public class Cache<K,V> extends Abstract
          * Waits for the completion of the value computation and returns this result. This
          * method should be invoked only from an other thread than the one doing the calculation.
          */
-        final V get() {
+        @Override
+        public V get() {
             if (lock.isHeldByCurrentThread()) {
-                throw new IllegalStateException();
+                return null;
             }
             final V v;
             lock.lock();
@@ -734,12 +730,12 @@ public class Cache<K,V> extends Abstract
              * Do nothing (except checking for programming error), since we don't hold any
lock.
              *
              * {@note An alternative would have been to store the result in the map anyway.
-             *        But doing so is unsafe because we have no lock; we have no guarantee
and
+             *        But doing so is unsafe because we have no lock; we have no guarantee
that
              *        nothing has happened in an other thread between peek and putAndUnlock.}
              */
             @Override
             public void putAndUnlock(final V result) throws IllegalStateException {
-                if (result != get() && !isKeyCollisionAllowed()) {
+                if (result != null && !isKeyCollisionAllowed() && result
!= get()) {
                     throw new IllegalStateException(Errors.format(Errors.Keys.KeyCollision_1,
key));
                 }
             }



Mime
View raw message