java.nio ramblings (was Re: What's Left for MingW 3.3)

Mohan Embar gnustuff@thisiscool.com
Tue Apr 15 17:32:00 GMT 2003


Hi Andrew,

>But it looks to me like this is quite deliberate:
>
>  ServerSocket sock_object;
>  int fd;
>
>So there is a fd that belings to ServerSocket's impl and one that
>belongs to ServerSocketChannelImpl....

This can't possibly be right. ServerSocket and ServerSocketChannelImpl
need to share the same file descriptor or else ServerSocketChannelImpl
shouldn't have a file descriptor at all.

I realize that java.nio is incomplete, so I don't want to beat this
to death. I also realize we need some input from the author, but in the absence
of that, I'm going to try to go into Michael's head, try to explain why I
think he did this, then throw in my two cents worth.

If you look at the introductory paragraphs here:

http://java.sun.com/j2se/1.4.1/docs/api/java/nio/channels/ServerSocketChannel.html

...you see that most of the functionality of server socket channels
is exposed through the ServerSocket object you get from ServerSocketChannel.socket().
However (using the safe assumption that all OSes use integers for socket descriptors),
you might need the integer fd to implement some other methods of ServerSocketChannel.
Unfortunately, there is no way to construct a ServerSocket from an fd.

(In a perfect world, all of the functionality in java.nio.channels would be in java.net,
ServerSocket would be an interface, you could leverage package-private classes and
none of this would be an issue.)

Note that the current implementation of ServerSocket is incorrect
in two ways:

- ServerSocket.ServerSocket() is incorrect WRT java.nio.channels.ServerSocketChannel.open()
  because you're not allowed to test for and use a factory in this case (see the introductory class
  comments in the above hyperlink)
- ServerSocket.getChannel() doesn't appear to work (there is no way to set ch).
  With the current implementation, there is no way of doing this without breaching
  encapsulation since ServerSocket and ServerSocketChannel(Impl) are in
  different packages.

I don't know what they JDK does, but see a possible solution in the context of GCJ:

- move java.net.PlainSocketImpl to gnu.java.net (which doesn't exist yet) and make it
  (necessarily) public; enhance it to support all the functionality needed for java.nio.channels
- create a package-private subclass of java.net.ServerSocket called java.nio.channels.ChannelServerSocket
  (you could also make this a private nested or inner class of ServerSocketChannelImpl) and in its constructor
  create and delegate to PlainSocketImpl
- for the non-ServerSocket-related functions in ServerSocketChannel, delegate directly
  to the PlainSocketImpl that ChannelServerSocket is holding onto

This would solve both of the problems I mentioned.

One hole in the above approach is that the methods in ServerSocket delegate
to impl, which is private to ServerSocket. You could either
make impl protected, or if you want to keep impl private, override every
single method of ServerSocket and delegate to our (ChannelServerSocket)
own PlainSocketImpl. This is a hack to work around the fact that ServerSocket
isn't an interface.

P.S. The MingW "simple" patch is forthcoming.

-- Mohan
http://www.thisiscool.com/
http://www.animalsong.org/






More information about the Java mailing list