Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/share/classes/java/nio/channels/spi/AbstractInterruptibleChannel.java
41161 views
1
/*
2
* Copyright (c) 2000, 2019, 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 java.nio.channels.spi;
27
28
import java.io.IOException;
29
import java.nio.channels.AsynchronousCloseException;
30
import java.nio.channels.Channel;
31
import java.nio.channels.ClosedByInterruptException;
32
import java.nio.channels.InterruptibleChannel;
33
34
import jdk.internal.access.SharedSecrets;
35
import sun.nio.ch.Interruptible;
36
37
38
/**
39
* Base implementation class for interruptible channels.
40
*
41
* <p> This class encapsulates the low-level machinery required to implement
42
* the asynchronous closing and interruption of channels. A concrete channel
43
* class must invoke the {@link #begin begin} and {@link #end end} methods
44
* before and after, respectively, invoking an I/O operation that might block
45
* indefinitely. In order to ensure that the {@link #end end} method is always
46
* invoked, these methods should be used within a
47
* {@code try}&nbsp;...&nbsp;{@code finally} block:
48
*
49
* <blockquote><pre id="be">
50
* boolean completed = false;
51
* try {
52
* begin();
53
* completed = ...; // Perform blocking I/O operation
54
* return ...; // Return result
55
* } finally {
56
* end(completed);
57
* }</pre></blockquote>
58
*
59
* <p> The {@code completed} argument to the {@link #end end} method tells
60
* whether or not the I/O operation actually completed, that is, whether it had
61
* any effect that would be visible to the invoker. In the case of an
62
* operation that reads bytes, for example, this argument should be
63
* {@code true} if, and only if, some bytes were actually transferred into the
64
* invoker's target buffer.
65
*
66
* <p> A concrete channel class must also implement the {@link
67
* #implCloseChannel implCloseChannel} method in such a way that if it is
68
* invoked while another thread is blocked in a native I/O operation upon the
69
* channel then that operation will immediately return, either by throwing an
70
* exception or by returning normally. If a thread is interrupted or the
71
* channel upon which it is blocked is asynchronously closed then the channel's
72
* {@link #end end} method will throw the appropriate exception.
73
*
74
* <p> This class performs the synchronization required to implement the {@link
75
* java.nio.channels.Channel} specification. Implementations of the {@link
76
* #implCloseChannel implCloseChannel} method need not synchronize against
77
* other threads that might be attempting to close the channel. </p>
78
*
79
*
80
* @author Mark Reinhold
81
* @author JSR-51 Expert Group
82
* @since 1.4
83
*/
84
85
public abstract class AbstractInterruptibleChannel
86
implements Channel, InterruptibleChannel
87
{
88
private final Object closeLock = new Object();
89
private volatile boolean closed;
90
91
/**
92
* Initializes a new instance of this class.
93
*/
94
protected AbstractInterruptibleChannel() { }
95
96
/**
97
* Closes this channel.
98
*
99
* <p> If the channel has already been closed then this method returns
100
* immediately. Otherwise it marks the channel as closed and then invokes
101
* the {@link #implCloseChannel implCloseChannel} method in order to
102
* complete the close operation. </p>
103
*
104
* @throws IOException
105
* If an I/O error occurs
106
*/
107
public final void close() throws IOException {
108
synchronized (closeLock) {
109
if (closed)
110
return;
111
closed = true;
112
implCloseChannel();
113
}
114
}
115
116
/**
117
* Closes this channel.
118
*
119
* <p> This method is invoked by the {@link #close close} method in order
120
* to perform the actual work of closing the channel. This method is only
121
* invoked if the channel has not yet been closed, and it is never invoked
122
* more than once.
123
*
124
* <p> An implementation of this method must arrange for any other thread
125
* that is blocked in an I/O operation upon this channel to return
126
* immediately, either by throwing an exception or by returning normally.
127
* </p>
128
*
129
* @throws IOException
130
* If an I/O error occurs while closing the channel
131
*/
132
protected abstract void implCloseChannel() throws IOException;
133
134
public final boolean isOpen() {
135
return !closed;
136
}
137
138
139
// -- Interruption machinery --
140
141
private Interruptible interruptor;
142
private volatile Thread interrupted;
143
144
/**
145
* Marks the beginning of an I/O operation that might block indefinitely.
146
*
147
* <p> This method should be invoked in tandem with the {@link #end end}
148
* method, using a {@code try}&nbsp;...&nbsp;{@code finally} block as
149
* shown <a href="#be">above</a>, in order to implement asynchronous
150
* closing and interruption for this channel. </p>
151
*/
152
protected final void begin() {
153
if (interruptor == null) {
154
interruptor = new Interruptible() {
155
public void interrupt(Thread target) {
156
synchronized (closeLock) {
157
if (closed)
158
return;
159
closed = true;
160
interrupted = target;
161
try {
162
AbstractInterruptibleChannel.this.implCloseChannel();
163
} catch (IOException x) { }
164
}
165
}};
166
}
167
blockedOn(interruptor);
168
Thread me = Thread.currentThread();
169
if (me.isInterrupted())
170
interruptor.interrupt(me);
171
}
172
173
/**
174
* Marks the end of an I/O operation that might block indefinitely.
175
*
176
* <p> This method should be invoked in tandem with the {@link #begin
177
* begin} method, using a {@code try}&nbsp;...&nbsp;{@code finally} block
178
* as shown <a href="#be">above</a>, in order to implement asynchronous
179
* closing and interruption for this channel. </p>
180
*
181
* @param completed
182
* {@code true} if, and only if, the I/O operation completed
183
* successfully, that is, had some effect that would be visible to
184
* the operation's invoker
185
*
186
* @throws AsynchronousCloseException
187
* If the channel was asynchronously closed
188
*
189
* @throws ClosedByInterruptException
190
* If the thread blocked in the I/O operation was interrupted
191
*/
192
protected final void end(boolean completed)
193
throws AsynchronousCloseException
194
{
195
blockedOn(null);
196
Thread interrupted = this.interrupted;
197
if (interrupted != null && interrupted == Thread.currentThread()) {
198
this.interrupted = null;
199
throw new ClosedByInterruptException();
200
}
201
if (!completed && closed)
202
throw new AsynchronousCloseException();
203
}
204
205
206
// -- jdk.internal.access.SharedSecrets --
207
static void blockedOn(Interruptible intr) { // package-private
208
SharedSecrets.getJavaLangAccess().blockedOn(intr);
209
}
210
}
211
212