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  <[EMAIL PROTECTED]>
 
+       * 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  <[EMAIL PROTECTED]>
+
        * 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. */
 

_______________________________________________
kaffe mailing list
kaffe@kaffe.org
http://kaffe.org/cgi-bin/mailman/listinfo/kaffe

Reply via email to