//========================================================================
// Parts Copyright 2006 Mort Bay Consulting Pty. Ltd.
//------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//========================================================================
package org.mortbay.jetty.grizzly;
import com.sun.grizzly.util.OutputWriter;
import com.sun.grizzly.util.SelectorFactory;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ByteChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
/**
*
* @author Jeanfrancois Arcand
*/
public class GrizzlySocketChannel implements ByteChannel
{
private SocketChannel socketChannel;
private SelectionKey key;
private long readTimeout=30*1000;
private long writeTimeout=30*1000;
public GrizzlySocketChannel()
{
}
public int read(ByteBuffer dst) throws IOException
{
//System.err.println("GrizzlySocketChannel.read");
if (key==null)
return -1;
int count=1;
int byteRead=0;
Selector readSelector=null;
SelectionKey tmpKey=null;
try
{
SocketChannel socketChannel=(SocketChannel)key.channel();
while (count>0)
{
count=socketChannel.read(dst);
if (count>0)
byteRead+=count;
}
if (byteRead==0)
{
readSelector=SelectorFactory.getSelector();
if (readSelector==null)
{
return 0;
}
count=1;
tmpKey=socketChannel.register(readSelector,SelectionKey.OP_READ);
tmpKey.interestOps(tmpKey.interestOps()|SelectionKey.OP_READ);
int code=readSelector.select(readTimeout);
tmpKey.interestOps(tmpKey.interestOps()&(~SelectionKey.OP_READ));
while (count>0)
{
count=socketChannel.read(dst);
if (count>0)
byteRead+=count;
}
}
}
finally
{
if (tmpKey!=null)
tmpKey.cancel();
if (readSelector!=null)
{
// Bug 6403933
try
{
readSelector.selectNow();
}
catch (IOException ex)
{
;
}
SelectorFactory.returnSelector(readSelector);
}
}
return byteRead;
}
public boolean isOpen()
{
return (socketChannel!=null?socketChannel.isOpen():false);
}
public void close() throws IOException
{
socketChannel.close();
}
public int write(ByteBuffer src) throws IOException
{
return (int)OutputWriter.flushChannel(socketChannel,src, writeTimeout);
}
public int write(ByteBuffer[] src) throws IOException
{
return (int)OutputWriter.flushChannel(socketChannel,src, writeTimeout);
}
public SocketChannel getSocketChannel()
{
return socketChannel;
}
public void setSocketChannel(SocketChannel socketChannel)
{
this.socketChannel=socketChannel;
}
public SelectionKey getSelectionKey()
{
return key;
}
public void setSelectionKey(SelectionKey key)
{
this.key=key;
}
public long getReadTimeout()
{
return readTimeout;
}
public void setReadTimeout(long readTimeout)
{
this.readTimeout=readTimeout;
}
public long getWriteTimeout()
{
return writeTimeout;
}
public void setWriteTimeout(long writeTimeout)
{
this.writeTimeout = writeTimeout;
}
}