History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/nio/ch/SimpleAsynchronousFileChannelImpl.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/nio/ch/SimpleAsynchronousFileChannelImpl.java+397−0
@@ -0,0 +1,397 @@
1/*
2 * Copyright (c) 2008, 2009, 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
26package sun.nio.ch;
27
28import java.nio.channels.*;
29import java.util.concurrent.*;
30import java.nio.ByteBuffer;
31import java.security.AccessController;
32import java.security.PrivilegedAction;
33import java.io.FileDescriptor;
34import java.io.IOException;
35
36/**
37 * "Portable" implementation of AsynchronousFileChannel for use on operating
38 * systems that don't support asynchronous file I/O.
39 */
40
41public class SimpleAsynchronousFileChannelImpl
42 extends AsynchronousFileChannelImpl
43{
44 // lazy initialization of default thread pool for file I/O
45 private static class DefaultExecutorHolder {
46 static final ExecutorService defaultExecutor =
47 ThreadPool.createDefault().executor();
48 }
49
50 // Used to make native read and write calls
51 private static final FileDispatcher nd = new FileDispatcherImpl();
52
53 // Thread-safe set of IDs of native threads, for signalling
54 private final NativeThreadSet threads = new NativeThreadSet(2);
55
56
57 SimpleAsynchronousFileChannelImpl(FileDescriptor fdObj,
58 boolean reading,
59 boolean writing,
60 ExecutorService executor)
61 {
62 super(fdObj, reading, writing, executor);
63 }
64
65 public static AsynchronousFileChannel open(FileDescriptor fdo,
66 boolean reading,
67 boolean writing,
68 ThreadPool pool)
69 {
70 // Executor is either default or based on pool parameters
71 ExecutorService executor = (pool == null) ?
72 DefaultExecutorHolder.defaultExecutor : pool.executor();
73 return new SimpleAsynchronousFileChannelImpl(fdo, reading, writing, executor);
74 }
75
76 @Override
77 public void close() throws IOException {
78 // mark channel as closed
79 synchronized (fdObj) {
80 if (closed)
81 return; // already closed
82 closed = true;
83 // from this point on, if another thread invokes the begin() method
84 // then it will throw ClosedChannelException
85 }
86
87 // Invalidate and release any locks that we still hold
88 invalidateAllLocks();
89
90 // signal any threads blocked on this channel
91 nd.preClose(fdObj);
92 threads.signalAndWait();
93
94 // wait until all async I/O operations have completely gracefully
95 closeLock.writeLock().lock();
96 try {
97 // do nothing
98 } finally {
99 closeLock.writeLock().unlock();
100 }
101
102 // close file
103 nd.close(fdObj);
104 }
105
106 @Override
107 public long size() throws IOException {
108 int ti = threads.add();
109 try {
110 long n = 0L;
111 try {
112 begin();
113 do {
114 n = nd.size(fdObj);
115 } while ((n == IOStatus.INTERRUPTED) && isOpen());
116 return n;
117 } finally {
118 end(n >= 0L);
119 }
120 } finally {
121 threads.remove(ti);
122 }
123 }
124
125 @Override
126 public AsynchronousFileChannel truncate(long size) throws IOException {
127 if (size < 0L)
128 throw new IllegalArgumentException("Negative size");
129 if (!writing)
130 throw new NonWritableChannelException();
131 int ti = threads.add();
132 try {
133 long n = 0L;
134 try {
135 begin();
136 do {
137 n = nd.size(fdObj);
138 } while ((n == IOStatus.INTERRUPTED) && isOpen());
139
140 // truncate file if 'size' less than current size
141 if (size < n && isOpen()) {
142 do {
143 n = nd.truncate(fdObj, size);
144 } while ((n == IOStatus.INTERRUPTED) && isOpen());
145 }
146 return this;
147 } finally {
148 end(n > 0);
149 }
150 } finally {
151 threads.remove(ti);
152 }
153 }
154
155 @Override
156 public void force(boolean metaData) throws IOException {
157 int ti = threads.add();
158 try {
159 int n = 0;
160 try {
161 begin();
162 do {
163 n = nd.force(fdObj, metaData);
164 } while ((n == IOStatus.INTERRUPTED) && isOpen());
165 } finally {
166 end(n >= 0);
167 }
168 } finally {
169 threads.remove(ti);
170 }
171 }
172
173 @Override
174 <A> Future<FileLock> implLock(final long position,
175 final long size,
176 final boolean shared,
177 final A attachment,
178 final CompletionHandler<FileLock,? super A> handler)
179 {
180 if (shared && !reading)
181 throw new NonReadableChannelException();
182 if (!shared && !writing)
183 throw new NonWritableChannelException();
184
185 // add to lock table
186 final FileLockImpl fli = addToFileLockTable(position, size, shared);
187 if (fli == null) {
188 Throwable exc = new ClosedChannelException();
189 if (handler == null)
190 return CompletedFuture.withFailure(exc);
191 Invoker.invokeIndirectly(handler, attachment, null, exc, executor);
192 return null;
193 }
194
195 final PendingFuture<FileLock,A> result = (handler == null) ?
196 new PendingFuture<FileLock,A>(this) : null;
197 Runnable task = new Runnable() {
198 public void run() {
199 Throwable exc = null;
200
201 int ti = threads.add();
202 try {
203 int n;
204 try {
205 begin();
206 do {
207 n = nd.lock(fdObj, true, position, size, shared);
208 } while ((n == FileDispatcher.INTERRUPTED) && isOpen());
209 if (n != FileDispatcher.LOCKED || !isOpen()) {
210 throw new AsynchronousCloseException();
211 }
212 } catch (IOException x) {
213 removeFromFileLockTable(fli);
214 if (!isOpen())
215 x = new AsynchronousCloseException();
216 exc = x;
217 } finally {
218 end();
219 }
220 } finally {
221 threads.remove(ti);
222 }
223 if (handler == null) {
224 result.setResult(fli, exc);
225 } else {
226 Invoker.invokeUnchecked(handler, attachment, fli, exc);
227 }
228 }
229 };
230 boolean executed = false;
231 try {
232 executor.execute(task);
233 executed = true;
234 } finally {
235 if (!executed) {
236 // rollback
237 removeFromFileLockTable(fli);
238 }
239 }
240 return result;
241 }
242
243 @Override
244 public FileLock tryLock(long position, long size, boolean shared)
245 throws IOException
246 {
247 if (shared && !reading)
248 throw new NonReadableChannelException();
249 if (!shared && !writing)
250 throw new NonWritableChannelException();
251
252 // add to lock table
253 FileLockImpl fli = addToFileLockTable(position, size, shared);
254 if (fli == null)
255 throw new ClosedChannelException();
256
257 int ti = threads.add();
258 boolean gotLock = false;
259 try {
260 begin();
261 int n;
262 do {
263 n = nd.lock(fdObj, false, position, size, shared);
264 } while ((n == FileDispatcher.INTERRUPTED) && isOpen());
265 if (n == FileDispatcher.LOCKED && isOpen()) {
266 gotLock = true;
267 return fli; // lock acquired
268 }
269 if (n == FileDispatcher.NO_LOCK)
270 return null; // locked by someone else
271 if (n == FileDispatcher.INTERRUPTED)
272 throw new AsynchronousCloseException();
273 // should not get here
274 throw new AssertionError();
275 } finally {
276 if (!gotLock)
277 removeFromFileLockTable(fli);
278 end();
279 threads.remove(ti);
280 }
281 }
282
283 @Override
284 protected void implRelease(FileLockImpl fli) throws IOException {
285 nd.release(fdObj, fli.position(), fli.size());
286 }
287
288 @Override
289 <A> Future<Integer> implRead(final ByteBuffer dst,
290 final long position,
291 final A attachment,
292 final CompletionHandler<Integer,? super A> handler)
293 {
294 if (position < 0)
295 throw new IllegalArgumentException("Negative position");
296 if (!reading)
297 throw new NonReadableChannelException();
298 if (dst.isReadOnly())
299 throw new IllegalArgumentException("Read-only buffer");
300
301 // complete immediately if channel closed or no space remaining
302 if (!isOpen() || (dst.remaining() == 0)) {
303 Throwable exc = (isOpen()) ? null : new ClosedChannelException();
304 if (handler == null)
305 return CompletedFuture.withResult(0, exc);
306 Invoker.invokeIndirectly(handler, attachment, 0, exc, executor);
307 return null;
308 }
309
310 final PendingFuture<Integer,A> result = (handler == null) ?
311 new PendingFuture<Integer,A>(this) : null;
312 Runnable task = new Runnable() {
313 public void run() {
314 int n = 0;
315 Throwable exc = null;
316
317 int ti = threads.add();
318 try {
319 begin();
320 do {
321 n = IOUtil.read(fdObj, dst, position, nd, null);
322 } while ((n == IOStatus.INTERRUPTED) && isOpen());
323 if (n < 0 && !isOpen())
324 throw new AsynchronousCloseException();
325 } catch (IOException x) {
326 if (!isOpen())
327 x = new AsynchronousCloseException();
328 exc = x;
329 } finally {
330 end();
331 threads.remove(ti);
332 }
333 if (handler == null) {
334 result.setResult(n, exc);
335 } else {
336 Invoker.invokeUnchecked(handler, attachment, n, exc);
337 }
338 }
339 };
340 executor.execute(task);
341 return result;
342 }
343
344 @Override
345 <A> Future<Integer> implWrite(final ByteBuffer src,
346 final long position,
347 final A attachment,
348 final CompletionHandler<Integer,? super A> handler)
349 {
350 if (position < 0)
351 throw new IllegalArgumentException("Negative position");
352 if (!writing)
353 throw new NonWritableChannelException();
354
355 // complete immediately if channel is closed or no bytes remaining
356 if (!isOpen() || (src.remaining() == 0)) {
357 Throwable exc = (isOpen()) ? null : new ClosedChannelException();
358 if (handler == null)
359 return CompletedFuture.withResult(0, exc);
360 Invoker.invokeIndirectly(handler, attachment, 0, exc, executor);
361 return null;
362 }
363
364 final PendingFuture<Integer,A> result = (handler == null) ?
365 new PendingFuture<Integer,A>(this) : null;
366 Runnable task = new Runnable() {
367 public void run() {
368 int n = 0;
369 Throwable exc = null;
370
371 int ti = threads.add();
372 try {
373 begin();
374 do {
375 n = IOUtil.write(fdObj, src, position, nd, null);
376 } while ((n == IOStatus.INTERRUPTED) && isOpen());
377 if (n < 0 && !isOpen())
378 throw new AsynchronousCloseException();
379 } catch (IOException x) {
380 if (!isOpen())
381 x = new AsynchronousCloseException();
382 exc = x;
383 } finally {
384 end();
385 threads.remove(ti);
386 }
387 if (handler == null) {
388 result.setResult(n, exc);
389 } else {
390 Invoker.invokeUnchecked(handler, attachment, n, exc);
391 }
392 }
393 };
394 executor.execute(task);
395 return result;
396 }
397}