Commit 5e6ff6bd by David Daney Committed by David Daney

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
parent 7735d402
2005-15-09 David Daney <ddaney@avtrex.com>
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.
2005-11-15 Andrew Haley <aph@redhat.com> 2005-11-15 Andrew Haley <aph@redhat.com>
* Merge from Classpath head: * Merge from Classpath head:
......
...@@ -226,6 +226,21 @@ gnu::java::net::PlainSocketImpl::listen (jint backlog) ...@@ -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 void
gnu::java::net::PlainSocketImpl::accept (gnu::java::net::PlainSocketImpl *s) gnu::java::net::PlainSocketImpl::accept (gnu::java::net::PlainSocketImpl *s)
{ {
...@@ -284,6 +299,7 @@ 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: error:
char* strerr = strerror (errno); char* strerr = strerror (errno);
throw_on_sock_closed (this);
throw new ::java::io::IOException (JvNewStringUTF (strerr)); throw new ::java::io::IOException (JvNewStringUTF (strerr));
} }
...@@ -294,7 +310,11 @@ gnu::java::net::PlainSocketImpl::close() ...@@ -294,7 +310,11 @@ gnu::java::net::PlainSocketImpl::close()
// Avoid races from asynchronous finalization. // Avoid races from asynchronous finalization.
JvSynchronize sync (this); 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); int res = _Jv_close (native_fd);
if (res == -1) if (res == -1)
...@@ -371,7 +391,8 @@ gnu::java::net::PlainSocketImpl::sendUrgentData (jint) ...@@ -371,7 +391,8 @@ gnu::java::net::PlainSocketImpl::sendUrgentData (jint)
} }
static 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. // Read a single byte from the socket.
jint jint
...@@ -379,7 +400,7 @@ gnu::java::net::PlainSocketImpl$SocketInputStream::read(void) ...@@ -379,7 +400,7 @@ gnu::java::net::PlainSocketImpl$SocketInputStream::read(void)
{ {
jbyte data; 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 data & 0xFF;
return -1; return -1;
...@@ -387,8 +408,9 @@ gnu::java::net::PlainSocketImpl$SocketInputStream::read(void) ...@@ -387,8 +408,9 @@ gnu::java::net::PlainSocketImpl$SocketInputStream::read(void)
// Read count bytes into the buffer, starting at offset. // Read count bytes into the buffer, starting at offset.
jint jint
gnu::java::net::PlainSocketImpl$SocketInputStream::read(jbyteArray buffer, jint offset, gnu::java::net::PlainSocketImpl$SocketInputStream::read(jbyteArray buffer,
jint count) jint offset,
jint count)
{ {
if (! buffer) if (! buffer)
throw new ::java::lang::NullPointerException; throw new ::java::lang::NullPointerException;
...@@ -398,12 +420,13 @@ gnu::java::net::PlainSocketImpl$SocketInputStream::read(jbyteArray buffer, jint ...@@ -398,12 +420,13 @@ gnu::java::net::PlainSocketImpl$SocketInputStream::read(jbyteArray buffer, jint
if (offset < 0 || count < 0 || offset + count > bsize) if (offset < 0 || count < 0 || offset + count > bsize)
throw new ::java::lang::ArrayIndexOutOfBoundsException; 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); elements (buffer) + offset * sizeof (jbyte), count);
} }
static 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)
{ {
// If zero bytes were requested, short circuit so that recv // If zero bytes were requested, short circuit so that recv
// doesn't signal EOF. // doesn't signal EOF.
...@@ -411,19 +434,22 @@ read_helper (jint native_fd, jint timeout, jbyte *bytes, jint count) ...@@ -411,19 +434,22 @@ read_helper (jint native_fd, jint timeout, jbyte *bytes, jint count)
return 0; return 0;
// Do timeouts via select. // 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. // Create the file descriptor set.
fd_set read_fds; fd_set read_fds;
FD_ZERO (&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. // Create the timeout struct based on our internal timeout value.
struct timeval timeout_value; struct timeval timeout_value;
timeout_value.tv_sec = timeout / 1000; timeout_value.tv_sec = soc_impl->timeout / 1000;
timeout_value.tv_usec =(timeout % 1000) * 1000; timeout_value.tv_usec =(soc_impl->timeout % 1000) * 1000;
// Select on the fds. // Select on the fds.
int sel_retval = 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. // We're only interested in the 0 return.
// error returns still require us to try to read // error returns still require us to try to read
// the socket to see what happened. // the socket to see what happened.
...@@ -437,10 +463,13 @@ read_helper (jint native_fd, jint timeout, jbyte *bytes, jint count) ...@@ -437,10 +463,13 @@ read_helper (jint native_fd, jint timeout, jbyte *bytes, jint count)
} }
// Read the socket. // 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) if (r == 0)
return -1; {
throw_on_sock_closed (soc_impl);
return -1;
}
if (::java::lang::Thread::interrupted()) if (::java::lang::Thread::interrupted())
{ {
...@@ -452,6 +481,7 @@ read_helper (jint native_fd, jint timeout, jbyte *bytes, jint count) ...@@ -452,6 +481,7 @@ read_helper (jint native_fd, jint timeout, jbyte *bytes, jint count)
} }
else if (r == -1) else if (r == -1)
{ {
throw_on_sock_closed (soc_impl);
// Some errors cause us to return end of stream... // Some errors cause us to return end of stream...
if (errno == ENOTCONN) if (errno == ENOTCONN)
return -1; return -1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment