Author: mturk
Date: Tue Jun 28 14:26:29 2011
New Revision: 1140637
URL: http://svn.apache.org/viewvc?rev=1140637&view=rev
Log:
Make Descriptor reference counted. Invoke close/free only when there are no
more references
Modified:
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Descriptor.java
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/LocalDescriptor.java
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketDescriptor.java
commons/sandbox/runtime/trunk/src/main/native/include/acr/descriptor.h
commons/sandbox/runtime/trunk/src/main/native/os/unix/inetsock.c
commons/sandbox/runtime/trunk/src/main/native/os/unix/usock.c
commons/sandbox/runtime/trunk/src/main/native/os/win32/pollset.c
commons/sandbox/runtime/trunk/src/main/native/shared/descriptor.c
Modified:
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Descriptor.java
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Descriptor.java?rev=1140637&r1=1140636&r2=1140637&view=diff
==============================================================================
---
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Descriptor.java
(original)
+++
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/io/Descriptor.java
Tue Jun 28 14:26:29 2011
@@ -37,10 +37,17 @@ import org.apache.commons.runtime.util.U
public abstract class Descriptor implements Device, Syncable
{
+ private static native void retain0(long fd);
+ private static native void release0(long fd);
+ private static native boolean unique0(long fd);
+
/** Operating system descriptor.
*/
- protected long fd;
-
+ protected long fd;
+ /**
+ * Closed flag.
+ */
+ protected volatile boolean closed;
/**
* Creates a new object.
*/
@@ -118,7 +125,7 @@ public abstract class Descriptor impleme
{
// true if both int is negative or zero
// Descriptor is always assured to be above the stderr (#3)
- if (fd == 0L)
+ if (closed || fd == 0L)
return false;
else
return true;
@@ -131,7 +138,7 @@ public abstract class Descriptor impleme
*/
public final boolean closed()
{
- if (fd == 0L)
+ if (closed || fd == 0L)
return true;
else
return false;
@@ -147,6 +154,50 @@ public abstract class Descriptor impleme
}
/**
+ * Increase retention.
+ * <p>
+ * This method increments the operating system descriptor's
+ * reference counter.
+ * </p>
+ * @return operating system descriptor with increased
+ * retention counter.
+ */
+ public final long retain()
+ {
+ if (fd != 0L)
+ retain0(fd);
+ return fd;
+ }
+
+ /**
+ * True if retention counter equals one.
+ * @param fd operating system descriptor.
+ */
+ public static boolean unique(final long fd)
+ throws InvalidDescriptorException
+ {
+ if (fd == 0L)
+ throw new InvalidDescriptorException();
+ return unique0(fd);
+ }
+
+ /**
+ * Decrease retention by decrementing the reference counter.
+ * User of this method will usually invalidate the operating
+ * system descriptor instead using {@code close()} method.
+ *
+ * @param fd operating system descriptor.
+ * @return {@code true} if the object can be released.
+ */
+ public static void release(final long fd)
+ throws InvalidDescriptorException
+ {
+ if (fd == 0L)
+ throw new InvalidDescriptorException();
+ release0(fd);
+ }
+
+ /**
* Compares this {@code Descriptor} to the specified object.
*
* @param other a {@code Descriptor}
@@ -171,6 +222,26 @@ public abstract class Descriptor impleme
}
/**
+ * Called by the garbage collector when the object is destroyed.
+ * The class will free internal resources allocated by the
+ * Operating system only if there are no additional references
+ * to this object.
+ * @see Object#finalize()
+ * @throws Throwable the {@code Exception} raised by this method.
+ */
+ @Override
+ protected final void finalize()
+ throws Throwable
+ {
+ try {
+ close();
+ }
+ finally {
+ fd = 0L;
+ }
+ }
+
+ /**
* Returns a string representation of the Descriptor.
* The returned string is hexadecimal representation of the underlying
* descriptor for the {@code pointer} type descriptors and integer for
Modified:
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/LocalDescriptor.java
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/LocalDescriptor.java?rev=1140637&r1=1140636&r2=1140637&view=diff
==============================================================================
---
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/LocalDescriptor.java
(original)
+++
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/LocalDescriptor.java
Tue Jun 28 14:26:29 2011
@@ -51,6 +51,7 @@ final class LocalDescriptor extends Desc
public LocalDescriptor(long fd)
{
this.fd = fd;
+ closed = false;
}
public void create(SocketType type)
@@ -63,6 +64,7 @@ final class LocalDescriptor extends Desc
throws IOException
{
this.fd = socket0(type.valueOf(), block);
+ closed = false;
}
public boolean isBlocking()
@@ -90,6 +92,7 @@ final class LocalDescriptor extends Desc
{
// Closing an empty socket is not an error
if (valid()) {
+ closed = true;
int rc = close0(fd);
fd = 0L;
if (rc != 0)
@@ -116,26 +119,4 @@ final class LocalDescriptor extends Desc
throw new ClosedDescriptorException();
}
- /**
- * Called by the garbage collector when the object is destroyed.
- * The class will free internal resources allocated by the Operating
system.
- * @see Object#finalize()
- * @throws Throwable the {@code Exception} raised by this method.
- */
- @Override
- protected final void finalize()
- throws Throwable
- {
- if (valid()) {
- try {
- close();
- } catch (Exception e) {
- // Ignore exceptions during close
- }
- finally {
- fd = 0L;
- }
- }
- }
-
}
Modified:
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketDescriptor.java
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketDescriptor.java?rev=1140637&r1=1140636&r2=1140637&view=diff
==============================================================================
---
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketDescriptor.java
(original)
+++
commons/sandbox/runtime/trunk/src/main/java/org/apache/commons/runtime/net/SocketDescriptor.java
Tue Jun 28 14:26:29 2011
@@ -48,12 +48,14 @@ final class SocketDescriptor extends Des
public SocketDescriptor(long fd)
{
this.fd = fd;
+ closed = false;
}
public void create(SocketType type)
throws IOException
{
this.fd = socket0(type.valueOf());
+ closed = false;
}
public boolean isBlocking()
@@ -81,6 +83,7 @@ final class SocketDescriptor extends Des
{
// Closing an empty socket is not an error
if (valid()) {
+ closed = true;
int rc = close0(fd);
fd = 0L;
if (rc != 0)
@@ -107,27 +110,4 @@ final class SocketDescriptor extends Des
throw new ClosedDescriptorException();
}
- /**
- * Called by the garbage collector when the object is destroyed.
- * The class will free internal resources allocated by the Operating
system.
- * @see Object#finalize()
- * @throws Throwable the {@code Exception} raised by this method.
- */
- @Override
- protected final void finalize()
- throws Throwable
- {
- if (valid()) {
- try {
- close();
- } catch (Exception e) {
- // Ignore exceptions during close
- }
- finally {
- fd = 0L;
- }
- }
- }
-
-
}
Modified: commons/sandbox/runtime/trunk/src/main/native/include/acr/descriptor.h
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/acr/descriptor.h?rev=1140637&r1=1140636&r2=1140637&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/include/acr/descriptor.h
(original)
+++ commons/sandbox/runtime/trunk/src/main/native/include/acr/descriptor.h Tue
Jun 28 14:26:29 2011
@@ -21,8 +21,8 @@
typedef struct acr_fd_t acr_fd_t;
struct acr_fd_t {
- int type; /**< Descriptor type */
- int size; /**< Allocated descriptor size */
+ int type; /**< Descriptor type */
+ volatile acr_atomic32_t refs; /**< Reference counter */
union {
jlong nh;
void *p;
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=1140637&r1=1140636&r2=1140637&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 Tue Jun 28
14:26:29 2011
@@ -21,21 +21,23 @@
#include "acr/unsafe.h"
#include "acr/port.h"
#include "arch_opts.h"
+#include "arch_sync.h"
#include <poll.h>
#include <sys/un.h>
ACR_NET_EXPORT(jint, SocketDescriptor, close0)(JNI_STDARGS, jlong fp)
{
+ int rc = 0;
acr_fd_t *fd = J2P(fp, acr_fd_t *);
if (fd == 0)
return ACR_EBADF;
- if (r_close(fd->u.s) == -1)
- return ACR_GET_OS_ERROR();
- else {
+ if (AcrAtomic32Dec(&fd->refs) == 0) {
+ if (r_close(fd->u.s) == -1)
+ rc = ACR_GET_OS_ERROR();
AcrFree(fd);
- return 0;
}
+ return rc;
}
ACR_NET_EXPORT(jint, SocketDescriptor, sendz0)(JNI_STDARGS, jlong fp)
Modified: commons/sandbox/runtime/trunk/src/main/native/os/unix/usock.c
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/unix/usock.c?rev=1140637&r1=1140636&r2=1140637&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/unix/usock.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/unix/usock.c Tue Jun 28
14:26:29 2011
@@ -24,6 +24,7 @@
#include "acr/unsafe.h"
#include "acr/port.h"
#include "arch_opts.h"
+#include "arch_sync.h"
#include <poll.h>
#include <sys/un.h>
@@ -34,16 +35,17 @@
ACR_NET_EXPORT(jint, LocalDescriptor, close0)(JNI_STDARGS, jlong fp)
{
+ int rc = 0;
acr_fd_t *fd = J2P(fp, acr_fd_t *);
if (fd == 0)
return ACR_EBADF;
- if (r_close(fd->u.s) == -1)
- return ACR_GET_OS_ERROR();
- else {
+ if (AcrAtomic32Dec(&fd->refs) == 0) {
+ if (r_close(fd->u.s) == -1)
+ rc = ACR_GET_OS_ERROR();
AcrFree(fd);
- return 0;
}
+ return rc;
}
ACR_NET_EXPORT(jint, LocalDescriptor, sendz0)(JNI_STDARGS, jlong fp)
@@ -107,7 +109,8 @@ ACR_NET_EXPORT(jlong, LocalDescriptor, s
r_close(sd);
return 0;
}
- sp->u.s = sd;
+ sp->refs = 1;
+ sp->u.s = sd;
return P2J(sp);
}
@@ -260,6 +263,7 @@ ACR_NET_EXPORT(jlong, LocalServerEndpoin
r_close(sd);
return 0;
}
- sp->u.s = sd;
+ sp->refs = 1;
+ sp->u.s = sd;
return P2J(sp);
}
Modified: commons/sandbox/runtime/trunk/src/main/native/os/win32/pollset.c
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/pollset.c?rev=1140637&r1=1140636&r2=1140637&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/pollset.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/pollset.c Tue Jun 28
14:26:29 2011
@@ -101,10 +101,8 @@ static int wwait(acr_pollset_t *ps)
LeaveCriticalSection(&ps->mutex);
ws = WaitForSingleObject(ps->wakeup, INFINITE);
EnterCriticalSection(&ps->mutex);
- if (AcrAtomic32Dec(&ps->waiters) <= 0) {
+ if (AcrAtomic32Dec(&ps->waiters) == 0)
ResetEvent(ps->wakeup);
- AcrAtomic32Set(&ps->waiters, 0);
- }
if (ws == WAIT_FAILED)
return GetLastError();
else
Modified: commons/sandbox/runtime/trunk/src/main/native/shared/descriptor.c
URL:
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/shared/descriptor.c?rev=1140637&r1=1140636&r2=1140637&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/shared/descriptor.c (original)
+++ commons/sandbox/runtime/trunk/src/main/native/shared/descriptor.c Tue Jun
28 14:26:29 2011
@@ -23,6 +23,7 @@
#include "acr/clazz.h"
#include "acr/memory.h"
#include "acr/unsafe.h"
+#include "arch_sync.h"
J_DECLARE_CLAZZ = {
INVALID_FIELD_OFFSET,
@@ -50,6 +51,24 @@ ACR_IO_EXPORT(void, Descriptor, init0)(J
_clazzn.u = 1;
}
+ACR_IO_EXPORT(void, Descriptor, retain0)(JNI_STDARGS, jlong fp)
+{
+ acr_fd_t *fd = J2P(fp, acr_fd_t *);
+ AcrAtomic32Inc(&fd->refs);
+}
+
+ACR_IO_EXPORT(void, Descriptor, release0)(JNI_STDARGS, jlong fp)
+{
+ acr_fd_t *fd = J2P(fp, acr_fd_t *);
+ AcrAtomic32Dec(&fd->refs);
+}
+
+ACR_IO_EXPORT(jboolean, Descriptor, unique0)(JNI_STDARGS, jlong fp)
+{
+ acr_fd_t *fd = J2P(fp, acr_fd_t *);
+ return AcrAtomic32Equ(&fd->refs, 1);
+}
+
acr_fd_t *
AcrGetDescriptorFp(JNI_STDARGS)
{