java 7 nio_初试Java 7 NIO2:实现高性能的HTTP Server

package sun.nio.ch;

import java.io.IOException;

import java.lang.reflect.Field;

import java.nio.channels.AsynchronousCloseException;

import java.nio.channels.AsynchronousSocketChannel;

import java.nio.channels.ClosedChannelException;

import java.nio.channels.CompletionHandler;

import java.nio.channels.NotYetConnectedException;

import java.nio.channels.WritePendingException;

import java.util.concurrent.Future;

/**

* @author Yvon

*

*/

public class WindowsTransmitFileSupport {

//Sun's NIO2 channel  implementation class

private WindowsAsynchronousSocketChannelImpl channel;

//nio2 framework core data structure

PendingIoCache ioCache;

//some field retrieve from sun channel implementation class

private Object writeLock;

private Field writingF;

private Field writeShutdownF;

private Field writeKilledF; // f

WindowsTransmitFileSupport()

{

//dummy one for JNI code

}

/**

*

*/

public WindowsTransmitFileSupport(

AsynchronousSocketChannel

channel) {

this.channel = (WindowsAsynchronousSocketChannelImpl)channel;

try {

// Initialize the fields

Field f = WindowsAsynchronousSocketChannelImpl.class

.getDeclaredField("ioCache");

f.setAccessible(true);

ioCache = (PendingIoCache) f.get(channel);

f = AsynchronousSocketChannelImpl.class

.getDeclaredField("writeLock");

f.setAccessible(true);

writeLock = f.get(channel);

writingF = AsynchronousSocketChannelImpl.class

.getDeclaredField("writing");

writingF.setAccessible(true);

writeShutdownF = AsynchronousSocketChannelImpl.class

.getDeclaredField("writeShutdown");

writeShutdownF.setAccessible(true);

writeKilledF = AsynchronousSocketChannelImpl.class

.getDeclaredField("writeKilled");

writeKilledF.setAccessible(true);

} catch (NoSuchFieldException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (SecurityException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IllegalArgumentException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IllegalAccessException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

/**

* Implements the task to initiate a write and the handler to consume the

* result when the send file completes.

*/

private class SendFileTask implements Runnable, Iocp.ResultHandler {

private final PendingFuture result;

private final long file;//file is windows file HANDLE

SendFileTask(long file, PendingFuture result) {

this.result = result;

this.file = file;

}

@Override

// @SuppressWarnings("unchecked")

public void run() {

long overlapped = 0L;

boolean pending = false;

boolean shutdown = false;

try {

channel.begin();

// get an OVERLAPPED structure (from the cache or allocate)

overlapped = ioCache.add(result);

int n = transmitFile0(channel.handle, file, overlapped);

if (n == IOStatus.UNAVAILABLE) {

// I/O is pending

pending = true;

return;

}

if (n == IOStatus.EOF) {

// special case for shutdown output

shutdown = true;

throw new ClosedChannelException();

}

// write completed immediately

throw new InternalError("Write completed immediately");

} catch (Throwable x) {

// write failed. Enable writing before releasing waiters.

channel.enableWriting();

if (!shutdown && (x instanceof ClosedChannelException))

x = new AsynchronousCloseException();

if (!(x instanceof IOException))

x = new IOException(x);

result.setFailure(x);

} finally {

// release resources if I/O not pending

if (!pending) {

if (overlapped != 0L)

ioCache.remove(overlapped);

}

channel.end();

}

// invoke completion handler

Invoker.invoke(result);

}

/**

* Executed when the I/O has completed

*/

@Override

@SuppressWarnings("unchecked")

public void completed(int bytesTransferred, boolean canInvokeDirect) {

// release waiters if not already released by timeout

synchronized (result) {

if (result.isDone())

return;

channel.enableWriting();

result.setResult((V) Integer.valueOf(bytesTransferred));

}

if (canInvokeDirect) {

Invoker.invokeUnchecked(result);

} else {

Invoker.invoke(result);

}

}

@Override

public void failed(int error, IOException x) {

// return direct buffer to cache if substituted

// release waiters if not already released by timeout

if (!channel.isOpen())

x = new AsynchronousCloseException();

synchronized (result) {

if (result.isDone())

return;

channel.enableWriting();

result.setFailure(x);

}

Invoker.invoke(result);

}

}

public  Future sendFile(long file, A att,

CompletionHandler handler) {

boolean closed = false;

if (channel.isOpen()) {

if (channel.remoteAddress == null)

throw new NotYetConnectedException();

// check and update state

synchronized (writeLock) {

try{

if (writeKilledF.getBoolean(channel))

throw new IllegalStateException(

"Writing not allowed due to timeout or cancellation");

if (writingF.getBoolean(channel))

throw new WritePendingException();

if (writeShutdownF.getBoolean(channel)) {

closed = true;

} else {

writingF.setBoolean(channel, true);

}

}catch(Exception e)

{

IllegalStateException ise=new IllegalStateException(" catch exception when write");

ise.initCause(e);

throw ise;

}

}

} else {

closed = true;

}

// channel is closed or shutdown for write

if (closed) {

Throwable e = new ClosedChannelException();

if (handler == null)

return CompletedFuture.withFailure(e);

Invoker.invoke(channel, handler, att, null, e);

return null;

}

return implSendFile(file,att,handler);

}

 Future implSendFile(long file, A attachment,

CompletionHandler handler) {

// setup task

PendingFuture result = new PendingFuture(channel, handler,

attachment);

SendFileTask sendTask=new SendFileTask(file,result);

result.setContext(sendTask);

// initiate I/O (can only be done from thread in thread pool)

// initiate I/O

if (Iocp.supportsThreadAgnosticIo()) {

sendTask.run();

} else {

Invoker.invokeOnThreadInThreadPool(channel, sendTask);

}

return result;

}

private native int transmitFile0(long handle, long file,

long overlapped);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值