Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/windows/classes/sun/nio/ch/PendingIoCache.java
32288 views
1
/*
2
* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package sun.nio.ch;
27
28
import java.nio.channels.*;
29
import java.util.*;
30
import sun.misc.Unsafe;
31
32
/**
33
* Maintains a mapping of pending I/O requests (identified by the address of
34
* an OVERLAPPED structure) to Futures.
35
*/
36
37
class PendingIoCache {
38
private static final Unsafe unsafe = Unsafe.getUnsafe();
39
private static final int addressSize = unsafe.addressSize();
40
41
private static int dependsArch(int value32, int value64) {
42
return (addressSize == 4) ? value32 : value64;
43
}
44
45
/*
46
* typedef struct _OVERLAPPED {
47
* DWORD Internal;
48
* DWORD InternalHigh;
49
* DWORD Offset;
50
* DWORD OffsetHigh;
51
* HANDLE hEvent;
52
* } OVERLAPPED;
53
*/
54
private static final int SIZEOF_OVERLAPPED = dependsArch(20, 32);
55
56
// set to true when closed
57
private boolean closed;
58
59
// set to true when thread is waiting for all I/O operations to complete
60
private boolean closePending;
61
62
// maps OVERLAPPED to PendingFuture
63
@SuppressWarnings("rawtypes")
64
private final Map<Long,PendingFuture> pendingIoMap =
65
new HashMap<Long,PendingFuture>();
66
67
// per-channel cache of OVERLAPPED structures
68
private long[] overlappedCache = new long[4];
69
private int overlappedCacheCount = 0;
70
71
PendingIoCache() {
72
}
73
74
long add(PendingFuture<?,?> result) {
75
synchronized (this) {
76
if (closed)
77
throw new AssertionError("Should not get here");
78
long ov;
79
if (overlappedCacheCount > 0) {
80
ov = overlappedCache[--overlappedCacheCount];
81
} else {
82
ov = unsafe.allocateMemory(SIZEOF_OVERLAPPED);
83
}
84
pendingIoMap.put(ov, result);
85
return ov;
86
}
87
}
88
89
@SuppressWarnings("unchecked")
90
<V,A> PendingFuture<V,A> remove(long overlapped) {
91
synchronized (this) {
92
PendingFuture<V,A> res = pendingIoMap.remove(overlapped);
93
if (res != null) {
94
if (overlappedCacheCount < overlappedCache.length) {
95
overlappedCache[overlappedCacheCount++] = overlapped;
96
} else {
97
// cache full or channel closing
98
unsafe.freeMemory(overlapped);
99
}
100
// notify closing thread.
101
if (closePending) {
102
this.notifyAll();
103
}
104
}
105
return res;
106
}
107
}
108
109
void close() {
110
synchronized (this) {
111
if (closed)
112
return;
113
114
// handle case where I/O operations that have not completed.
115
if (!pendingIoMap.isEmpty())
116
clearPendingIoMap();
117
118
// release memory for any cached OVERLAPPED structures
119
while (overlappedCacheCount > 0) {
120
unsafe.freeMemory( overlappedCache[--overlappedCacheCount] );
121
}
122
123
// done
124
closed = true;
125
}
126
}
127
128
private void clearPendingIoMap() {
129
assert Thread.holdsLock(this);
130
131
// wait up to 50ms for the I/O operations to complete
132
closePending = true;
133
try {
134
this.wait(50);
135
} catch (InterruptedException x) {
136
Thread.currentThread().interrupt();
137
}
138
closePending = false;
139
if (pendingIoMap.isEmpty())
140
return;
141
142
// cause all pending I/O operations to fail
143
// simulate the failure of all pending I/O operations.
144
for (Long ov: pendingIoMap.keySet()) {
145
PendingFuture<?,?> result = pendingIoMap.get(ov);
146
assert !result.isDone();
147
148
// make I/O port aware of the stale OVERLAPPED structure
149
Iocp iocp = (Iocp)((Groupable)result.channel()).group();
150
iocp.makeStale(ov);
151
152
// execute a task that invokes the result handler's failed method
153
final Iocp.ResultHandler rh = (Iocp.ResultHandler)result.getContext();
154
Runnable task = new Runnable() {
155
public void run() {
156
rh.failed(-1, new AsynchronousCloseException());
157
}
158
};
159
iocp.executeOnPooledThread(task);
160
}
161
pendingIoMap.clear();
162
}
163
}
164
165