|
From: <cr...@us...> - 2008-09-30 12:00:29
|
Revision: 4592
http://jnode.svn.sourceforge.net/jnode/?rev=4592&view=rev
Author: crawley
Date: 2008-09-30 12:00:11 +0000 (Tue, 30 Sep 2008)
Log Message:
-----------
This checkin adds some infrastructure for 'status links' and
corrects a mis-named public method in the Isolate class. I've renamed
VmDataLink / DataLinkImpl to VmLink / LinkImpl because they also need
to support status links.
Modified Paths:
--------------
trunk/core/src/classpath/ext/javax/isolate/Isolate.java
trunk/core/src/classpath/ext/javax/isolate/Link.java
trunk/core/src/core/org/jnode/vm/isolate/VmIsolate.java
trunk/core/src/core/org/jnode/vm/isolate/link/LinkLinkMessage.java
trunk/core/src/core/org/jnode/vm/isolate/link/LinkMessageFactory.java
Added Paths:
-----------
trunk/core/src/core/org/jnode/vm/isolate/link/LinkImpl.java
trunk/core/src/core/org/jnode/vm/isolate/link/VmLink.java
Removed Paths:
-------------
trunk/core/src/core/org/jnode/vm/isolate/link/DataLinkImpl.java
trunk/core/src/core/org/jnode/vm/isolate/link/VmDataLink.java
Modified: trunk/core/src/classpath/ext/javax/isolate/Isolate.java
===================================================================
--- trunk/core/src/classpath/ext/javax/isolate/Isolate.java 2008-09-30 11:54:14 UTC (rev 4591)
+++ trunk/core/src/classpath/ext/javax/isolate/Isolate.java 2008-09-30 12:00:11 UTC (rev 4592)
@@ -147,14 +147,13 @@
/**
* Gets a new Link associated with this Isolate from which the current
- * isolate can receive events.
+ * isolate can receive status link messages.
*
* @return
* @throws ClosedLinkException
*/
- public Link newEventLink() throws ClosedLinkException {
- // TODO implement me
- return null;
+ public Link newStatusLink() throws ClosedLinkException {
+ return impl.newStatusLink(currentIsolate().impl);
}
/**
Modified: trunk/core/src/classpath/ext/javax/isolate/Link.java
===================================================================
--- trunk/core/src/classpath/ext/javax/isolate/Link.java 2008-09-30 11:54:14 UTC (rev 4591)
+++ trunk/core/src/classpath/ext/javax/isolate/Link.java 2008-09-30 12:00:11 UTC (rev 4592)
@@ -24,7 +24,7 @@
import java.io.IOException;
import java.io.InterruptedIOException;
-import org.jnode.vm.isolate.link.VmDataLink;
+import org.jnode.vm.isolate.link.VmLink;
/**
* @author Ewout Prangsma (ep...@us...)
@@ -228,6 +228,6 @@
*/
public static Link newLink(Isolate sender, Isolate receiver)
throws ClosedLinkException {
- return VmDataLink.newLink(sender.getImpl(), receiver.getImpl());
+ return VmLink.newLink(sender.getImpl(), receiver.getImpl());
}
}
Modified: trunk/core/src/core/org/jnode/vm/isolate/VmIsolate.java
===================================================================
--- trunk/core/src/core/org/jnode/vm/isolate/VmIsolate.java 2008-09-30 11:54:14 UTC (rev 4591)
+++ trunk/core/src/core/org/jnode/vm/isolate/VmIsolate.java 2008-09-30 12:00:11 UTC (rev 4592)
@@ -54,7 +54,7 @@
import org.jnode.vm.annotation.SharedStatics;
import org.jnode.vm.classmgr.VmIsolatedStatics;
import org.jnode.vm.classmgr.VmType;
-import org.jnode.vm.isolate.link.VmDataLink;
+import org.jnode.vm.isolate.link.VmLink;
/**
* VM specific implementation of the Isolate class.
@@ -122,9 +122,14 @@
/**
* Links passed to the start of this isolate
*/
- private VmDataLink[] dataLinks;
+ private VmLink[] dataLinks;
/**
+ * Status links created by newStatusLink()
+ */
+ private LinkedList<VmLink> statusLinks = new LinkedList<VmLink>();
+
+ /**
* The isolate-specific default IO context
*/
private final IOContext vmIoContext = new VmIOContext();
@@ -344,7 +349,7 @@
public final void exit(Isolate isolate, int status) {
testIsolate(isolate);
//todo handle demon threads
- if(threadGroup.activeCount() > 0 || threadGroup.activeGroupCount() > 0)
+ if (threadGroup.activeCount() > 0 || threadGroup.activeGroupCount() > 0)
return;
try {
@@ -352,7 +357,7 @@
} catch (Throwable t) {
t.printStackTrace();
}
- state = State.EXITED;
+ changeState(State.EXITED);
StaticData.isolates.remove(this);
}
@@ -375,7 +380,7 @@
} catch (Throwable t) {
t.printStackTrace();
}
- this.state = State.TERMINATED;
+ changeState(State.TERMINATED);
StaticData.isolates.remove(this);
}
@@ -428,14 +433,14 @@
* Gets the links passed to the start of the current isolate.
*/
public static Link[] getLinks() {
- final VmDataLink[] vmLinks = currentIsolate().dataLinks;
+ final VmLink[] vmLinks = currentIsolate().dataLinks;
if ((vmLinks == null) || (vmLinks.length == 0)) {
return new Link[0];
} else {
Link[] links = new Link[vmLinks.length];
int i = 0;
- for (VmDataLink vmLink : vmLinks) {
+ for (VmLink vmLink : vmLinks) {
links[i++] = vmLink.asLink();
}
return links;
@@ -449,7 +454,7 @@
* @throws IsolateStartupException
*/
@PrivilegedActionPragma
- public final void start(Isolate isolate, Link[] links)
+ public synchronized final void start(Isolate isolate, Link[] links)
throws IsolateStartupException {
testIsolate(isolate);
// The creator of this isolate must be the same as the current isolate
@@ -461,10 +466,9 @@
synchronized (this) {
// The state must be CREATED
if (state != State.CREATED) {
- throw new IllegalStateException(
- "Isolate has already been started");
+ throw new IllegalStateException("Isolate has already been started");
}
- this.state = State.STARTING;
+ changeState(State.STARTING);
}
// Save starter
@@ -473,13 +477,13 @@
// Save links
this.dataLinks = null;
if (links != null) {
- VmDataLink[] vmLinks = new VmDataLink[links.length];
+ VmLink[] vmLinks = new VmLink[links.length];
int i = 0;
for (Link link : links) {
if (!link.isOpen()) {
throw new IsolateStartupException("Link is closed");
}
- vmLinks[i] = VmDataLink.fromLink(link);
+ vmLinks[i] = VmLink.fromLink(link);
}
this.dataLinks = vmLinks;
}
@@ -514,7 +518,7 @@
piManager, stdout, stderr, stdin);
// Update the state of this isolate.
- this.state = State.STARTED;
+ changeState(State.STARTED);
// Start the main thread.
mainThread.start();
@@ -750,4 +754,35 @@
BootableHashMap getIsolateLocalMap() {
return isolateLocalMap;
}
+
+ /**
+ * Create and return a new status link for this isolate and the supplied
+ * receiver isolate.
+ * @param receiver the receiver for the link.
+ * @return the link.
+ */
+ public synchronized Link newStatusLink(VmIsolate receiver) {
+ Link link = VmLink.newLink(this, receiver);
+ VmLink vmLink = VmLink.fromLink(link);
+ statusLinks.add(vmLink);
+ if (state == State.TERMINATED) {
+ // The spec says that we should immediately send a link message
+ // if the isolate is already 'EXITED'.
+ sendStatus(vmLink, state);
+ }
+ return link;
+ }
+
+ private synchronized void changeState(State newState) {
+ if (state != newState) {
+ this.state = newState;
+ for (VmLink link : statusLinks) {
+ sendStatus(link, this.state);
+ }
+ }
+ }
+
+ private void sendStatus(VmLink link, State state) {
+ // TODO implement.
+ }
}
Deleted: trunk/core/src/core/org/jnode/vm/isolate/link/DataLinkImpl.java
===================================================================
--- trunk/core/src/core/org/jnode/vm/isolate/link/DataLinkImpl.java 2008-09-30 11:54:14 UTC (rev 4591)
+++ trunk/core/src/core/org/jnode/vm/isolate/link/DataLinkImpl.java 2008-09-30 12:00:11 UTC (rev 4592)
@@ -1,98 +0,0 @@
-/*
- * $Id$
- */
-package org.jnode.vm.isolate.link;
-
-import java.io.IOException;
-import java.io.InterruptedIOException;
-
-import javax.isolate.ClosedLinkException;
-import javax.isolate.Isolate;
-import javax.isolate.Link;
-import javax.isolate.LinkMessage;
-
-final class DataLinkImpl extends Link {
-
- private final VmDataLink vmLink;
-
- /**
- * Constructor
- *
- * @param vmLink
- */
- DataLinkImpl(VmDataLink vmLink) {
- this.vmLink = vmLink;
- }
-
- final VmDataLink getImpl() {
- return vmLink;
- }
-
- /**
- * @see javax.isolate.Link#close()
- */
- @Override
- public void close() {
- vmLink.close();
- }
-
- /**
- * @see javax.isolate.Link#Equals(java.lang.Object)
- */
- @Override
- public boolean equals(Object other) {
- if (other instanceof DataLinkImpl) {
- return (((DataLinkImpl) other).vmLink == this.vmLink);
- }
- return false;
- }
-
- /**
- * @see javax.isolate.Link#getReceiver()
- */
- @Override
- public Isolate getReceiver() {
- return vmLink.getReceiver().getIsolate();
- }
-
- /**
- * @see javax.isolate.Link#getSender()
- */
- @Override
- public Isolate getSender() {
- return vmLink.getSender().getIsolate();
- }
-
- /**
- * @see javax.isolate.Link#isOpen()
- */
- @Override
- public boolean isOpen() {
- return vmLink.isOpen();
- }
-
- /**
- * @see javax.isolate.Link#receive()
- */
- @Override
- public LinkMessage receive()
- throws ClosedLinkException, IllegalStateException, InterruptedIOException, IOException {
- return vmLink.receive();
- }
-
- /**
- * @see javax.isolate.Link#send(javax.isolate.LinkMessage)
- */
- @Override
- public void send(LinkMessage message) throws ClosedLinkException, InterruptedIOException, IOException {
- vmLink.send(message);
- }
-
- /**
- * @see javax.isolate.Link#toString()
- */
- @Override
- public String toString() {
- return vmLink.toString();
- }
-}
Added: trunk/core/src/core/org/jnode/vm/isolate/link/LinkImpl.java
===================================================================
--- trunk/core/src/core/org/jnode/vm/isolate/link/LinkImpl.java (rev 0)
+++ trunk/core/src/core/org/jnode/vm/isolate/link/LinkImpl.java 2008-09-30 12:00:11 UTC (rev 4592)
@@ -0,0 +1,98 @@
+/*
+ * $Id: DataLinkImpl.java 4552 2008-09-11 11:38:42Z crawley $
+ */
+package org.jnode.vm.isolate.link;
+
+import java.io.IOException;
+import java.io.InterruptedIOException;
+
+import javax.isolate.ClosedLinkException;
+import javax.isolate.Isolate;
+import javax.isolate.Link;
+import javax.isolate.LinkMessage;
+
+final class LinkImpl extends Link {
+
+ private final VmLink vmLink;
+
+ /**
+ * Constructor
+ *
+ * @param vmLink
+ */
+ LinkImpl(VmLink vmLink) {
+ this.vmLink = vmLink;
+ }
+
+ final VmLink getImpl() {
+ return vmLink;
+ }
+
+ /**
+ * @see javax.isolate.Link#close()
+ */
+ @Override
+ public void close() {
+ vmLink.close();
+ }
+
+ /**
+ * @see javax.isolate.Link#Equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object other) {
+ if (other instanceof LinkImpl) {
+ return (((LinkImpl) other).vmLink == this.vmLink);
+ }
+ return false;
+ }
+
+ /**
+ * @see javax.isolate.Link#getReceiver()
+ */
+ @Override
+ public Isolate getReceiver() {
+ return vmLink.getReceiver().getIsolate();
+ }
+
+ /**
+ * @see javax.isolate.Link#getSender()
+ */
+ @Override
+ public Isolate getSender() {
+ return vmLink.getSender().getIsolate();
+ }
+
+ /**
+ * @see javax.isolate.Link#isOpen()
+ */
+ @Override
+ public boolean isOpen() {
+ return vmLink.isOpen();
+ }
+
+ /**
+ * @see javax.isolate.Link#receive()
+ */
+ @Override
+ public LinkMessage receive()
+ throws ClosedLinkException, IllegalStateException, InterruptedIOException, IOException {
+ return vmLink.receive();
+ }
+
+ /**
+ * @see javax.isolate.Link#send(javax.isolate.LinkMessage)
+ */
+ @Override
+ public void send(LinkMessage message) throws ClosedLinkException, InterruptedIOException, IOException {
+ vmLink.send(message);
+ }
+
+ /**
+ * @see javax.isolate.Link#toString()
+ */
+ @Override
+ public String toString() {
+ return vmLink.toString();
+ }
+}
Modified: trunk/core/src/core/org/jnode/vm/isolate/link/LinkLinkMessage.java
===================================================================
--- trunk/core/src/core/org/jnode/vm/isolate/link/LinkLinkMessage.java 2008-09-30 11:54:14 UTC (rev 4591)
+++ trunk/core/src/core/org/jnode/vm/isolate/link/LinkLinkMessage.java 2008-09-30 12:00:11 UTC (rev 4592)
@@ -8,14 +8,14 @@
final class LinkLinkMessage extends LinkMessageImpl {
- private final VmDataLink value;
+ private final VmLink value;
/**
* Message constructor
*
* @param value
*/
- LinkLinkMessage(VmDataLink link) {
+ LinkLinkMessage(VmLink link) {
this.value = link;
}
Modified: trunk/core/src/core/org/jnode/vm/isolate/link/LinkMessageFactory.java
===================================================================
--- trunk/core/src/core/org/jnode/vm/isolate/link/LinkMessageFactory.java 2008-09-30 11:54:14 UTC (rev 4591)
+++ trunk/core/src/core/org/jnode/vm/isolate/link/LinkMessageFactory.java 2008-09-30 12:00:11 UTC (rev 4592)
@@ -51,7 +51,7 @@
* @return
*/
public static LinkMessage newLinkMessage(Link link) {
- return new LinkLinkMessage(((DataLinkImpl) link).getImpl());
+ return new LinkLinkMessage(((LinkImpl) link).getImpl());
}
/**
Deleted: trunk/core/src/core/org/jnode/vm/isolate/link/VmDataLink.java
===================================================================
--- trunk/core/src/core/org/jnode/vm/isolate/link/VmDataLink.java 2008-09-30 11:54:14 UTC (rev 4591)
+++ trunk/core/src/core/org/jnode/vm/isolate/link/VmDataLink.java 2008-09-30 12:00:11 UTC (rev 4592)
@@ -1,272 +0,0 @@
-/*
- * $Id$
- */
-package org.jnode.vm.isolate.link;
-
-import java.io.IOException;
-import java.io.InterruptedIOException;
-import java.util.LinkedList;
-import java.util.Queue;
-
-import javax.isolate.ClosedLinkException;
-import javax.isolate.Link;
-import javax.isolate.LinkMessage;
-
-import org.jnode.vm.isolate.VmIsolate;
-import org.jnode.vm.isolate.VmIsolateLocal;
-
-/**
- * Shared implementation of javax.isolate.Link
- *
- * @author Ewout Prangsma (ep...@us...)
- */
-public final class VmDataLink {
-
- private final VmIsolateLocal<DataLinkImpl> linkHolder = new VmIsolateLocal<DataLinkImpl>();
-
- private final Queue<LinkMessageImpl> messages = new LinkedList<LinkMessageImpl>();
-
- private boolean closed = false;
-
- private VmIsolate sender;
-
- private VmIsolate receiver;
-
- /**
- * Create a new data link between the given isolates.
- *
- * @param sender
- * @param receiver
- * @return
- */
- public static Link newLink(VmIsolate sender, VmIsolate receiver) {
- if (sender == receiver) {
- throw new IllegalArgumentException("sender == receiver");
- }
- VmDataLink vmLink = new VmDataLink(sender, receiver);
- return vmLink.asLink();
- }
-
- public static VmDataLink fromLink(Link link) {
- return ((DataLinkImpl) link).getImpl();
- }
-
- /**
- * @param sender
- * @param receiver
- */
- VmDataLink(VmIsolate sender, VmIsolate receiver) {
- this.sender = sender;
- this.receiver = receiver;
- }
-
- /**
- * Gets this shared link as Link instance.
- *
- * @return
- */
- public final Link asLink() {
- final DataLinkImpl link = linkHolder.get();
- if (link == null) {
- linkHolder.set(new DataLinkImpl(this));
- return linkHolder.get();
- } else {
- return link;
- }
- }
-
- /**
- * Close this link.
- */
- final void close() {
- if (!this.closed) {
- final VmIsolate current = VmIsolate.currentIsolate();
- if ((current != receiver) && (current != sender)) {
- throw new IllegalStateException(
- "Only sender or receiver can close this link");
- }
- this.closed = true;
- synchronized (this) {
- notifyAll();
- }
- }
- }
-
- /**
- * Is this link currently open.
- *
- * @return
- */
- final boolean isOpen() {
- return !closed;
- }
-
- /**
- * @return the receiver
- */
- final VmIsolate getReceiver() {
- return receiver;
- }
-
- /**
- * @return the sender
- */
- final VmIsolate getSender() {
- return sender;
- }
-
- /**
- * Receives a copy of a message sent on this Link.
- * <p/>
- * The current thread will block in this method until a sender is available.
- * When the sender and receiver rendezvous, the message will then be
- * transferred. If multiple threads invoke this method on the same object,
- * only one thread will receive any message at rendezvous and the other
- * threads will contend for subsequent access to the rendezvous point. A
- * normal return indicates that the message was received successfully. If an
- * exception occured on the sender side, no rendezvous will occur, and no
- * object will be transferred; the receiver will wait for the next
- * successful send. If an exception occurs on the receive, the sender will
- * see a successful transfer.
- * <p/>
- * This method never returns null.
- * <p/>
- * If the sending isolate becomes terminated after this method is invoked
- * but before it returns, the link will be closed, a ClosedLinkException
- * will be thrown, any subsequent attempts to use receive() will result in a
- * ClosedLinkException, and any Isolate objects corresponding to the receive
- * side of the link will reflect a terminated state.
- * <p/>
- * If invoked on a closed Link, this method will throw a
- * ClosedLinkException.
- * <p/>
- * If close() is invoked on the link while a thread is blocked in receive(),
- * receive() will throw a ClosedLinkException. No message will have been
- * transferred in that case.
- * <p/>
- * If Thread.interrupt() is invoked on a thread that has not yet completed
- * an invocation of this method, the results are undefined. An
- * InterruptedIOException may or may not be thrown; if not, control will
- * return from the method with a valid LinkMessage object. However, even if
- * InterruptedIOException is thrown, rendezvous and data transfer from the
- * sending isolate may have occurred. In particular, undetected message loss
- * between sender and receiver may occur.
- * <p/>
- * If a failure occurs due to the object being transferred between isolates
- * an IOException may be thrown in the receiver. For example, if a message
- * containing a large buffer is sent and the receiver has insufficient heap
- * memory for the buffer or if construction of a link in the receiver
- * isolate fails, an IOException will be thrown. The sender will see a
- * successful transfer in these cases.
- * <p/>
- * If the current isolate is not a receiver on this Link an
- * IllegalStateException will be thrown. The receiver will not rendezvous
- * with a sender in this case.
- *
- * @return
- */
- final LinkMessage receive() throws ClosedLinkException,
- IllegalStateException, InterruptedIOException, IOException {
- if (VmIsolate.currentIsolate() != receiver) {
- // Current isolate is not the receiver
- throw new IllegalStateException();
- }
- if (this.closed) {
- throw new ClosedLinkException();
- }
- final LinkMessageImpl message;
- synchronized (this) {
- while (messages.isEmpty()) {
- if (this.closed) {
- throw new ClosedLinkException();
- }
- try {
- wait();
- } catch (InterruptedException ex) {
- throw new InterruptedIOException();
- }
- }
- message = messages.poll();
- }
- message.notifyReceived();
- return message.CloneMessage();
- }
-
- /**
- * Sends the given message on this Link.
- * <p/>
- * The current thread will block in this method until a receiver is
- * available. When the sender and receiver rendezvous, the message will then
- * be transferred. A normal return indicates that the message was
- * transferred. If an exception occurs on the sender side, no rendezvous
- * will occur and no object will be transferred. But if an exception occurs
- * on the receive(), the sender will see a successful transfer.
- * <p/>
- * If the receiving isolate becomes terminated after this method is invoked
- * but before it returns, the link will be closed, a ClosedLinkException
- * will be thrown, any subsequent attempts to use send() will result in a
- * ClosedLinkException, and any Isolate objects corresponding to the receive
- * side of the link will reflect a terminated state.
- * <p/>
- * If invoked on a closed link, this method will throw a
- * ClosedLinkException.
- * <p/>
- * If close() is invoked on this Link while a thread is blocked in send(),
- * send() will throw a ClosedLinkException. No message will have been
- * transferred in that case.
- * <p/>
- * If Thread.interrupt() is invoked on a thread that has not yet completed
- * an invocation of this method, the results are undefined. An
- * InterruptedIOException may or may not be thrown; however, even if not,
- * control will return from the method. Rendezvous and data transfer to the
- * receiving isolate may or may not have occurred. In particular, undetected
- * message loss between sender and receiver may occur.
- * <p/>
- * If a failure occurs during the transfer an IOException may be thrown in
- * the sender and the object will not be sent. A transfer may succeed from
- * the sender's point of view, but cause an independent IOException in the
- * receiver. For example, if a message containing a large buffer is sent and
- * the receiver has insufficient heap memory for the buffer or if
- * construction of a link in the receiver isolate fails, an IOException will
- * be thrown in the receiver after the transfer completes.
- * <p/>
- * A ClosedLinkException will be thrown if the given LinkMessage contains a
- * closed Link, Socket, or ServerSocket. No object will be transferred in
- * this case.
- * <p/>
- * If the current isolate is not a sender on this Link, an
- * UnsupportedOperationException will be thrown. No object will be sent in
- * this case.
- *
- * @param message
- * @throws ClosedLinkException
- * @throws InterruptedIOException
- * @throws IOException
- */
- final void send(LinkMessage message) throws ClosedLinkException,
- InterruptedIOException, IOException {
- if (VmIsolate.currentIsolate() != sender) {
- // Current isolate is not a sender
- throw new UnsupportedOperationException();
- }
- if (this.closed) {
- throw new ClosedLinkException();
- }
- final LinkMessageImpl messageImpl = (LinkMessageImpl) message;
- synchronized (this) {
- if (this.closed) {
- throw new ClosedLinkException();
- }
- // Send message
- messages.add(messageImpl);
- notifyAll();
- }
-
- // Wait for the message to be picked up by the receiver
- try {
- messageImpl.waitUntilReceived();
- } catch (InterruptedException ex) {
- throw new InterruptedIOException();
- }
- }
-}
Added: trunk/core/src/core/org/jnode/vm/isolate/link/VmLink.java
===================================================================
--- trunk/core/src/core/org/jnode/vm/isolate/link/VmLink.java (rev 0)
+++ trunk/core/src/core/org/jnode/vm/isolate/link/VmLink.java 2008-09-30 12:00:11 UTC (rev 4592)
@@ -0,0 +1,295 @@
+/*
+ * $Id: VmDataLink.java 4552 2008-09-11 11:38:42Z crawley $
+ */
+package org.jnode.vm.isolate.link;
+
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.util.LinkedList;
+import java.util.Queue;
+
+import javax.isolate.ClosedLinkException;
+import javax.isolate.Link;
+import javax.isolate.LinkMessage;
+
+import org.jnode.vm.isolate.VmIsolate;
+import org.jnode.vm.isolate.VmIsolateLocal;
+
+/**
+ * Shared implementation of javax.isolate.Link
+ *
+ * @author Ewout Prangsma (ep...@us...)
+ */
+public final class VmLink {
+
+ private final VmIsolateLocal<LinkImpl> linkHolder = new VmIsolateLocal<LinkImpl>();
+
+ private final Queue<LinkMessageImpl> messages = new LinkedList<LinkMessageImpl>();
+
+ private boolean closed = false;
+
+ private VmIsolate sender;
+
+ private VmIsolate receiver;
+
+ /**
+ * Create a new data link between the given isolates.
+ *
+ * @param sender
+ * @param receiver
+ * @return
+ */
+ public static Link newLink(VmIsolate sender, VmIsolate receiver) {
+ if (sender == receiver) {
+ throw new IllegalArgumentException("sender == receiver");
+ }
+ VmLink vmLink = new VmLink(sender, receiver);
+ return vmLink.asLink();
+ }
+
+ public static VmLink fromLink(Link link) {
+ return ((LinkImpl) link).getImpl();
+ }
+
+ /**
+ * @param sender
+ * @param receiver
+ */
+ VmLink(VmIsolate sender, VmIsolate receiver) {
+ this.sender = sender;
+ this.receiver = receiver;
+ }
+
+ /**
+ * Gets this shared link as Link instance.
+ *
+ * @return
+ */
+ public final Link asLink() {
+ final LinkImpl link = linkHolder.get();
+ if (link == null) {
+ linkHolder.set(new LinkImpl(this));
+ return linkHolder.get();
+ } else {
+ return link;
+ }
+ }
+
+ /**
+ * Close this link.
+ */
+ final void close() {
+ if (!this.closed) {
+ final VmIsolate current = VmIsolate.currentIsolate();
+ if ((current != receiver) && (current != sender)) {
+ throw new IllegalStateException(
+ "Only sender or receiver can close this link");
+ }
+ this.closed = true;
+ synchronized (this) {
+ notifyAll();
+ }
+ }
+ }
+
+ /**
+ * Is this link currently open.
+ *
+ * @return
+ */
+ final boolean isOpen() {
+ return !closed;
+ }
+
+ /**
+ * @return the receiver
+ */
+ final VmIsolate getReceiver() {
+ return receiver;
+ }
+
+ /**
+ * @return the sender
+ */
+ final VmIsolate getSender() {
+ return sender;
+ }
+
+ /**
+ * Receives a copy of a message sent on this Link.
+ * <p/>
+ * The current thread will block in this method until a sender is available.
+ * When the sender and receiver rendezvous, the message will then be
+ * transferred. If multiple threads invoke this method on the same object,
+ * only one thread will receive any message at rendezvous and the other
+ * threads will contend for subsequent access to the rendezvous point. A
+ * normal return indicates that the message was received successfully. If an
+ * exception occured on the sender side, no rendezvous will occur, and no
+ * object will be transferred; the receiver will wait for the next
+ * successful send. If an exception occurs on the receive, the sender will
+ * see a successful transfer.
+ * <p/>
+ * This method never returns null.
+ * <p/>
+ * If the sending isolate becomes terminated after this method is invoked
+ * but before it returns, the link will be closed, a ClosedLinkException
+ * will be thrown, any subsequent attempts to use receive() will result in a
+ * ClosedLinkException, and any Isolate objects corresponding to the receive
+ * side of the link will reflect a terminated state.
+ * <p/>
+ * If invoked on a closed Link, this method will throw a
+ * ClosedLinkException.
+ * <p/>
+ * If close() is invoked on the link while a thread is blocked in receive(),
+ * receive() will throw a ClosedLinkException. No message will have been
+ * transferred in that case.
+ * <p/>
+ * If Thread.interrupt() is invoked on a thread that has not yet completed
+ * an invocation of this method, the results are undefined. An
+ * InterruptedIOException may or may not be thrown; if not, control will
+ * return from the method with a valid LinkMessage object. However, even if
+ * InterruptedIOException is thrown, rendezvous and data transfer from the
+ * sending isolate may have occurred. In particular, undetected message loss
+ * between sender and receiver may occur.
+ * <p/>
+ * If a failure occurs due to the object being transferred between isolates
+ * an IOException may be thrown in the receiver. For example, if a message
+ * containing a large buffer is sent and the receiver has insufficient heap
+ * memory for the buffer or if construction of a link in the receiver
+ * isolate fails, an IOException will be thrown. The sender will see a
+ * successful transfer in these cases.
+ * <p/>
+ * If the current isolate is not a receiver on this Link an
+ * IllegalStateException will be thrown. The receiver will not rendezvous
+ * with a sender in this case.
+ *
+ * @return
+ */
+ final LinkMessage receive() throws ClosedLinkException,
+ IllegalStateException, InterruptedIOException, IOException {
+ if (VmIsolate.currentIsolate() != receiver) {
+ // Current isolate is not the receiver
+ throw new IllegalStateException();
+ }
+ if (this.closed) {
+ throw new ClosedLinkException();
+ }
+ final LinkMessageImpl message;
+ synchronized (this) {
+ while (messages.isEmpty()) {
+ if (this.closed) {
+ throw new ClosedLinkException();
+ }
+ try {
+ wait();
+ } catch (InterruptedException ex) {
+ throw new InterruptedIOException();
+ }
+ }
+ message = messages.poll();
+ }
+ message.notifyReceived();
+ return message.CloneMessage();
+ }
+
+ /**
+ * Sends the given message on this Link.
+ * <p/>
+ * The current thread will block in this method until a receiver is
+ * available. When the sender and receiver rendezvous, the message will then
+ * be transferred. A normal return indicates that the message was
+ * transferred. If an exception occurs on the sender side, no rendezvous
+ * will occur and no object will be transferred. But if an exception occurs
+ * on the receive(), the sender will see a successful transfer.
+ * <p/>
+ * If the receiving isolate becomes terminated after this method is invoked
+ * but before it returns, the link will be closed, a ClosedLinkException
+ * will be thrown, any subsequent attempts to use send() will result in a
+ * ClosedLinkException, and any Isolate objects corresponding to the receive
+ * side of the link will reflect a terminated state.
+ * <p/>
+ * If invoked on a closed link, this method will throw a
+ * ClosedLinkException.
+ * <p/>
+ * If close() is invoked on this Link while a thread is blocked in send(),
+ * send() will throw a ClosedLinkException. No message will have been
+ * transferred in that case.
+ * <p/>
+ * If Thread.interrupt() is invoked on a thread that has not yet completed
+ * an invocation of this method, the results are undefined. An
+ * InterruptedIOException may or may not be thrown; however, even if not,
+ * control will return from the method. Rendezvous and data transfer to the
+ * receiving isolate may or may not have occurred. In particular, undetected
+ * message loss between sender and receiver may occur.
+ * <p/>
+ * If a failure occurs during the transfer an IOException may be thrown in
+ * the sender and the object will not be sent. A transfer may succeed from
+ * the sender's point of view, but cause an independent IOException in the
+ * receiver. For example, if a message containing a large buffer is sent and
+ * the receiver has insufficient heap memory for the buffer or if
+ * construction of a link in the receiver isolate fails, an IOException will
+ * be thrown in the receiver after the transfer completes.
+ * <p/>
+ * A ClosedLinkException will be thrown if the given LinkMessage contains a
+ * closed Link, Socket, or ServerSocket. No object will be transferred in
+ * this case.
+ * <p/>
+ * If the current isolate is not a sender on this Link, an
+ * UnsupportedOperationException will be thrown. No object will be sent in
+ * this case.
+ *
+ * @param message
+ * @throws ClosedLinkException
+ * @throws InterruptedIOException
+ * @throws IOException
+ */
+ final void send(LinkMessage message) throws ClosedLinkException,
+ InterruptedIOException, IOException {
+ if (VmIsolate.currentIsolate() != sender) {
+ // Current isolate is not the sender for this message
+ throw new UnsupportedOperationException();
+ }
+ if (this.closed) {
+ throw new ClosedLinkException();
+ }
+ final LinkMessageImpl messageImpl = (LinkMessageImpl) message;
+ synchronized (this) {
+ if (this.closed) {
+ throw new ClosedLinkException();
+ }
+ // Send message
+ messages.add(messageImpl);
+ notifyAll();
+ }
+
+ // Wait for the message to be picked up by the receiver
+ try {
+ messageImpl.waitUntilReceived();
+ } catch (InterruptedException ex) {
+ throw new InterruptedIOException();
+ }
+ }
+
+ /**
+ * This method is used to send status messages. These are sent
+ * without blocking and are queued in the link for the receiver
+ * to read at its leisure. If the link is closed when this
+ * method is called, the message is quietly dropped.
+ *
+ * @param message the status message to be sent.
+ */
+ public final void sendStatus(LinkMessage message) {
+ if (VmIsolate.currentIsolate() != sender) {
+ // Current isolate is not the sender for this message
+ throw new UnsupportedOperationException();
+ }
+ final LinkMessageImpl messageImpl = (LinkMessageImpl) message;
+ synchronized (this) {
+ if (!this.closed) {
+ // Send message
+ messages.add(messageImpl);
+ notifyAll();
+ }
+ }
+ }
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|