[kaffe] CVS kaffe (guilhem): Socket methods can be used asynchronously now.

Kaffe CVS cvs-commits at kaffe.org
Fri Nov 25 13:12:51 PST 2005


PatchSet 6970 
Date: 2005/11/25 21:01:51
Author: guilhem
Branch: HEAD
Tag: (none) 
Log:
Socket methods can be used asynchronously now.

        * include/jsyscall.h
        (sockShutdown): New syscall to support.
        (KSOCKSHUTDOWN): New macro.

        * kaffe/kaffevm/systems/unix-jthreads/syscalls.c,
        (jthreadedSocketShutdown): Added support for shutdown.

        * kaffe/kaffevm/systems/unix-jthreads/syscalls.c,
        (jthreadedSocketShutdown): Added support for shutdown.
        (selectHelper): New function which protect calls to select.
        (waitForTimeout, waitForWritable): Use selectHelper now.
        (waitForRW): New function.
        (jthreadedAccept): Use waitForRW and not waitForTimeout.

        * libraries/clib/net/PlainSocketImpl.c
        (getFileFromSocket): New function to retrieve safely a fd from a
        socket object.
        (releaseFileToSocket): Release the fd.
        (socketCreate, socketConnect, socketBind,
        socketListen, socketAccept, socketAvailable,
        socketSetOption, socketGetOption, socketRead,
        socketWrite, waitForConnection): Use the new facility to
        get the fd.
        (socketClose): Shutdown the socket and if possible close the fd.

        * libraries/javalib/vmspecific/gnu/java/net/PlainSocketImpl.java
        (fdUsed): New field.
        (available, close, getInputStream, socketGetOption,
        socketSetOption, socketAccept, socketAvailable,
        socketBind, socketClose, socketConnect, socketCreate,
        socketListen, socketRead, socketWrite, waitForConnection,
        setBlocking): Removed synchronization.

Members: 
	ChangeLog:1.4492->1.4493 
	include/jsyscall.h:1.23->1.24 
	kaffe/kaffevm/systems/unix-jthreads/syscalls.c:1.17->1.18 
	kaffe/kaffevm/systems/unix-pthreads/syscalls.c:1.33->1.34 
	libraries/clib/net/PlainSocketImpl.c:1.56->1.57 
	libraries/javalib/vmspecific/gnu/java/net/PlainSocketImpl.java:1.1->1.2 

Index: kaffe/ChangeLog
diff -u kaffe/ChangeLog:1.4492 kaffe/ChangeLog:1.4493
--- kaffe/ChangeLog:1.4492	Fri Nov 25 18:12:47 2005
+++ kaffe/ChangeLog	Fri Nov 25 21:01:51 2005
@@ -1,5 +1,40 @@
 2005-11-25  Guilhem Lavaux  <guilhem at kaffe.org>
 
+	* include/jsyscall.h
+	(sockShutdown): New syscall to support.
+	(KSOCKSHUTDOWN): New macro.
+
+	* kaffe/kaffevm/systems/unix-jthreads/syscalls.c,
+	(jthreadedSocketShutdown): Added support for shutdown.
+
+	* kaffe/kaffevm/systems/unix-jthreads/syscalls.c,
+	(jthreadedSocketShutdown): Added support for shutdown.
+	(selectHelper): New function which protect calls to select.
+	(waitForTimeout, waitForWritable): Use selectHelper now.
+	(waitForRW): New function.
+	(jthreadedAccept): Use waitForRW and not waitForTimeout.
+
+	* libraries/clib/net/PlainSocketImpl.c
+	(getFileFromSocket): New function to retrieve safely a fd from a
+	socket object.
+	(releaseFileToSocket): Release the fd.
+	(socketCreate, socketConnect, socketBind,
+	socketListen, socketAccept, socketAvailable,
+	socketSetOption, socketGetOption, socketRead,
+	socketWrite, waitForConnection): Use the new facility to
+	get the fd.
+	(socketClose): Shutdown the socket and if possible close the fd.
+
+	* libraries/javalib/vmspecific/gnu/java/net/PlainSocketImpl.java
+	(fdUsed): New field.
+	(available, close, getInputStream, socketGetOption, 
+	socketSetOption, socketAccept, socketAvailable,
+	socketBind, socketClose, socketConnect, socketCreate,
+	socketListen, socketRead, socketWrite, waitForConnection,
+	setBlocking): Removed synchronization.
+	
+2005-11-25  Guilhem Lavaux  <guilhem at kaffe.org>
+
 	* libraries/clib/native/java_lang_VMProcess.c
 	(nativeSpawn): Fixed eclipse startup by using the true kaffe
 	internal functions.
Index: kaffe/include/jsyscall.h
diff -u kaffe/include/jsyscall.h:1.23 kaffe/include/jsyscall.h:1.24
--- kaffe/include/jsyscall.h:1.23	Fri Aug  5 01:14:36 2005
+++ kaffe/include/jsyscall.h	Fri Nov 25 21:01:53 2005
@@ -84,6 +84,7 @@
 	int	(*_getsockname)(int, struct sockaddr *, socklen_t *);
 	int	(*_getpeername)(int, struct sockaddr *, socklen_t *);
 	int	(*_sockclose)(int);
+        int     (*_sockShutdown)(int);
 	int	(*_gethostbyname)(const char *, struct hostent **);
 	int	(*_gethostbyaddr)(const char *, size_t, int, struct hostent **);
 
@@ -257,6 +258,8 @@
 #define KPIPECREATE(A,B)   (*Kaffe_SystemCallInterface._pipecreate)(A,B)
 #define KPIPEREAD(A,B,C,D,E) (*Kaffe_SystemCallInterface._piperead)(A,B,C,D,E)
 #define KPIPEWRITE(A,B,C,D,E) (*Kaffe_SystemCallInterface._pipewrite)(A,B,C,D,E)
+
+#define KSOCKSHUTDOWN(A) (*Kaffe_SystemCallInterface._sockShutdown)(A)
 
 #define KAFFE_MMAP_READ 0
 #define KAFFE_MMAP_WRITE 1
Index: kaffe/kaffe/kaffevm/systems/unix-jthreads/syscalls.c
diff -u kaffe/kaffe/kaffevm/systems/unix-jthreads/syscalls.c:1.17 kaffe/kaffe/kaffevm/systems/unix-jthreads/syscalls.c:1.18
--- kaffe/kaffe/kaffevm/systems/unix-jthreads/syscalls.c:1.17	Tue May  3 20:43:04 2005
+++ kaffe/kaffe/kaffevm/systems/unix-jthreads/syscalls.c	Fri Nov 25 21:01:53 2005
@@ -37,6 +37,19 @@
 }
 
 static int
+jthreadedSocketShutdown(int fd)
+{
+        int rc = 0;
+
+	jthread_spinon(0);
+	if (shutdown(fd, 2) == -1)
+	  rc = errno;
+	jthread_spinoff(0);
+
+	return rc;
+}
+
+static int
 jthreadedListen(int fd, int l)
 {
 	int rc = 0;
@@ -424,6 +437,7 @@
         jthreadedGetSockName, 
         jthreadedGetPeerName, 
         jthreadedClose,
+	jthreadedSocketShutdown,
         jthreadedGetHostByName,
         jthreadedGetHostByAddr,
         jthreadedSelect,	
Index: kaffe/kaffe/kaffevm/systems/unix-pthreads/syscalls.c
diff -u kaffe/kaffe/kaffevm/systems/unix-pthreads/syscalls.c:1.33 kaffe/kaffe/kaffevm/systems/unix-pthreads/syscalls.c:1.34
--- kaffe/kaffe/kaffevm/systems/unix-pthreads/syscalls.c:1.33	Sat Aug  6 14:25:15 2005
+++ kaffe/kaffe/kaffevm/systems/unix-pthreads/syscalls.c	Fri Nov 25 21:01:53 2005
@@ -59,64 +59,65 @@
 		r = 0;					\
 	}
 
-static 
-int
-waitForTimeout(int fd, int timeout){
-	fd_set rset;
-	struct timeval tv;
-	int ret;
-
-	FD_ZERO(&rset);
-	FD_SET(fd,&rset);
-	tv.tv_sec = timeout / 1000;
-	tv.tv_usec = (timeout % 1000) * 1000;
-
-	jthread_current()->interrupting = 0;
-	if (timeout == NOTIMEOUT) 
-		ret = select(fd+1,&rset,NULL,NULL,NULL);
-	else	
-		ret = select(fd+1,&rset,NULL,NULL,&tv);
-
-	if (ret == 0) 
-		errno = ETIMEDOUT;
-	else if (ret == -1)
-	{
-		errno = EINTR;
-		jthread_current()->interrupting = 1;
-	}
+static int selectHelper(int n, fd_set *readfds, fd_set *writefds, fd_set *errfds, int timeout)
+{
+  struct timeval tv;
+  int ret;
 
-	return (ret);
+  jthread_current()->interrupting = 0;
+  if (timeout == NOTIMEOUT)
+    {
+      ret = select(n, readfds, writefds, errfds, NULL);
+    }
+  else
+    {      
+      tv.tv_sec = timeout / 1000;
+      tv.tv_usec = (timeout % 1000) * 1000;
+      ret = select(n, readfds, writefds, errfds, &tv);
+    }
+
+  if (ret == 0)
+    errno = ETIMEDOUT;
+  else if (ret == -1)
+    {
+      errno = EINTR;
+      jthread_current()->interrupting = 1;
+    }
+  
+  return ret;
 }
 
-/* These two functions would need to be merged some time later.
- */
-static
-int waitForWritable(int fd, int timeout)
+static int
+waitForTimeout(int fd, int timeout)
 {
-	fd_set wset;
-	struct timeval tv;
-	int ret;
-
-	FD_ZERO(&wset);
-        FD_SET(fd,&wset);
-        tv.tv_sec = timeout / 1000;
-	tv.tv_usec = (timeout % 1000) * 1000;
-
-	jthread_current()->interrupting = 0;
-        if (timeout == NOTIMEOUT)
-		ret = select(fd+1,NULL,&wset,NULL,NULL);
-	else
-		ret = select(fd+1,NULL,&wset,NULL,&tv);
+  fd_set rset;
+  
+  FD_ZERO(&rset);
+  FD_SET(fd,&rset);
+  
+  return selectHelper(fd+1, &rset, NULL, NULL, timeout);
+}
 
-	if (ret == 0)
-		errno = ETIMEDOUT;
-	else if (ret == -1)
-	{
-		errno = EINTR;
-		jthread_current()->interrupting = 1;
-	}
+static int
+waitForRW(int fd, int timeout)
+{
+  fd_set rwset;
+  
+  FD_ZERO(&rwset);
+  FD_SET(fd,&rwset);
+  
+  return selectHelper(fd+1, &rwset, &rwset, NULL, timeout);
+}
 
-	return (ret);
+static int
+waitForWritable(int fd, int timeout)
+{
+  fd_set wset;
+  
+  FD_ZERO(&wset);
+  FD_SET(fd,&wset);
+  
+  return selectHelper(fd+1, NULL, &wset, NULL, timeout);
 }
 
 static
@@ -174,6 +175,17 @@
 }
 
 static int
+jthreadedSocketShutdown(int fd)
+{
+       int rc = 0;
+  
+       if (shutdown(fd, 2) == -1)
+	 rc = errno;
+
+       return rc;
+}
+
+static int
 jthreadedListen(int fd, int l)
 {
 	int rc = 0;
@@ -472,7 +484,7 @@
 {
 	/* absolute time at which time out is reached */
 	int r=-1, ret;	
-	ret = waitForTimeout(fd,timeout);
+	ret = waitForRW(fd,timeout);
 
 	/* If result is 0, we had a timeout. 
 	 * If it's not, let's try to accept.
@@ -591,12 +603,6 @@
 	jthread_set_blocking(fd, 0);
 	SET_DEADLINE(deadline, timeout)
 	for (;;) {
-		r = recvfrom(fd, buf, len, flags, from, fromlen);
-		if (r >= 0 || !(errno == EWOULDBLOCK || errno == EINTR 
-					|| errno == EAGAIN)) {
-			break;
-		}
-		IGNORE_EINTR(r)
 		if (timeout != NOTIMEOUT) {
 		        poll_timeout = deadline - currentTime();
 			if (poll_timeout > 0)
@@ -605,6 +611,8 @@
 			waitForTimeout(fd, NOTIMEOUT);
 		}
 		BREAK_IF_LATE(deadline, timeout)
+
+		r = recvfrom(fd, buf, len, flags, from, fromlen);
 	}
 	jthread_set_blocking(fd, blocking);
 	SET_RETURN_OUT(r, out, r)
@@ -900,6 +908,7 @@
         jthreadedGetSockName, 
         jthreadedGetPeerName, 
         jthreadedClose,
+	jthreadedSocketShutdown,
         jthreadedGetHostByName,
         jthreadedGetHostByAddr,
         jthreadedSelect,	
Index: kaffe/libraries/clib/net/PlainSocketImpl.c
diff -u kaffe/libraries/clib/net/PlainSocketImpl.c:1.56 kaffe/libraries/clib/net/PlainSocketImpl.c:1.57
--- kaffe/libraries/clib/net/PlainSocketImpl.c:1.56	Fri Aug 12 02:26:15 2005
+++ kaffe/libraries/clib/net/PlainSocketImpl.c	Fri Nov 25 21:01:54 2005
@@ -27,6 +27,7 @@
 #include "object.h"
 #include "itypes.h"
 #include "exception.h"
+#include "locks.h"
 
 #include "dummyin6.h"
 
@@ -131,6 +132,51 @@
 #endif /* defined(HAVE_STRUCT_SOCKADDR_IN6) */
 #endif /* defined(KAFFE_VMDEBUG) && !defined(NDEBUG) */
 
+/**
+ * This is a helper functions to obtain safely a file descriptor which represents
+ * the socket.
+ *
+ * @param this A valid socket implementation.
+ * @return A valid file descriptor if available.
+ */
+static int
+getFileFromSocket(struct Hgnu_java_net_PlainSocketImpl* this)
+{
+  int fd;
+
+  lockObject((struct Hjava_lang_Object *)this);
+  fd = (int)unhand(this)->native_fd;
+  if (fd < 0)
+    {
+      unlockObject((struct Hjava_lang_Object *)this);
+      SignalError("java.net.SocketException", "fd invalid");
+    }
+  unhand(this)->fdUsed++;
+  unlockObject((struct Hjava_lang_Object*)this);
+  
+  return fd;
+}
+
+/**
+ * This is a helper functions to return safely a file descriptor to
+ * the socket.
+ *
+ * @param this A valid socket implementation.
+ */
+static void
+releaseFileToSocket(struct Hgnu_java_net_PlainSocketImpl* this)
+{
+  lockObject((struct Hjava_lang_Object*)this);
+  unhand(this)->fdUsed--;
+
+  if (unhand(this)->fdUsed == 0)
+    {
+      KSOCKCLOSE(unhand(this)->native_fd);
+      unhand(this)->native_fd = -1;
+    }
+  unlockObject((struct Hjava_lang_Object*)this);
+}
+
 /*
  * Create a stream or datagram socket.
  */
@@ -163,7 +209,7 @@
 		    this, stream ? "stream" : "datagram", fd);
 	    );
 
-	unhand(this)->native_fd = fd;
+	unhand(this)->fdUsed++;
 	unhand(this)->native_fd = fd;
 }
 
@@ -216,13 +262,15 @@
 		    this, ip2str(addr.addr4.sin_addr.s_addr), dport, timeout);
 	    );
 
-	fd = (int)unhand(this)->native_fd;
+	fd = getFileFromSocket(this);
 	r = KCONNECT(fd, (struct sockaddr*)&addr, alen, timeout);
 	if (r == EINTR) {
+	        releaseFileToSocket(this);
 		SignalError("java.io.InterruptedIOException", 
 			    "Connect was interrupted");
 	}
 	if (r == ETIMEDOUT) {
+	        releaseFileToSocket(this);
 	        SignalError("java.net.SocketTimeoutException",
 			    "Connect timed out");
 	}
@@ -231,12 +279,14 @@
 		return;
 	}
 	if (r) {
+	        releaseFileToSocket(this);
 		SignalError("java.io.IOException", SYS_ERROR(r));
 	}
 
 	/* Enter information into socket object */
 	alen = sizeof(addr);
 	r = KGETSOCKNAME(fd, (struct sockaddr*)&addr, &alen);
+	releaseFileToSocket(this);
 	if (r) {
 		SignalError("java.io.IOException", SYS_ERROR(r));
 	}
@@ -312,7 +362,7 @@
 	} else {
 		SignalError("java.net.SocketException", "Unsupported address family");
 	}
-	fd = (int)unhand(this)->native_fd;
+	fd = getFileFromSocket(this);
 
 	/* Allow rebinding to socket - ignore errors */
 	(void)KSETSOCKOPT(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on));
@@ -324,9 +374,11 @@
 	case EADDRNOTAVAIL:
 	case EADDRINUSE:
 	case EACCES:
+	        releaseFileToSocket(this);
 		SignalError("java.net.BindException", SYS_ERROR(r));
 		break;
 	default:
+	        releaseFileToSocket(this);
 		SignalError("java.net.SocketException", SYS_ERROR(r));
 		break;
 	}
@@ -336,6 +388,7 @@
 	if (lport == 0) {
 		alen = sizeof(addr);
 		r = KGETSOCKNAME(fd, (struct sockaddr*)&addr, &alen);
+		releaseFileToSocket(this);
 		if (r) {
 			SignalError("java.io.IOException", SYS_ERROR(r));
 		}
@@ -363,7 +416,8 @@
 	    dprintf("socketListen(%p, count=%d)\n", this, count);
 	    );
 
-	r = KLISTEN((int)unhand(this)->native_fd, count);
+	r = KLISTEN(getFileFromSocket(this), count);
+	releaseFileToSocket(this);
 	if (r) {
 		SignalError("java.io.IOException", SYS_ERROR(r));
 	}
@@ -375,6 +429,7 @@
 void
 gnu_java_net_PlainSocketImpl_socketAccept(struct Hgnu_java_net_PlainSocketImpl* this, struct Hjava_net_SocketImpl* sock)
 {
+        int fd;
 	int r;
 	int rc, rc1;
 	socklen_t alen;
@@ -384,6 +439,8 @@
 	  (struct Hgnu_java_net_PlainSocketImpl *)sock;
 	jvalue jv;
 
+	fd = getFileFromSocket(this);
+
 	remote_addr = NULL;
 	memset(&addr, 0, sizeof(addr));
 
@@ -406,8 +463,13 @@
 
 	alen = sizeof(addr);
 	do {
-	        rc = KACCEPT(unhand(this)->native_fd,
+	        rc = KACCEPT(fd,
 			     (struct sockaddr*)&addr, &alen, unhand(this)->timeout, &r);
+		releaseFileToSocket(this);
+		if (unhand(this)->native_fd < 0)
+		  {
+		    SignalError("java.net.SocketException", "Socket was closed");
+		  }
 	} while (rc == EINTR);
 	if (rc == ETIMEDOUT) {
 	  	DBG(NATIVENET,
@@ -428,6 +490,7 @@
 	}
 
 	unhand(accepted_socket)->native_fd = r;
+	unhand(accepted_socket)->fdUsed++;
 
 	/* Enter information into socket object */
 	alen = sizeof(addr);
@@ -501,12 +564,13 @@
 	DBG(NATIVENET,
 	    dprintf("socketAvailable(%p)\n", this);
 	    );
-	fd = (int)unhand(this)->native_fd;
+	fd = getFileFromSocket(this);
 
 #if defined(HAVE_IOCTL) && defined(FIONREAD)
 	/* XXX make part of system call interface to protect errno */
 	r = ioctl(fd, FIONREAD, &len);
 	if (r < 0) {
+	        releaseFileToSocket(this);
 		SignalError("java.io.IOException", SYS_ERROR(errno));
 	}
 #else /* !(defined(HAVE_IOCTL) && defined(FIONREAD)) */
@@ -533,6 +597,7 @@
 	    dprintf("socketAvailable(%p) -> %d\n", this, len);
 	    );
 
+	releaseFileToSocket(this);
 	return (len);
 }
 
@@ -549,8 +614,16 @@
 	    );
 
 	if (unhand(this)->native_fd != -1) {
-		r = KSOCKCLOSE((int)unhand(this)->native_fd);
-		unhand(this)->native_fd = -1;
+	        r = KSOCKSHUTDOWN((int)unhand(this)->native_fd);
+		lockObject((struct Hjava_lang_Object*)this);
+		unhand(this)->fdUsed--;
+		if (unhand(this)->fdUsed == 0 && r == 0)
+		  {
+		    r = KSOCKCLOSE((int)unhand(this)->native_fd);
+		    unhand(this)->native_fd = -1;
+		  }
+		unlockObject((struct Hjava_lang_Object*)this);
+
 		if (r) {
 			SignalError("java.io.IOException", SYS_ERROR(r));
 		}
@@ -564,6 +637,7 @@
 {
 	int r, v;
 	unsigned int k;
+	int fd;
 
 	DBG(NATIVENET,
 	    const char *optstr = "UNKNOWN";
@@ -573,6 +647,7 @@
 	    dprintf("socketSetOption(%p, %s, arg=%p)\n", this, optstr, arg);
 	    );
 
+
 	/* Do easy cases */
 	for (k = 0; k < sizeof(socketOptions) / sizeof(*socketOptions); k++) {
 		if (opt == socketOptions[k].jopt) {
@@ -580,6 +655,8 @@
 			char *optdata;
 			int optlen;
 			
+			fd = getFileFromSocket(this);
+
 			v = unhand((struct Hjava_lang_Integer*)arg)->value;
 			if( socketOptions[k].copt == SO_LINGER )
 			{
@@ -593,16 +670,16 @@
 				optdata = (char *)&v;
 				optlen = sizeof(v);
 			}
-			r = KSETSOCKOPT((int)unhand(this)->native_fd,
+			r = KSETSOCKOPT(fd,
 				socketOptions[k].level, socketOptions[k].copt,
 				optdata, optlen);
+			releaseFileToSocket(this);
 			if (r) {
 				SignalError("java.net.SocketException", SYS_ERROR(r));
 			}
 			return;
 		}
 	}
-
 	/* Do harder cases */
 	switch(opt) {
 	case java_net_SocketOptions_SO_BINDADDR:
@@ -624,6 +701,7 @@
 	int r = 0, v;
 	socklen_t vsize = sizeof(v);
 	unsigned int k;
+	int fd;
 
 	DBG(NATIVENET,
 	    const char *optstr = "UNKNOWN";
@@ -636,9 +714,11 @@
 	/* Do easy cases */
 	for (k = 0; k < sizeof(socketOptions) / sizeof(*socketOptions); k++) {
 		if (opt == socketOptions[k].jopt) {
-			r = KGETSOCKOPT((int)unhand(this)->native_fd,
+		        fd = getFileFromSocket(this);
+			r = KGETSOCKOPT(fd,
 				socketOptions[k].level, socketOptions[k].copt,
 				&v, &vsize);
+			releaseFileToSocket(this);
 			if (r) {
 				SignalError("java.net.SocketException", SYS_ERROR(r));
 			}
@@ -652,8 +732,10 @@
 	/* Do harder cases */
 	switch(opt) {
 	case java_net_SocketOptions_SO_BINDADDR:
-		r = KGETSOCKNAME((int)unhand(this)->native_fd,
+	        fd = getFileFromSocket(this);
+		r = KGETSOCKNAME(fd,
 			(struct sockaddr*)&addr, &alen);
+		releaseFileToSocket(this);
 		if (r) {
 			SignalError("java.net.SocketException", SYS_ERROR(r));
 		}
@@ -683,19 +765,18 @@
 		    this, buf, offset, len);
 	    );
 
-	fd = (int)unhand(this)->native_fd;
-	if (fd < 0) {
-		SignalError("java.io.IOException", "fd invalid"); 
-	}
+	fd = getFileFromSocket(this);
 
 	total_read = 0;
 	r = 0;
 	do {
-		rc = KSOCKREAD(fd, &unhand_array(buf)->body[offset], (unsigned)len, unhand(this)->timeout, &r);
+	         rc = KSOCKREAD(fd, &unhand_array(buf)->body[offset], (unsigned)len, unhand(this)->timeout, &r);
 
 		 if (rc == ETIMEDOUT) {
 		         struct Hjava_io_InterruptedIOException* except;
 
+			 releaseFileToSocket(this);
+
 			 except = (struct Hjava_io_InterruptedIOException *)
 			   execute_java_constructor(
 						    "java.net.SocketTimeoutException", NULL, NULL,
@@ -705,14 +786,21 @@
 	      
 			 throwException((struct Hjava_lang_Throwable*)except);
 		 } else if (rc != EINTR && rc != 0) {
-		   SignalError("java.io.IOException", SYS_ERROR(rc));
+		   releaseFileToSocket(this);
+		   if (unhand(this)->native_fd < 0)
+		     SignalError("java.net.SocketException", "Socket was closed");
+
+		   SignalError("java.net.IOException", SYS_ERROR(rc));
 		 } else if (rc == 0 && r == 0 && len > 0) {
+		   releaseFileToSocket(this);
 		   return (-1);
 		 }
 		 offset += r;
 		 len -= r;
 		 total_read += r;
 	} while (rc == EINTR);
+
+	releaseFileToSocket(this);
 	return (total_read);
 }
 
@@ -728,20 +816,23 @@
 		    this, buf, offset, len);
 	    );
 
-	fd = (int)unhand(this)->native_fd;
-	if (fd >= 0) {
-		while (len > 0) {
-			r = KSOCKWRITE(fd,
-			    &unhand_array(buf)->body[offset], (unsigned)len, &nw);
-			if (r) {
-				SignalError("java.io.IOException", SYS_ERROR(r));
-			}
-			offset += nw;
-			len -= nw;
-		}
-	} else {
-		SignalError("java.io.IOException", "fd invalid"); 
+	fd = getFileFromSocket(this);
+
+	while (len > 0) {
+	  r = KSOCKWRITE(fd,
+			 &unhand_array(buf)->body[offset], (unsigned)len, &nw);
+	  if (r) {
+	    releaseFileToSocket(this);
+	    if (unhand(this)->native_fd < 0)
+	      {
+		SignalError("java.net.SocketException", "Socket was closed");
+	      }
+	    SignalError("java.net.SocketException", SYS_ERROR(r));
+	  }
+	  offset += nw;
+	  len -= nw;
 	}
+	releaseFileToSocket(this);
 }
 
 void
@@ -758,14 +849,17 @@
 gnu_java_net_PlainSocketImpl_waitForConnection(struct Hgnu_java_net_PlainSocketImpl* this)
 {
 	fd_set w;
-	int fd = (int)unhand(this)->native_fd;
+	int fd = getFileFromSocket(this);
 	int o, r;
 	struct timeval tv;
 	struct timeval *ptv = NULL;
 	
 	if (!unhand(this)->blocking) {
 		if (!unhand(this)->connecting)
-			return;
+		  {
+		    releaseFileToSocket(this);
+		    return;
+		  }
 		
 		FD_ZERO(&w);
 		FD_SET(fd, &w);
@@ -775,6 +869,8 @@
 	}
 
 	r = KSELECT(fd+1, NULL, &w, NULL, ptv, &o);
+	releaseFileToSocket(this);
+
 	if (r == EINTR) {
 		SignalError("java.io.InterruptedIOException", SYS_ERROR(r));
 	}
Index: kaffe/libraries/javalib/vmspecific/gnu/java/net/PlainSocketImpl.java
diff -u kaffe/libraries/javalib/vmspecific/gnu/java/net/PlainSocketImpl.java:1.1 kaffe/libraries/javalib/vmspecific/gnu/java/net/PlainSocketImpl.java:1.2
--- kaffe/libraries/javalib/vmspecific/gnu/java/net/PlainSocketImpl.java:1.1	Wed Oct 19 20:16:02 2005
+++ kaffe/libraries/javalib/vmspecific/gnu/java/net/PlainSocketImpl.java	Fri Nov 25 21:01:54 2005
@@ -38,6 +38,8 @@
 private boolean blocking;
 private boolean connecting;
 private int native_fd;
+private int fdUsed;
+
   /**
    * Indicates whether a channel initiated whatever operation
    * is being invoked on this socket.
@@ -85,7 +87,7 @@
 	socketAccept(s);
 }
 
-protected synchronized int available() throws IOException {
+protected int available() throws IOException {
 	return closed ? 0 : socketAvailable();
 }
 
@@ -93,7 +95,7 @@
 	socketBind(address, lport);
 }
 
-protected synchronized void close() throws IOException {
+protected void close() throws IOException {
 	if( !closed )
 		socketClose();
 	closed = true;
@@ -134,14 +136,14 @@
 	super.finalize();
 }
 
-protected synchronized InputStream getInputStream() throws IOException {
+protected InputStream getInputStream() throws IOException {
 	if (in == null) {
 		in = new SocketInputStream(this); 
 	}
 	return (in);
 }
 
-protected synchronized OutputStream getOutputStream() throws IOException {
+protected OutputStream getOutputStream() throws IOException {
 	if (out == null) {
 		out = new SocketOutputStream(this);
 	}
@@ -285,19 +287,19 @@
 
 public synchronized native void socketSetOption(int option, Object data) throws SocketException;
 public synchronized native int socketGetOption(int option) throws SocketException;
-protected synchronized native void socketAccept(SocketImpl sock);
-protected synchronized native int  socketAvailable();
-protected synchronized native void socketBind(InetAddress addr, int port);
-protected synchronized native void socketClose();
-protected synchronized native void socketConnect(InetAddress addr, int port, int timeout);
-protected synchronized native void socketCreate(boolean stream);
-protected synchronized native void socketListen(int count);
-protected synchronized native int socketRead(byte[] buf, int offset, int len) throws IOException;
-protected synchronized native void socketWrite(byte[] buf, int offset, int len) throws IOException;
+protected native void socketAccept(SocketImpl sock);
+protected native int  socketAvailable();
+protected native void socketBind(InetAddress addr, int port);
+protected native void socketClose();
+protected native void socketConnect(InetAddress addr, int port, int timeout);
+protected native void socketCreate(boolean stream);
+protected native void socketListen(int count);
+protected native int socketRead(byte[] buf, int offset, int len) throws IOException;
+protected native void socketWrite(byte[] buf, int offset, int len) throws IOException;
 
 // This function are principally for the NIO implementation of sockets.
-protected synchronized native void waitForConnection() throws IOException;
-protected synchronized native void setBlocking(boolean blocking);
+protected native void waitForConnection() throws IOException;
+protected native void setBlocking(boolean blocking);
 
 /* Taken from GNU Classpath. */
 




More information about the kaffe mailing list