You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by mh...@apache.org on 2007/12/27 22:34:56 UTC
svn commit: r607125 - in /mina/trunk/core/src:
main/java/org/apache/mina/common/
main/java/org/apache/mina/transport/socket/nio/
test/java/org/apache/mina/transport/
test/java/org/apache/mina/transport/socket/nio/
Author: mheath
Date: Thu Dec 27 13:34:55 2007
New Revision: 607125
URL: http://svn.apache.org/viewvc?rev=607125&view=rev
Log:
Fixed DIRMINA-503.
Added tests for sending files with FileRegion.
Fixed FileRegion creation code in AbstractIoSession.
Added:
mina/trunk/core/src/test/java/org/apache/mina/transport/AbstractFileRegionTest.java (with props)
mina/trunk/core/src/test/java/org/apache/mina/transport/socket/nio/NioFileRegionTest.java (with props)
Modified:
mina/trunk/core/src/main/java/org/apache/mina/common/AbstractIoSession.java
mina/trunk/core/src/main/java/org/apache/mina/common/AbstractPollingIoProcessor.java
mina/trunk/core/src/main/java/org/apache/mina/transport/socket/nio/NioProcessor.java
Modified: mina/trunk/core/src/main/java/org/apache/mina/common/AbstractIoSession.java
URL: http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/common/AbstractIoSession.java?rev=607125&r1=607124&r2=607125&view=diff
==============================================================================
--- mina/trunk/core/src/main/java/org/apache/mina/common/AbstractIoSession.java (original)
+++ mina/trunk/core/src/main/java/org/apache/mina/common/AbstractIoSession.java Thu Dec 27 13:34:55 2007
@@ -281,35 +281,32 @@
return future;
}
- FileChannel channel = null;
- if (message instanceof IoBuffer
- && !((IoBuffer) message).hasRemaining()) {
- throw new IllegalArgumentException(
- "message is empty. Forgot to call flip()?");
- } else if (message instanceof FileChannel) {
- channel = (FileChannel) message;
- try {
- message = new DefaultFileRegion(channel, 0, channel.size());
- } catch (IOException e) {
- ExceptionMonitor.getInstance().exceptionCaught(e);
- return DefaultWriteFuture.newNotWrittenFuture(this, e);
- }
- } else if (message instanceof File) {
- File file = (File) message;
- try {
- channel = new FileInputStream(file).getChannel();
- } catch (IOException e) {
- ExceptionMonitor.getInstance().exceptionCaught(e);
- return DefaultWriteFuture.newNotWrittenFuture(this, e);
+ FileChannel openedFileChannel = null;
+ try {
+ if (message instanceof IoBuffer
+ && !((IoBuffer) message).hasRemaining()) {
+ throw new IllegalArgumentException(
+ "message is empty. Forgot to call flip()?");
+ } else if (message instanceof FileChannel) {
+ FileChannel fileChannel = (FileChannel) message;
+ message = new DefaultFileRegion(fileChannel, 0, fileChannel.size());
+ } else if (message instanceof File) {
+ File file = (File) message;
+ openedFileChannel = new FileInputStream(file).getChannel();
+ message = new DefaultFileRegion(openedFileChannel, 0, openedFileChannel.size());
}
+ } catch (IOException e) {
+ ExceptionMonitor.getInstance().exceptionCaught(e);
+ return DefaultWriteFuture.newNotWrittenFuture(this, e);
}
WriteFuture future = new DefaultWriteFuture(this);
getFilterChain().fireFilterWrite(
new DefaultWriteRequest(message, future, remoteAddress));
- if (message instanceof File) {
- final FileChannel finalChannel = channel;
+ if (openedFileChannel != null) {
+ // If we opened a FinalChannel, it needs to be closed when the write has completed
+ final FileChannel finalChannel = openedFileChannel;
future.addListener(new IoFutureListener<WriteFuture>() {
public void operationComplete(WriteFuture future) {
try {
Modified: mina/trunk/core/src/main/java/org/apache/mina/common/AbstractPollingIoProcessor.java
URL: http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/common/AbstractPollingIoProcessor.java?rev=607125&r1=607124&r2=607125&view=diff
==============================================================================
--- mina/trunk/core/src/main/java/org/apache/mina/common/AbstractPollingIoProcessor.java (original)
+++ mina/trunk/core/src/main/java/org/apache/mina/common/AbstractPollingIoProcessor.java Thu Dec 27 13:34:55 2007
@@ -591,6 +591,13 @@
}
localWrittenBytes = transferFile(session, region, length);
region.setPosition(region.getPosition() + localWrittenBytes);
+
+ // Fix for Java bug on Linux http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5103988
+ // If there's still data to be written in the FileRegion, return 0 indicating that we need
+ // to pause until writing may resume.
+ if (localWrittenBytes > 0 && region.getCount() > 0) {
+ return 0;
+ }
} else {
localWrittenBytes = 0;
}
Modified: mina/trunk/core/src/main/java/org/apache/mina/transport/socket/nio/NioProcessor.java
URL: http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/transport/socket/nio/NioProcessor.java?rev=607125&r1=607124&r2=607125&view=diff
==============================================================================
--- mina/trunk/core/src/main/java/org/apache/mina/transport/socket/nio/NioProcessor.java (original)
+++ mina/trunk/core/src/main/java/org/apache/mina/transport/socket/nio/NioProcessor.java Thu Dec 27 13:34:55 2007
@@ -173,7 +173,8 @@
@Override
protected int transferFile(NioSession session, FileRegion region, int length) throws Exception {
- return (int) region.getFileChannel().transferTo(region.getPosition(), region.getCount(), session.getChannel());
+ int writtenBytes = (int) region.getFileChannel().transferTo(region.getPosition(), length, session.getChannel());
+ return writtenBytes;
}
protected static class IoSessionIterator implements Iterator<NioSession> {
Added: mina/trunk/core/src/test/java/org/apache/mina/transport/AbstractFileRegionTest.java
URL: http://svn.apache.org/viewvc/mina/trunk/core/src/test/java/org/apache/mina/transport/AbstractFileRegionTest.java?rev=607125&view=auto
==============================================================================
--- mina/trunk/core/src/test/java/org/apache/mina/transport/AbstractFileRegionTest.java (added)
+++ mina/trunk/core/src/test/java/org/apache/mina/transport/AbstractFileRegionTest.java Thu Dec 27 13:34:55 2007
@@ -0,0 +1,113 @@
+package org.apache.mina.transport;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.util.concurrent.CountDownLatch;
+
+import junit.framework.TestCase;
+
+import org.apache.mina.common.ConnectFuture;
+import org.apache.mina.common.IoAcceptor;
+import org.apache.mina.common.IoBuffer;
+import org.apache.mina.common.IoConnector;
+import org.apache.mina.common.IoHandlerAdapter;
+import org.apache.mina.common.IoSession;
+import org.apache.mina.util.AvailablePortFinder;
+
+public abstract class AbstractFileRegionTest extends TestCase {
+
+ private static final int FILE_SIZE = 1 * 1024 * 1024; // 1MB file
+
+ protected abstract IoAcceptor createAcceptor();
+ protected abstract IoConnector createConnector();
+
+ public void testSendLargeFile() throws Throwable {
+ File file = createLargeFile();
+ assertEquals("Test file not as big as specified", FILE_SIZE, file.length());
+
+ final CountDownLatch latch = new CountDownLatch(1);
+ final boolean[] success = {false};
+ final Throwable[] exception = {null};
+
+ int port = AvailablePortFinder.getNextAvailable(1025);
+ IoAcceptor acceptor = createAcceptor();
+ acceptor.setHandler(new IoHandlerAdapter() {
+ private int index = 0;
+ @Override
+ public void exceptionCaught(IoSession session, Throwable cause)
+ throws Exception {
+ exception[0] = cause;
+ session.close();
+ }
+ @Override
+ public void sessionClosed(IoSession session) throws Exception {
+ latch.countDown();
+ }
+ @Override
+ public void messageReceived(IoSession session, Object message) throws Exception {
+ IoBuffer buffer = (IoBuffer) message;
+ while (buffer.hasRemaining()) {
+ int x = buffer.getInt();
+ if (x != index) {
+ throw new Exception(String.format("Integer at %d was %d but should have been %d", index, x, index));
+ }
+ index++;
+ }
+ if (index > FILE_SIZE / 4) {
+ throw new Exception("Read too much data");
+ }
+ if (index == FILE_SIZE / 4) {
+ success[0] = true;
+ session.close();
+ }
+ }
+ });
+ acceptor.bind(new InetSocketAddress(port));
+
+ IoConnector connector = createConnector();
+ connector.setHandler(new IoHandlerAdapter() {
+ @Override
+ public void exceptionCaught(IoSession session, Throwable cause)
+ throws Exception {
+ exception[0] = cause;
+ latch.countDown();
+ }
+ });
+ ConnectFuture future = connector.connect(new InetSocketAddress("localhost", port));
+ future.awaitUninterruptibly();
+
+ future.getSession().write(file);
+
+ latch.await();
+
+ if (exception[0] != null) {
+ throw exception[0];
+ }
+ assertTrue("Did not complete file transfer successfully", success[0]);
+
+ connector.dispose();
+ acceptor.dispose();
+ }
+
+ private File createLargeFile() throws IOException {
+ File largeFile = File.createTempFile("mina-test", "largefile");
+ FileChannel channel = new FileOutputStream(largeFile).getChannel();
+ ByteBuffer buffer = createBuffer();
+ channel.write(buffer);
+ channel.close();
+ return largeFile;
+ }
+ private ByteBuffer createBuffer() {
+ ByteBuffer buffer = ByteBuffer.allocate(FILE_SIZE);
+ for (int i = 0; i < FILE_SIZE / 4; i++) {
+ buffer.putInt(i);
+ }
+ buffer.flip();
+ return buffer;
+ }
+
+}
Propchange: mina/trunk/core/src/test/java/org/apache/mina/transport/AbstractFileRegionTest.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: mina/trunk/core/src/test/java/org/apache/mina/transport/socket/nio/NioFileRegionTest.java
URL: http://svn.apache.org/viewvc/mina/trunk/core/src/test/java/org/apache/mina/transport/socket/nio/NioFileRegionTest.java?rev=607125&view=auto
==============================================================================
--- mina/trunk/core/src/test/java/org/apache/mina/transport/socket/nio/NioFileRegionTest.java (added)
+++ mina/trunk/core/src/test/java/org/apache/mina/transport/socket/nio/NioFileRegionTest.java Thu Dec 27 13:34:55 2007
@@ -0,0 +1,19 @@
+package org.apache.mina.transport.socket.nio;
+
+import org.apache.mina.common.IoAcceptor;
+import org.apache.mina.common.IoConnector;
+import org.apache.mina.transport.AbstractFileRegionTest;
+
+public class NioFileRegionTest extends AbstractFileRegionTest{
+
+ @Override
+ protected IoAcceptor createAcceptor() {
+ return new NioSocketAcceptor();
+ }
+
+ @Override
+ protected IoConnector createConnector() {
+ return new NioSocketConnector();
+ }
+
+}
Propchange: mina/trunk/core/src/test/java/org/apache/mina/transport/socket/nio/NioFileRegionTest.java
------------------------------------------------------------------------------
svn:mime-type = text/plain