JDK-8071599 : (so) Socket adapter sendUrgentData throws IllegalBlockingMode when channel configured non-blocking
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.nio
  • Affected Version: 9
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2015-01-26
  • Updated: 2016-08-24
  • Resolved: 2015-02-27
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8 JDK 9
8u60Fixed 9 b54Fixed
Description
sc.socket().sendUrgentData(b) throws IllegalBlockingMode when channel configured non-blocking. This is correct behavior because java.net.Socket is blocking only and Socket operations are expected to block.

It has been suggested that that sendUrgentData should work with SocketChannel's configured non-blocking. In order to do this then it requires understanding how send(MSG_OOB) behaves when the socket buffer is full and whether send can return EAGAIN/EWOULDBLOCK.

The data that have so far is:

Linux - returns EAGAIN/EWOULDBLOCK
OSX - fails with "No buffer space available"
Windows - fails with " Resource temporarily unavailable: no further information"

The I/O error is okay as that is allowed by the spec.





Comments
Review threads: [1] http://mail.openjdk.java.net/pipermail/nio-dev/2015-February/003042.html [2] http://mail.openjdk.java.net/pipermail/nio-dev/2015-February/003046.html [3] http://mail.openjdk.java.net/pipermail/nio-dev/2015-February/003065.html Sub-thread [3] is the version approved for this fix.
27-02-2015

I've changed the fixVersion to 9 as this needs to be pushed to 9 first and bake before a back-port to 8uX is considered.
21-02-2015

Solaris succeeds in sending an out of band byte when the socket buffer is full. On Mac OS X the error message "No buffer space available" corresponds to send() failing with errno set to ENOBUFS which is described in the man page by [ENOBUFS] The system is unable to allocate an internal buffer. The operation may succeed when buffers become available. [ENOBUFS] The output queue for a network interface is full. This generally indicates that the interface has stopped sending, but may be caused by transient congestion Presumably it is the second situation which obtains here. On Windows the error message "Resource temporarily unavailable" corresponds to the Windows Socket error code WSAEWOULDBLOCK which is described by This error is returned from operations on nonblocking sockets that cannot be completed immediately [...]
28-01-2015

A possible approach is to have sendUrgentData fail with an IOException when the socket buffer is full, as in the following: diff --git a/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java b/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java --- a/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java +++ b/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java @@ -321,12 +321,9 @@ } public void sendUrgentData(int data) throws IOException { - synchronized (sc.blockingLock()) { - if (!sc.isBlocking()) - throw new IllegalBlockingModeException(); - int n = sc.sendOutOfBandData((byte)data); - assert n == 1; - } + int n = sc.sendOutOfBandData((byte)data); + if (n == 0) + throw new IOException("Socket buffer full"); } public void setOOBInline(boolean on) throws SocketException {
27-01-2015