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. |