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+
26+package sun.nio.ch;
27+
28+import java.nio.channels.*;
29+import java.util.concurrent.*;
30+import java.nio.ByteBuffer;
31+import java.security.AccessController;
32+import java.security.PrivilegedAction;
33+import java.io.FileDescriptor;
34+import 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+
41+public 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+}