aboutsummaryrefslogtreecommitdiff
path: root/libjava/gnu/java
diff options
context:
space:
mode:
authorDavid Daney <ddaney@avtrex.com>2005-11-15 19:11:53 +0000
committerDavid Daney <daney@gcc.gnu.org>2005-11-15 19:11:53 +0000
commit5e6ff6bda38f8d92ef1522b45cdd78c90557ae1b (patch)
treeb24e7f59a4d050f706a76e11e684d9f172e30439 /libjava/gnu/java
parent7735d402c405f05343b3ea732426eb5ca4b43b6a (diff)
downloadgcc-5e6ff6bda38f8d92ef1522b45cdd78c90557ae1b.zip
gcc-5e6ff6bda38f8d92ef1522b45cdd78c90557ae1b.tar.gz
gcc-5e6ff6bda38f8d92ef1522b45cdd78c90557ae1b.tar.bz2
re PR libgcj/15430 (Cannot interrupt blocking I/O calls with close())
PR libgcj/15430 * gnu/java/net/natPlainSocketImplPosix.cc (throw_on_sock_closed): New function. (accept): Call it. (close): Call shutdown before closing. (read()): Call read_helper with proper parameters. (read(buffer, int, int)): Likewise. (read_helper): Pass pointer to the PlainSocketImpl, remove native_fd and timeout parameters. Make prototype to match. Use pointer to PlainSocketImpl to access members. Call throw_on_sock_closed in two places. From-SVN: r107036
Diffstat (limited to 'libjava/gnu/java')
-rw-r--r--libjava/gnu/java/net/natPlainSocketImplPosix.cc58
1 files changed, 44 insertions, 14 deletions
diff --git a/libjava/gnu/java/net/natPlainSocketImplPosix.cc b/libjava/gnu/java/net/natPlainSocketImplPosix.cc
index 5f6f046..643f4e4 100644
--- a/libjava/gnu/java/net/natPlainSocketImplPosix.cc
+++ b/libjava/gnu/java/net/natPlainSocketImplPosix.cc
@@ -226,6 +226,21 @@ gnu::java::net::PlainSocketImpl::listen (jint backlog)
}
}
+static void
+throw_on_sock_closed (gnu::java::net::PlainSocketImpl *soc_impl)
+{
+ // Avoid races from asynchronous close().
+ JvSynchronize sync (soc_impl);
+ if (soc_impl->native_fd == -1)
+ {
+ using namespace java::net;
+ // Socket was closed.
+ SocketException *se =
+ new SocketException (JvNewStringUTF ("Socket Closed"));
+ throw se;
+ }
+}
+
void
gnu::java::net::PlainSocketImpl::accept (gnu::java::net::PlainSocketImpl *s)
{
@@ -284,6 +299,7 @@ gnu::java::net::PlainSocketImpl::accept (gnu::java::net::PlainSocketImpl *s)
error:
char* strerr = strerror (errno);
+ throw_on_sock_closed (this);
throw new ::java::io::IOException (JvNewStringUTF (strerr));
}
@@ -294,7 +310,11 @@ gnu::java::net::PlainSocketImpl::close()
// Avoid races from asynchronous finalization.
JvSynchronize sync (this);
- // should we use shutdown here? how would that effect so_linger?
+ // Should we use shutdown here? Yes.
+ // How would that effect so_linger? Uncertain.
+ ::shutdown (native_fd, 2);
+ // Ignore errors in shutdown as we are closing and all the same
+ // errors are handled in the close.
int res = _Jv_close (native_fd);
if (res == -1)
@@ -371,7 +391,8 @@ gnu::java::net::PlainSocketImpl::sendUrgentData (jint)
}
static jint
-read_helper (jint native_fd, jint timeout, jbyte *bytes, jint count);
+read_helper (gnu::java::net::PlainSocketImpl *soc_impl,
+ jbyte *bytes, jint count);
// Read a single byte from the socket.
jint
@@ -379,7 +400,7 @@ gnu::java::net::PlainSocketImpl$SocketInputStream::read(void)
{
jbyte data;
- if (read_helper (this$0->native_fd, this$0->timeout, &data, 1) == 1)
+ if (read_helper (this$0, &data, 1) == 1)
return data & 0xFF;
return -1;
@@ -387,8 +408,9 @@ gnu::java::net::PlainSocketImpl$SocketInputStream::read(void)
// Read count bytes into the buffer, starting at offset.
jint
-gnu::java::net::PlainSocketImpl$SocketInputStream::read(jbyteArray buffer, jint offset,
- jint count)
+gnu::java::net::PlainSocketImpl$SocketInputStream::read(jbyteArray buffer,
+ jint offset,
+ jint count)
{
if (! buffer)
throw new ::java::lang::NullPointerException;
@@ -398,12 +420,13 @@ gnu::java::net::PlainSocketImpl$SocketInputStream::read(jbyteArray buffer, jint
if (offset < 0 || count < 0 || offset + count > bsize)
throw new ::java::lang::ArrayIndexOutOfBoundsException;
- return read_helper (this$0->native_fd, this$0->timeout,
+ return read_helper (this$0,
elements (buffer) + offset * sizeof (jbyte), count);
}
static jint
-read_helper (jint native_fd, jint timeout, jbyte *bytes, jint count)
+read_helper (gnu::java::net::PlainSocketImpl *soc_impl,
+ jbyte *bytes, jint count)
{
// If zero bytes were requested, short circuit so that recv
// doesn't signal EOF.
@@ -411,19 +434,22 @@ read_helper (jint native_fd, jint timeout, jbyte *bytes, jint count)
return 0;
// Do timeouts via select.
- if (timeout > 0 && native_fd >= 0 && native_fd < FD_SETSIZE)
+ if (soc_impl->timeout > 0
+ && soc_impl->native_fd >= 0
+ && soc_impl->native_fd < FD_SETSIZE)
{
// Create the file descriptor set.
fd_set read_fds;
FD_ZERO (&read_fds);
- FD_SET (native_fd, &read_fds);
+ FD_SET (soc_impl->native_fd, &read_fds);
// Create the timeout struct based on our internal timeout value.
struct timeval timeout_value;
- timeout_value.tv_sec = timeout / 1000;
- timeout_value.tv_usec =(timeout % 1000) * 1000;
+ timeout_value.tv_sec = soc_impl->timeout / 1000;
+ timeout_value.tv_usec =(soc_impl->timeout % 1000) * 1000;
// Select on the fds.
int sel_retval =
- _Jv_select (native_fd + 1, &read_fds, NULL, NULL, &timeout_value);
+ _Jv_select (soc_impl->native_fd + 1,
+ &read_fds, NULL, NULL, &timeout_value);
// We're only interested in the 0 return.
// error returns still require us to try to read
// the socket to see what happened.
@@ -437,10 +463,13 @@ read_helper (jint native_fd, jint timeout, jbyte *bytes, jint count)
}
// Read the socket.
- int r = ::recv (native_fd, (char *) bytes, count, 0);
+ int r = ::recv (soc_impl->native_fd, (char *) bytes, count, 0);
if (r == 0)
- return -1;
+ {
+ throw_on_sock_closed (soc_impl);
+ return -1;
+ }
if (::java::lang::Thread::interrupted())
{
@@ -452,6 +481,7 @@ read_helper (jint native_fd, jint timeout, jbyte *bytes, jint count)
}
else if (r == -1)
{
+ throw_on_sock_closed (soc_impl);
// Some errors cause us to return end of stream...
if (errno == ENOTCONN)
return -1;