Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/java/io/FileInputStream/UnreferencedFISClosesFd.java
41149 views
1
/*
2
* Copyright (c) 2007, 2018, 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.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*/
23
24
/**
25
*
26
* @test
27
* @modules java.base/java.io:open
28
* @library /test/lib
29
* @build jdk.test.lib.util.FileUtils UnreferencedFISClosesFd
30
* @bug 6524062
31
* @summary Test to ensure that FIS.finalize() invokes the close() method as per
32
* the specification.
33
* @run main/othervm UnreferencedFISClosesFd
34
*/
35
import java.io.File;
36
import java.io.FileDescriptor;
37
import java.io.FileInputStream;
38
import java.io.FileNotFoundException;
39
import java.io.IOException;
40
import java.lang.management.ManagementFactory;
41
import java.lang.management.OperatingSystemMXBean;
42
import java.lang.ref.Reference;
43
import java.lang.ref.ReferenceQueue;
44
import java.lang.ref.WeakReference;
45
import java.lang.reflect.Field;
46
import java.nio.file.Path;
47
import java.util.ArrayDeque;
48
import java.util.HashSet;
49
import java.util.concurrent.atomic.AtomicInteger;
50
51
import com.sun.management.UnixOperatingSystemMXBean;
52
53
import jdk.test.lib.util.FileUtils;
54
55
/**
56
* Tests for FIS unreferenced.
57
* - Not subclassed - cleaner cleanup
58
* - Subclassed no finalize or close - cleaner cleanup
59
* - Subclassed close overridden - AltFinalizer cleanup
60
* - Subclasses finalize overridden - cleaner cleanup
61
* - Subclasses finalize and close overridden - AltFinalizer cleanup
62
*/
63
public class UnreferencedFISClosesFd {
64
65
static final String FILE_NAME = "empty.txt";
66
67
/**
68
* Subclass w/ no overrides; not finalize or close.
69
* Cleanup should be via the Cleaner.
70
*/
71
public static class StreamOverrides extends FileInputStream {
72
73
protected final AtomicInteger closeCounter;
74
75
public StreamOverrides(String name) throws FileNotFoundException {
76
super(name);
77
closeCounter = new AtomicInteger(0);
78
}
79
80
final AtomicInteger closeCounter() {
81
return closeCounter;
82
}
83
}
84
85
/**
86
* Subclass overrides close.
87
* Cleanup should be via the Cleaner.
88
*/
89
public static class StreamOverridesClose extends StreamOverrides {
90
91
public StreamOverridesClose(String name) throws FileNotFoundException {
92
super(name);
93
}
94
95
public void close() throws IOException {
96
closeCounter.incrementAndGet();
97
super.close();
98
}
99
}
100
101
/**
102
* Subclass overrides finalize.
103
* Cleanup should be via the Cleaner.
104
*/
105
public static class StreamOverridesFinalize extends StreamOverrides {
106
107
public StreamOverridesFinalize(String name) throws FileNotFoundException {
108
super(name);
109
}
110
111
@SuppressWarnings({"deprecation","removal"})
112
protected void finalize() throws IOException, Throwable {
113
super.finalize();
114
}
115
}
116
117
/**
118
* Subclass overrides finalize and close.
119
* Cleanup should be via AltFinalizer calling close().
120
*/
121
public static class StreamOverridesFinalizeClose extends StreamOverridesClose {
122
123
public StreamOverridesFinalizeClose(String name) throws FileNotFoundException {
124
super(name);
125
}
126
127
@SuppressWarnings({"deprecation","removal"})
128
protected void finalize() throws IOException, Throwable {
129
super.finalize();
130
}
131
}
132
133
/**
134
* Main runs each test case and reports number of failures.
135
*/
136
public static void main(String argv[]) throws Exception {
137
138
File inFile = new File(System.getProperty("test.dir", "."), FILE_NAME);
139
inFile.createNewFile();
140
inFile.deleteOnExit();
141
142
String name = inFile.getPath();
143
144
FileUtils.listFileDescriptors(System.out);
145
long fdCount0 = getFdCount();
146
147
int failCount = 0;
148
failCount += test(new FileInputStream(name));
149
150
failCount += test(new StreamOverrides(name));
151
152
failCount += test(new StreamOverridesClose(name));
153
154
failCount += test(new StreamOverridesFinalize(name));
155
156
failCount += test(new StreamOverridesFinalizeClose(name));
157
158
if (failCount > 0) {
159
throw new AssertionError("Failed test count: " + failCount);
160
}
161
162
// Check the final count of open file descriptors
163
long fdCount = getFdCount();
164
if (fdCount != fdCount0) {
165
System.out.printf("initial count of open file descriptors: %d%n", fdCount0);
166
System.out.printf("final count of open file descriptors: %d%n", fdCount);
167
FileUtils.listFileDescriptors(System.out);
168
}
169
}
170
171
// Get the count of open file descriptors, or -1 if not available
172
private static long getFdCount() {
173
OperatingSystemMXBean mxBean = ManagementFactory.getOperatingSystemMXBean();
174
return (mxBean instanceof UnixOperatingSystemMXBean)
175
? ((UnixOperatingSystemMXBean) mxBean).getOpenFileDescriptorCount()
176
: -1L;
177
}
178
179
private static int test(FileInputStream fis) throws Exception {
180
181
try {
182
System.out.printf("%nTesting %s%n", fis.getClass().getName());
183
184
// Prepare to wait for FIS to be reclaimed
185
ReferenceQueue<Object> queue = new ReferenceQueue<>();
186
HashSet<Reference<?>> pending = new HashSet<>();
187
WeakReference<FileInputStream> msWeak = new WeakReference<>(fis, queue);
188
pending.add(msWeak);
189
190
FileDescriptor fd = fis.getFD();
191
WeakReference<FileDescriptor> fdWeak = new WeakReference<>(fd, queue);
192
pending.add(fdWeak);
193
194
Field fdField = FileDescriptor.class.getDeclaredField("fd");
195
fdField.setAccessible(true);
196
int ffd = fdField.getInt(fd);
197
198
Field cleanupField = FileDescriptor.class.getDeclaredField("cleanup");
199
cleanupField.setAccessible(true);
200
Object cleanup = cleanupField.get(fd);
201
System.out.printf(" cleanup: %s, ffd: %d, cf: %s%n", cleanup, ffd, cleanupField);
202
if (cleanup == null) {
203
throw new RuntimeException("cleanup should not be null");
204
}
205
206
WeakReference<Object> cleanupWeak = new WeakReference<>(cleanup, queue);
207
pending.add(cleanupWeak);
208
System.out.printf(" fdWeak: %s%n msWeak: %s%n cleanupWeak: %s%n",
209
fdWeak, msWeak, cleanupWeak);
210
211
AtomicInteger closeCounter = fis instanceof StreamOverrides
212
? ((StreamOverrides)fis).closeCounter() : null;
213
214
Reference<?> r;
215
while (((r = queue.remove(1000L)) != null)
216
|| !pending.isEmpty()) {
217
System.out.printf(" r: %s, pending: %d%n",
218
r, pending.size());
219
if (r != null) {
220
pending.remove(r);
221
} else {
222
fis = null;
223
fd = null;
224
cleanup = null;
225
System.gc(); // attempt to reclaim them
226
}
227
}
228
Reference.reachabilityFence(fd);
229
Reference.reachabilityFence(fis);
230
Reference.reachabilityFence(cleanup);
231
232
// Confirm the correct number of calls to close depending on the cleanup type
233
if (closeCounter != null && closeCounter.get() > 0) {
234
throw new RuntimeException("Close should not have been called: count: " + closeCounter);
235
}
236
} catch (Exception ex) {
237
ex.printStackTrace(System.out);
238
return 1;
239
}
240
return 0;
241
}
242
}
243
244