/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* Windows implementation of AsynchronousFileChannel using overlapped I/O.
*/
public class WindowsAsynchronousFileChannelImpl
extends AsynchronousFileChannelImpl
{
// error when EOF is detected asynchronously.
// Lazy initialization of default I/O completion port
private static class DefaultIocpHolder {
try {
} catch (IOException ioe) {
InternalError e = new InternalError();
throw e;
}
}
}
// The handle is extracted for use in native methods invoked from this class.
private final long handle;
// The key that identifies the channel's association with the I/O port
private final int completionKey;
// I/O completion port (group)
private final boolean isDefaultIocp;
// Caches OVERLAPPED structure for each outstanding I/O operation
boolean reading,
boolean writing,
boolean isDefaultIocp)
throws IOException
{
this.isDefaultIocp = isDefaultIocp;
this.ioCache = new PendingIoCache();
}
boolean reading,
boolean writing,
throws IOException
{
boolean isDefaultIocp;
isDefaultIocp = true;
} else {
isDefaultIocp = false;
}
try {
return new
} catch (IOException x) {
// error binding to port so need to close it (if created for this channel)
if (!isDefaultIocp)
throw x;
}
}
}
try {
if (closed)
return; // already closed
closed = true;
} finally {
}
// invalidate all locks held for this channel
// close the file
// waits until all I/O operations have completed
// disassociate from port
// for the non-default group close the port
if (!isDefaultIocp)
}
return iocp;
}
/**
* Translates Throwable to IOException
*/
if (x instanceof IOException) {
if (x instanceof ClosedChannelException)
x = new AsynchronousCloseException();
return (IOException)x;
}
return new IOException(x);
}
try {
begin();
} finally {
end();
}
}
if (size < 0)
throw new IllegalArgumentException("Negative size");
if (!writing)
throw new NonWritableChannelException();
try {
begin();
return this;
} finally {
end();
}
return this;
}
try {
begin();
} finally {
end();
}
}
// -- file locking --
/**
* Task that initiates locking operation and handles completion result.
*/
private final long position;
{
}
public void run() {
long overlapped = 0L;
try {
begin();
// allocate OVERLAPPED structure
// synchronize on result to avoid race with handler thread
// when lock is acquired immediately.
synchronized (result) {
if (n == IOStatus.UNAVAILABLE) {
// I/O is pending
return;
}
// acquired lock immediately
}
} catch (Throwable x) {
// lock failed or channel closed
if (overlapped != 0L)
} finally {
end();
}
// invoke completion handler
}
// release waiters and invoke completion handler
if (canInvokeDirect) {
} else {
}
}
// lock not acquired so remove from lock table
// release waiters
if (isOpen()) {
result.setFailure(x);
} else {
}
}
}
final long size,
final boolean shared,
A attachment,
{
throw new NonReadableChannelException();
throw new NonWritableChannelException();
// add to lock table
return null;
}
// create Future and task that will be invoked to acquire lock
// initiate I/O
if (Iocp.supportsThreadAgnosticIo()) {
} else {
boolean executed = false;
try {
executed = true;
} finally {
if (!executed) {
// rollback
}
}
}
return result;
}
throws IOException
{
throw new NonReadableChannelException();
throw new NonWritableChannelException();
// add to lock table
throw new ClosedChannelException();
boolean gotLock = false;
try {
begin();
// try to acquire the lock
return null;
gotLock = true;
return fli;
} finally {
if (!gotLock)
end();
}
}
}
/**
* Task that initiates read operation and handles completion result.
*/
// set to dst if direct; otherwise set to substituted direct buffer
int pos,
int rem,
long position,
{
}
void releaseBufferIfSubstituted() {
}
// if the I/O succeeded then adjust buffer position
if (bytesTransferred > 0) {
try {
} catch (IllegalArgumentException x) {
// someone has changed the position; ignore
}
} else {
// had to substitute direct buffer
try {
} catch (BufferOverflowException x) {
// someone has changed the position; ignore
}
}
}
}
public void run() {
int n = -1;
long overlapped = 0L;
long address;
// Substitute a native buffer if not direct
if (dst instanceof DirectBuffer) {
} else {
}
boolean pending = false;
try {
begin();
// allocate OVERLAPPED
// initiate read
if (n == IOStatus.UNAVAILABLE) {
// I/O is pending
pending = true;
return;
} else {
throw new InternalError("Unexpected result: " + n);
}
} catch (Throwable x) {
// failed to initiate read
} finally {
if (!pending) {
// release resources
if (overlapped != 0L)
}
end();
}
// invoke completion handler
}
/**
* Executed when the I/O has completed
*/
// return direct buffer to cache if substituted
// release waiters and invoke completion handler
if (canInvokeDirect) {
} else {
}
}
// if EOF detected asynchronously then it is reported as error
if (error == ERROR_HANDLE_EOF) {
completed(-1, false);
} else {
// return direct buffer to cache if substituted
// release waiters
if (isOpen()) {
result.setFailure(x);
} else {
}
}
}
}
long position,
A attachment,
{
if (!reading)
throw new NonReadableChannelException();
if (position < 0)
throw new IllegalArgumentException("Negative position");
if (dst.isReadOnly())
throw new IllegalArgumentException("Read-only buffer");
// check if channel is closed
if (!isOpen()) {
return null;
}
// no space remaining
if (rem == 0) {
return null;
}
// create Future and task that initiates read
// initiate I/O
if (Iocp.supportsThreadAgnosticIo()) {
} else {
}
return result;
}
/**
* Task that initiates write operation and handles completion result.
*/
// set to src if direct; otherwise set to substituted direct buffer
int pos,
int rem,
long position,
{
}
void releaseBufferIfSubstituted() {
}
// if the I/O succeeded then adjust buffer position
if (bytesTransferred > 0) {
try {
} catch (IllegalArgumentException x) {
// someone has changed the position
}
}
}
public void run() {
int n = -1;
long overlapped = 0L;
long address;
// Substitute a native buffer if not direct
if (src instanceof DirectBuffer) {
} else {
// temporarily restore position as we don't know how many bytes
// will be written
}
try {
begin();
// allocate an OVERLAPPED structure
// initiate the write
if (n == IOStatus.UNAVAILABLE) {
// I/O is pending
return;
} else {
throw new InternalError("Unexpected result: " + n);
}
} catch (Throwable x) {
// failed to initiate read:
// release resources
if (overlapped != 0L)
} finally {
end();
}
// invoke completion handler
}
/**
* Executed when the I/O has completed
*/
// return direct buffer to cache if substituted
// release waiters and invoke completion handler
if (canInvokeDirect) {
} else {
}
}
// return direct buffer to cache if substituted
// release waiters and invoker completion handler
if (isOpen()) {
result.setFailure(x);
} else {
}
}
}
long position,
A attachment,
{
if (!writing)
throw new NonWritableChannelException();
if (position < 0)
throw new IllegalArgumentException("Negative position");
// check if channel is closed
if (!isOpen()) {
return null;
}
// nothing to write
if (rem == 0) {
return null;
}
// create Future and task to initiate write
// initiate I/O
if (Iocp.supportsThreadAgnosticIo()) {
} else {
}
return result;
}
// -- Native methods --
static {
}
}