< prev index next >

src/java.base/windows/classes/sun/nio/ch/PendingIoCache.java

Print this page

        

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.  Oracle designates this

@@ -62,10 +62,13 @@
     // maps OVERLAPPED to PendingFuture
     @SuppressWarnings("rawtypes")
     private final Map<Long,PendingFuture> pendingIoMap =
         new HashMap<Long,PendingFuture>();
 
+    // keys of former pendingIoMap entries which were invalidated
+    private final Set<Long> invalidOverlapped = new HashSet<Long>();
+
     // per-channel cache of OVERLAPPED structures
     private long[] overlappedCache = new long[4];
     private int overlappedCacheCount = 0;
 
     PendingIoCache() {

@@ -85,25 +88,34 @@
             return ov;
         }
     }
 
     @SuppressWarnings("unchecked")
+    void invalidate(long overlapped) {
+        synchronized (this) {
+            if (pendingIoMap.remove(overlapped) != null) {
+                invalidOverlapped.add(overlapped);
+            }
+        }
+    }
+
+    @SuppressWarnings("unchecked")
     <V,A> PendingFuture<V,A> remove(long overlapped) {
         synchronized (this) {
             PendingFuture<V,A> res = pendingIoMap.remove(overlapped);
-            if (res != null) {
+            if (res != null || invalidOverlapped.remove(overlapped)) {
                 if (overlappedCacheCount < overlappedCache.length) {
                     overlappedCache[overlappedCacheCount++] = overlapped;
                 } else {
                     // cache full or channel closing
                     unsafe.freeMemory(overlapped);
                 }
+            }
+            if (res != null && closePending) {
                 // notify closing thread.
-                if (closePending) {
                     this.notifyAll();
                 }
-            }
             return res;
         }
     }
 
     void close() {

@@ -118,10 +130,13 @@
             // release memory for any cached OVERLAPPED structures
             while (overlappedCacheCount > 0) {
                 unsafe.freeMemory( overlappedCache[--overlappedCacheCount] );
             }
 
+            // release memory for any invalidated OVERLAPPED structures
+            invalidOverlapped.stream().forEach(ov -> unsafe.freeMemory(ov));
+
             // done
             closed = true;
         }
     }
 
< prev index next >