Skip to content

Commit

Permalink
Make NativeSelectableChannel an interface and reparent NativeSocketCh…
Browse files Browse the repository at this point in the history
…annel and NativeDeviceChannel
  • Loading branch information
vp-of-awesome committed Jan 31, 2009
1 parent 5213fb6 commit e2bebc3
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 107 deletions.
19 changes: 5 additions & 14 deletions src/enxio/nio/channels/NativeDeviceChannel.java
@@ -1,7 +1,3 @@
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package enxio.nio.channels;

Expand All @@ -12,25 +8,20 @@
import java.nio.channels.spi.AbstractSelectableChannel;
import java.nio.channels.spi.SelectorProvider;

/**
*
* @author wayne
*/
public class NativeDeviceChannel extends AbstractSelectableChannel implements ByteChannel {
public class NativeDeviceChannel extends AbstractSelectableChannel implements ByteChannel, NativeSelectableChannel {

private final int fd;
private final int validOps;

public NativeDeviceChannel(int fd) {
this(NativeSelectorProvider.getInstance(), fd, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
}
public NativeDeviceChannel(SelectorProvider provider, int fd, int ops) {
super(provider);
this.fd = fd;
this.validOps = ops;
}
public static NativeSelectableChannel forDevice(int fd) {
return new NativeSelectableChannel(NativeSelectorProvider.getInstance(), fd,
SelectionKey.OP_READ | SelectionKey.OP_WRITE);
}


@Override
protected void implCloseSelectableChannel() throws IOException {
Native.close(fd);
Expand Down
55 changes: 3 additions & 52 deletions src/enxio/nio/channels/NativeSelectableChannel.java
@@ -1,57 +1,8 @@
package enxio.nio.channels;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ByteChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.spi.AbstractSelectableChannel;
import java.nio.channels.spi.SelectorProvider;
import java.nio.channels.Channel;

public class NativeSelectableChannel extends AbstractSelectableChannel
implements ByteChannel {
public interface NativeSelectableChannel extends Channel {

private final int fd;
private final int validOps;

public NativeSelectableChannel(SelectorProvider provider, int fd, int ops) {
super(provider);
this.fd = fd;
this.validOps = ops;
}
public static NativeSelectableChannel forSocket(int fd) {
return new NativeSelectableChannel(NativeSelectorProvider.getInstance(), fd,
SelectionKey.OP_READ | SelectionKey.OP_WRITE | SelectionKey.OP_CONNECT | SelectionKey.OP_ACCEPT);
}
public static NativeSelectableChannel forServerSocket(int fd) {
return forSocket(fd);
}
public static NativeSelectableChannel forDevice(int fd) {
return new NativeSelectableChannel(NativeSelectorProvider.getInstance(), fd,
SelectionKey.OP_READ | SelectionKey.OP_WRITE);
}

@Override
protected void implCloseSelectableChannel() throws IOException {
Native.close(fd);
}

@Override
protected void implConfigureBlocking(boolean block) throws IOException {
Native.setBlocking(fd, block);
}

@Override
public final int validOps() {
return validOps;
}
public final int getFD() {
return fd;
}
public int read(ByteBuffer dst) throws IOException {
return Native.read(fd, dst);
}

public int write(ByteBuffer src) throws IOException {
return Native.write(fd, src);
}
public int getFD();
}
40 changes: 40 additions & 0 deletions src/enxio/nio/channels/NativeServerSocketChannel.java
@@ -0,0 +1,40 @@

package enxio.nio.channels;

import java.io.IOException;
import java.nio.channels.SelectionKey;
import java.nio.channels.spi.AbstractSelectableChannel;
import java.nio.channels.spi.SelectorProvider;

public class NativeServerSocketChannel extends AbstractSelectableChannel implements NativeSelectableChannel {

private final int fd;
private final int validOps;

public NativeServerSocketChannel(int fd) {
this(NativeSelectorProvider.getInstance(), fd, SelectionKey.OP_ACCEPT);
}
public NativeServerSocketChannel(SelectorProvider provider, int fd, int ops) {
super(provider);
this.fd = fd;
this.validOps = ops;
}

@Override
protected void implCloseSelectableChannel() throws IOException {
Native.close(fd);
}

@Override
protected void implConfigureBlocking(boolean block) throws IOException {
Native.setBlocking(fd, block);
}

@Override
public final int validOps() {
return validOps;
}
public final int getFD() {
return fd;
}
}
39 changes: 33 additions & 6 deletions src/enxio/nio/channels/NativeSocketChannel.java
Expand Up @@ -3,20 +3,48 @@

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ByteChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.spi.AbstractSelectableChannel;
import java.nio.channels.spi.SelectorProvider;

public class NativeSocketChannel extends NativeSelectableChannel {
public class NativeSocketChannel extends AbstractSelectableChannel
implements ByteChannel, NativeSelectableChannel {

private final int fd;
private final int validOps;

public NativeSocketChannel(int fd) {
this(fd, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
this(NativeSelectorProvider.getInstance(), fd, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
}
public NativeSocketChannel(int fd, int ops) {
super(NativeSelectorProvider.getInstance(), fd, ops);
this(NativeSelectorProvider.getInstance(), fd, ops);
}
NativeSocketChannel(SelectorProvider provider, int fd, int ops) {
super(provider);
this.fd = fd;
this.validOps = ops;
}

@Override
protected void implCloseSelectableChannel() throws IOException {
Native.close(fd);
}

@Override
protected void implConfigureBlocking(boolean block) throws IOException {
Native.setBlocking(fd, block);
}

@Override
public final int validOps() {
return validOps;
}
public final int getFD() {
return fd;
}
public int read(ByteBuffer dst) throws IOException {
int n = super.read(dst);
int n = Native.read(fd, dst);
switch (n) {
case 0:
return -1;
Expand All @@ -27,8 +55,7 @@ public int read(ByteBuffer dst) throws IOException {
}
}

@Override
public int write(ByteBuffer src) throws IOException {
return super.write(src);
return Native.write(fd, src);
}
}
10 changes: 1 addition & 9 deletions src/enxio/nio/channels/kqueue/KQSelectionKey.java
@@ -1,7 +1,3 @@
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package enxio.nio.channels.kqueue;

Expand All @@ -12,10 +8,6 @@
import java.nio.channels.spi.AbstractSelectionKey;
import enxio.nio.channels.NativeSelectableChannel;

/**
*
* @author wayne
*/
class KQSelectionKey extends AbstractSelectionKey {
private final KQSelector selector;
private final NativeSelectableChannel channel;
Expand All @@ -33,7 +25,7 @@ int getFD() {

@Override
public SelectableChannel channel() {
return channel;
return (SelectableChannel) channel;
}

@Override
Expand Down
10 changes: 1 addition & 9 deletions src/enxio/nio/channels/poll/PollSelectionKey.java
@@ -1,7 +1,3 @@
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package enxio.nio.channels.poll;

Expand All @@ -11,10 +7,6 @@
import java.nio.channels.spi.AbstractSelectionKey;
import enxio.nio.channels.NativeSelectableChannel;

/**
*
* @author wayne
*/
class PollSelectionKey extends AbstractSelectionKey {
private final PollSelector selector;
private final NativeSelectableChannel channel;
Expand All @@ -39,7 +31,7 @@ int getFD() {

@Override
public SelectableChannel channel() {
return channel;
return (SelectableChannel) channel;
}

@Override
Expand Down
33 changes: 16 additions & 17 deletions src/example/TCPServer.java
@@ -1,7 +1,3 @@
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package example;

Expand All @@ -19,6 +15,9 @@
import java.nio.channels.Selector;
import enxio.nio.channels.NativeSelectableChannel;
import enxio.nio.channels.NativeSelectorProvider;
import enxio.nio.channels.NativeServerSocketChannel;
import enxio.nio.channels.NativeSocketChannel;
import java.nio.channels.SelectableChannel;

/**
*
Expand Down Expand Up @@ -60,7 +59,7 @@ private static interface LibC {
static short htons(short val) {
return Short.reverseBytes(val);
}
static NativeSelectableChannel serverSocket(int port) {
static NativeServerSocketChannel serverSocket(int port) {
int fd = libc.socket(LibC.AF_INET, LibC.SOCK_STREAM, 0);
System.out.println("fd=" + fd);
SockAddr addr;
Expand All @@ -85,28 +84,28 @@ static NativeSelectableChannel serverSocket(int port) {
System.exit(1);
}
System.out.println("bind+listen succeeded");
return NativeSelectableChannel.forServerSocket(fd);
return new NativeServerSocketChannel(fd);
}
private static abstract class IO {
protected final NativeSelectableChannel channel;
protected final SelectableChannel channel;
protected final Selector selector;
public IO(Selector selector, NativeSelectableChannel ch) {
public IO(Selector selector, SelectableChannel ch) {
this.selector = selector;
this.channel = ch;
}
public abstract void read();
public abstract void write();
}
private static class Accepter extends IO {
public Accepter(Selector selector, NativeSelectableChannel ch) {
public Accepter(Selector selector, NativeServerSocketChannel ch) {
super(selector, ch);
}
public void read() {
SockAddrIN sin = new SockAddrIN();
int[] addrSize = { StructUtil.getSize(sin) };
int clientfd = libc.accept(channel.getFD(), sin, addrSize);
int clientfd = libc.accept(((NativeSelectableChannel) channel).getFD(), sin, addrSize);
System.out.println("client fd = " + clientfd);
NativeSelectableChannel ch = NativeSelectableChannel.forSocket(clientfd);
NativeSocketChannel ch = new NativeSocketChannel(clientfd);
try {
ch.configureBlocking(false);
ch.register(selector, SelectionKey.OP_READ, new Client(selector, ch));
Expand All @@ -120,16 +119,16 @@ public void write() {
}
private static class Client extends IO {
private final ByteBuffer buf = ByteBuffer.allocateDirect(1024);
public Client(Selector selector, NativeSelectableChannel ch) {
public Client(Selector selector, NativeSocketChannel ch) {
super(selector, ch);
}
public void read() {
int n = libc.read(channel.getFD(), buf, buf.remaining());
int n = libc.read(((NativeSelectableChannel) channel).getFD(), buf, buf.remaining());
System.out.println("Read " + n + " bytes from client");
if (n <= 0) {
SelectionKey k = channel.keyFor(selector);
k.cancel();
libc.close(channel.getFD());
libc.close(((NativeSelectableChannel) channel).getFD());
return;
}
buf.position(n);
Expand All @@ -138,7 +137,7 @@ public void read() {
}
public void write() {
while (buf.hasRemaining()) {
int n = libc.write(channel.getFD(), buf, buf.remaining());
int n = libc.write(((NativeSelectableChannel) channel).getFD(), buf, buf.remaining());
System.out.println("write returned " + n);
if (n > 0) {
buf.position(buf.position() + n);
Expand All @@ -148,7 +147,7 @@ public void write() {
}
if (n < 0) {
channel.keyFor(selector).cancel();
libc.close(channel.getFD());
libc.close(((NativeSelectableChannel) channel).getFD());
return;
}
}
Expand All @@ -162,7 +161,7 @@ public static void main(String[] args) {
try {
Selector selector = NativeSelectorProvider.getInstance().openSelector();
for (int i = 0; i < 2; ++i) {
NativeSelectableChannel ch = serverSocket(baseport + i);
NativeServerSocketChannel ch = serverSocket(baseport + i);
ch.configureBlocking(false);
ch.register(selector, SelectionKey.OP_ACCEPT, new Accepter(selector, ch));
}
Expand Down

0 comments on commit e2bebc3

Please sign in to comment.