Author: mturk
Date: Fri Jul 15 06:50:02 2011
New Revision: 1146978

URL: http://svn.apache.org/viewvc?rev=1146978&view=rev
Log:
Make sure we don't use fd if release destroyed descriptor

Modified:
    commons/sandbox/runtime/trunk/src/main/native/os/unix/inetsock.c
    commons/sandbox/runtime/trunk/src/main/native/os/unix/localsock.c
    commons/sandbox/runtime/trunk/src/main/native/os/win32/inetsock.c
    commons/sandbox/runtime/trunk/src/main/native/os/win32/localsock.c

Modified: commons/sandbox/runtime/trunk/src/main/native/os/unix/inetsock.c
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/unix/inetsock.c?rev=1146978&r1=1146977&r2=1146978&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/unix/inetsock.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/unix/inetsock.c Fri Jul 15 
06:50:02 2011
@@ -25,13 +25,13 @@
 #include <poll.h>
 #include <sys/un.h>
 
-ACR_INLINE(int) _retain_sd(acr_sd_t *sd)
+ACR_INLINE(int) retain_sd(acr_sd_t *sd)
 {
     AcrAtomic32Inc(&sd->refs);
     return sd->s;
 }
 
-ACR_INLINE(void) _release_sd(acr_sd_t *sd)
+ACR_INLINE(void) release_sd(acr_sd_t *sd)
 {
     if (AcrAtomic32Dec(&sd->refs) == 0) {
         /* Socket was closed while we were
@@ -40,7 +40,10 @@ ACR_INLINE(void) _release_sd(acr_sd_t *s
          * we have to do it here.
          */
         AcrFree(sd);
+        return 0;
     }
+    else
+        return 1;
 }
 
 ACR_NET_EXPORT(jlong, SocketDescriptor, socket0)(JNI_STDARGS, jint saf,
@@ -159,12 +162,12 @@ ACR_NET_EXPORT(jint, SocketDescriptor, s
         how = SHUT_WR;
     else
         how = SHUT_RDWR;
-    sd = _retain_sd(fd);
+    sd = retain_sd(fd);
     if (shutdown(fd->s, how) == -1)
         rc = ACR_GET_NETOS_ERROR();
-    _release_sd(fd);
     if (how != 1)
         fd->flags |= ACR_DT_HITEOF;
+    release_sd(fd);
     return rc;
 }
 

Modified: commons/sandbox/runtime/trunk/src/main/native/os/unix/localsock.c
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/unix/localsock.c?rev=1146978&r1=1146977&r2=1146978&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/unix/localsock.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/unix/localsock.c Fri Jul 
15 06:50:02 2011
@@ -34,13 +34,13 @@
 #define SOCKADDR_RELEASE(BA, SA) \
     AcrReleaseArrayCritical(env, (BA), (SA))
 
-ACR_INLINE(int) _retain_sd(acr_sd_t *sd)
+ACR_INLINE(int) retain_sd(acr_sd_t *sd)
 {
     AcrAtomic32Inc(&sd->refs);
     return sd->s;
 }
 
-ACR_INLINE(void) _release_sd(acr_sd_t *sd)
+ACR_INLINE(int) release_sd(acr_sd_t *sd)
 {
     if (AcrAtomic32Dec(&sd->refs) == 0) {
         /* Socket was closed while we were
@@ -49,7 +49,10 @@ ACR_INLINE(void) _release_sd(acr_sd_t *s
          * we have to do it here.
          */
         AcrFree(sd);
+        return 0;
     }
+    else
+        return 1;
 }
 
 ACR_NET_EXPORT(jint, LocalDescriptor, close0)(JNI_STDARGS, jlong fp)
@@ -85,12 +88,12 @@ ACR_NET_EXPORT(jint, LocalDescriptor, sh
         how = SHUT_WR;
     else
         how = SHUT_RDWR;
-    sd = _retain_sd(fd);
+    sd = retain_sd(fd);
     if (shutdown(sd, how) == -1)
         rc = ACR_GET_NETOS_ERROR();
     if (how != 1)
         fd->flags |= ACR_DT_HITEOF;
-    _release_sd(fd);
+    release_sd(fd);
     return rc;
 }
 
@@ -284,7 +287,7 @@ ACR_NET_EXPORT(jint, LocalEndpoint, conn
     acr_sockaddr_t *ca = SOCKADDR_CAST(cb);
     acr_sd_t *fd       = J2P(fp, acr_sd_t *);
 
-    sd = _retain_sd(fd);
+    sd = retain_sd(fd);
     if (timeout == 0)
         timeout = fd->timeout;
     if (timeout > 0 && (fd->flags & ACR_DT_NONBLOCK) == 0) {
@@ -321,7 +324,7 @@ ACR_NET_EXPORT(jint, LocalEndpoint, conn
         }
     }
 finally:
-    _release_sd(fd);
+    release_sd(fd);
     return rc;
 }
 
@@ -370,7 +373,7 @@ ACR_NET_EXPORT(jlong, LocalServerEndpoin
         flags |= SOCK_NONBLOCK;
 # endif
 #endif
-    ad = _retain_sd(fd);
+    ad = retain_sd(fd);
     memset(&aa, 0, sizeof(aa));
     aalen = ISIZEOF(struct sockaddr_un);
     do {
@@ -380,7 +383,10 @@ ACR_NET_EXPORT(jlong, LocalServerEndpoin
         sd = accept(ad,  (struct sockaddr *)&aa.sa, &aalen);
 #endif
     } while (sd == -1 && errno == EINTR);
-    _release_sd(fd);
+    if (release_sd(fd) == 0 && sd != -1) {
+        sd = -1;
+        errno = ENOTSOCK;
+    }
     if (sd == -1) {
         ACR_THROW_NET_ERRNO();
         return 0;

Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/inetsock.c
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/inetsock.c?rev=1146978&r1=1146977&r2=1146978&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/inetsock.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/inetsock.c Fri Jul 
15 06:50:02 2011
@@ -21,21 +21,32 @@
 #include "acr/unsafe.h"
 #include "acr/port.h"
 #include "arch_opts.h"
+#include "arch_sync.h"
 
-ACR_NET_EXPORT(jint, SocketDescriptor, close0)(JNI_STDARGS, jint fd)
+#define SOCKADDR_CAST(BA) \
+    (acr_sockaddr_t *)AcrGetArrayCritical(env, (BA))
+#define SOCKADDR_RELEASE(BA, SA) \
+    AcrReleaseArrayCritical(env, (BA), (SA))
+
+ACR_INLINE(SOCKET) retain_sd(acr_sd_t *sd)
 {
-    if (closesocket(I2SOCK(fd)) == -1)
-        return ACR_GET_OS_ERROR();
-    else
-        return 0;
+    AcrAtomic32Inc(&sd->refs);
+    return sd->s;
 }
 
-ACR_NET_EXPORT(jint, SocketDescriptor, sendz0)(JNI_STDARGS, jint fd)
+ACR_INLINE(int) release_sd(acr_sd_t *sd)
 {
-    if (send(I2SOCK(fd), (const char *)&fd, 0, 0) == -1)
-        return ACR_GET_OS_ERROR();
-    else
+    if (AcrAtomic32Dec(&sd->refs) == 0) {
+        /* Socket was closed while we were
+         * executing the native method.
+         * Since Socket didn't free the fd
+         * we have to do it here.
+         */
+        AcrFree(sd);
         return 0;
+    }
+    else
+        return 1;
 }
 
 ACR_NET_EXPORT(jboolean, SocketAddress, haveipv6)(JNI_STDARGS)
@@ -50,3 +61,145 @@ ACR_NET_EXPORT(jboolean, SocketAddress, 
     else
         return JNI_FALSE;
 }
+
+ACR_NET_EXPORT(jint, SocketDescriptor, close0)(JNI_STDARGS, jlong fp)
+{
+    int rc = 0;
+    SOCKET sd;
+    acr_sd_t *fd = J2P(fp, acr_sd_t *);
+
+    if (fd == 0)
+        return ACR_EBADF;
+    sd = fd->s;
+    if (fd->pob != 0) {
+        /* Close TransmitFile overlapped struct */
+        SAFE_CLOSE_HANDLE(fd->pob->hEvent);
+        AcrFree(fd->pob);
+        fd->pob = 0;
+    }
+    if (sd != INVALID_SOCKET) {
+        fd->s = INVALID_SOCKET;
+        if (closesocket(sd) == SOCKET_ERROR)
+            rc = ACR_GET_NETOS_ERROR();
+        fd->s = INVALID_SOCKET;
+    }
+    if (AcrAtomic32Dec(&fd->refs) == 0)
+        AcrFree(fd);
+    return rc;
+}
+
+ACR_NET_EXPORT(jint, SocketDescriptor, shutdown0)(JNI_STDARGS, jlong fp,
+                                                 jint how)
+{
+    int rc = 0;
+    SOCKET sd;
+    acr_sd_t *fd = J2P(fp, acr_sd_t *);
+
+    if (fd == 0)
+        return ACR_EBADF;
+    if (how == 0)
+        how = SD_RECEIVE;
+    else if (how == 1)
+        how = SD_SEND;
+    else
+        how = SD_BOTH;
+    sd = retain_sd(fd);
+    if (shutdown(fd->s, how) == SOCKET_ERROR)
+        rc = ACR_GET_NETOS_ERROR();
+    if (how != 1)
+        fd->flags |= ACR_DT_HITEOF;
+    release_sd(fd);
+    return rc;
+}
+
+ACR_NET_EXPORT(jint, SocketDescriptor, sendz0)(JNI_STDARGS, jlong fp)
+{
+    char dummy = 0;
+    acr_sd_t *fd = J2P(fp, acr_sd_t *);
+
+    if (send(fd->s, &dummy, 0, 0) == SOCKET_ERROR)
+        return ACR_GET_NETOS_ERROR();
+    else
+        return 0;
+}
+
+ACR_NET_EXPORT(jint, SocketDescriptor, block0)(JNI_STDARGS, jlong fp, jboolean 
on)
+{
+    int rc;
+    acr_sd_t *fd = J2P(fp, acr_sd_t *);
+
+    if (on == JNI_TRUE) {
+        if ((fd->flags & ACR_DT_NONBLOCK) != 0) {
+            int zero = 0;
+            if ((rc = AcrNonblock(fd->s, 0)) != 0)
+                return rc;
+            setsockopt(fd->s, SOL_SOCKET, SO_RCVTIMEO,
+                        (char *)&zero, (socklen_t)sizeof(zero));
+            setsockopt(fd->s, SOL_SOCKET, SO_SNDTIMEO,
+                        (char *)&zero, (socklen_t)sizeof(zero));
+            fd->timeout = -1;
+            fd->flags &= ~ACR_DT_NONBLOCK;
+        }
+    }
+    else {
+        if ((fd->flags & ACR_DT_NONBLOCK) == 0) {
+            if ((rc = AcrNonblock(fd->s, 1)) != 0)
+                return rc;
+            if (fd->timeout < 0)
+                fd->timeout = 0;
+            fd->flags |= ACR_DT_NONBLOCK;
+        }
+    }    
+    return 0;
+}
+
+ACR_NET_EXPORT(jboolean, SocketDescriptor, isBlocking0)(JNI_STDARGS, jlong fp)
+{
+    acr_sd_t *fd = J2P(fp, acr_sd_t *);
+
+    if ((fd->flags & ACR_DT_NONBLOCK) == 0)
+        return JNI_TRUE;
+    else
+        return JNI_FALSE;
+}
+
+ACR_NET_EXPORT(jint, SocketDescriptor, tmset0)(JNI_STDARGS, jlong fp, jint 
timeout)
+{
+    int rc = 0;
+    acr_sd_t *fd = J2P(fp, acr_sd_t *);
+
+    if (timeout == 0) {
+        if ((fd->flags & ACR_DT_NONBLOCK) == 0) {
+            if ((rc = AcrNonblock(fd->s, 1)) != 0)
+                return rc;
+            fd->flags |= ACR_DT_NONBLOCK;
+        }
+    }
+    else if (timeout > 0) {
+        if ((fd->flags & ACR_DT_NONBLOCK) == 0) {
+            if ((rc = AcrNonblock(fd->s, 1)) != 0)
+                return rc;
+            fd->flags |= ACR_DT_NONBLOCK;
+        }
+        if (fd->timeout != timeout) {
+            setsockopt(fd->s, SOL_SOCKET, SO_RCVTIMEO,
+                      (char *)&timeout, (socklen_t)sizeof(timeout));
+            setsockopt(fd->s, SOL_SOCKET, SO_SNDTIMEO,
+                      (char *)&timeout, (socklen_t)sizeof(timeout));
+        }
+    }
+    else if (timeout < 0) {
+        int zero = 0;
+        if ((fd->flags & ACR_DT_NONBLOCK) != 0) {
+            if ((rc = AcrNonblock(fd->s, 0)) != 0)
+                return rc;
+            fd->flags &= ~ACR_DT_NONBLOCK;
+        }
+        setsockopt(fd->s, SOL_SOCKET, SO_RCVTIMEO,
+                    (char *)&zero, (socklen_t)sizeof(zero));
+        setsockopt(fd->s, SOL_SOCKET, SO_SNDTIMEO,
+                    (char *)&zero, (socklen_t)sizeof(zero));
+    }
+    fd->timeout = timeout;
+    return 0;
+}

Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/localsock.c
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/localsock.c?rev=1146978&r1=1146977&r2=1146978&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/localsock.c 
(original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/localsock.c Fri Jul 
15 06:50:02 2011
@@ -41,13 +41,13 @@
 #define SOCKADDR_RELEASE(BA, SA) \
     AcrReleaseArrayCritical(env, (BA), (SA))
 
-ACR_INLINE(SOCKET) _retain_sd(acr_sd_t *sd)
+ACR_INLINE(SOCKET) retain_sd(acr_sd_t *sd)
 {
     AcrAtomic32Inc(&sd->refs);
     return sd->s;
 }
 
-ACR_INLINE(void) _release_sd(acr_sd_t *sd)
+ACR_INLINE(int) release_sd(acr_sd_t *sd)
 {
     if (AcrAtomic32Dec(&sd->refs) == 0) {
         /* Socket was closed while we were
@@ -56,7 +56,10 @@ ACR_INLINE(void) _release_sd(acr_sd_t *s
          * we have to do it here.
          */
         AcrFree(sd);
+        return 0;
     }
+    else
+        return 1;
 }
 
 ACR_NET_EXPORT(jint, LocalDescriptor, close0)(JNI_STDARGS, jlong fp)
@@ -76,7 +79,7 @@ ACR_NET_EXPORT(jint, LocalDescriptor, cl
     }
     if (sd != INVALID_SOCKET) {
         fd->s = INVALID_SOCKET;
-        if (fd->socketfname) {
+        if (fd->socketfname != 0) {
             DeleteFileW(fd->socketfname);
             AcrFree(fd->socketfname);
             fd->socketfname = 0;
@@ -105,10 +108,12 @@ ACR_NET_EXPORT(jint, LocalDescriptor, sh
         how = SD_SEND;
     else
         how = SD_BOTH;
-    sd = _retain_sd(fd);
+    sd = retain_sd(fd);
     if (shutdown(fd->s, how) == SOCKET_ERROR)
         rc = ACR_GET_NETOS_ERROR();
-    _release_sd(fd);
+    if (how != 1)
+        fd->flags |= ACR_DT_HITEOF;
+    release_sd(fd);
     return rc;
 }
 
@@ -295,7 +300,7 @@ ACR_NET_EXPORT(jint, LocalEndpoint, conn
     sa.sin_addr.s_addr = inet_addr("127.0.0.1");
     if (timeout == 0)
         timeout = fd->timeout;
-    sd = _retain_sd(fd);
+    sd = retain_sd(fd);
     if (timeout > 0 && (fd->flags & ACR_DT_NONBLOCK) == 0) {
         /* Turn the socket to non-blocking mode
          * for the duration of the connect call.
@@ -324,7 +329,7 @@ ACR_NET_EXPORT(jint, LocalEndpoint, conn
         }
     }
 finally:
-    _release_sd(fd);
+    release_sd(fd);
     return rc;
 }
 
@@ -418,9 +423,13 @@ ACR_NET_EXPORT(jlong, LocalServerEndpoin
     acr_sd_t *fd  = J2P(fp, acr_sd_t *);
 
     memset(&sa, 0, sizeof(sa));
-    ad = _retain_sd(fd);
+    ad = retain_sd(fd);
     sd = accept(ad,  0, 0);
-    _release_sd(fd);
+    if (release_sd(fd) == 0 && sd != INVALID_SOCKET) {
+        /* XXX: Can this happen ? */    
+        sd = INVALID_SOCKET;
+        WSASetLastError(WSAENOTSOCK);
+    }
     if (sd == INVALID_SOCKET) {
         ACR_THROW_NET_ERRNO();
         return 0;


Reply via email to