/** * This version is used internally by ServerChannel to call send using a temporory mailAddress * that is unowned. * * @param env the message to send * @throws IllegateStateException if the address is not in the open state, or if the caller is not * the "owner" of this MailboxAddress. */ void send0(Envelope env) throws AddressClosedException { if (state == CLOSED) { throw new AddressClosedException(this); } else if (!mailbox.isOpen()) { closeLocalState(); throw new AddressClosedException(this); } env.setAddresses(this); mailbox.handleMessage(env); }
/** * Sends a message to the Mailbox. Does not wait for acknowledgment. The MailboxAddress must have * been opened by #lookup, must not have been closed, and caller must by the owning isolate of * this MailboxAddress, or an IllegateStateException will be thrown. * * @param env the message to send * @throws IllegateStateException if the address is not in the open state, or if the caller is not * the "owner" of this MailboxAddress. */ public void send(Envelope env) throws AddressClosedException { if (state == CLOSED) { throw new AddressClosedException(this); } else if (!mailbox.isOpen()) { closeLocalState(); throw new AddressClosedException(this); } else if (state == UNOWNED) { throw new IllegalStateException(this + " has not been opened for sending."); } else if (Isolate.currentIsolate() != owner && !(env instanceof AddressClosedEnvelope)) { throw new IllegalStateException( "Attempted send on " + this + " by " + Isolate.currentIsolate()); } env.setAddresses(this); mailbox.handleMessage(env); }
/** * Sends a close message to the corresponding Mailbox, explaining that no more messages will be * sent via this MailboxAddress. Also closes otherAddress if it's open, to eagerly break * connections between isolates. Redundant closes on a Mailbox are ignored. * * <p>Do NOT call while synchronized on "this". Can deadlock on otherAddress.close(). * * @todo Rethink how to close otherAddress only semi-agressivly. Reaper thread, or close dead * Mailbox addresses before attampting a hibernate. */ public void close() { try { synchronized (this) { if (state != OPEN) { return; } Assert.that(mailbox != null, "mailbox is null"); Assert.that(otherAddress != null, "otherAddress is null"); Assert.that(owner != null, "owner is null"); send(new AddressClosedEnvelope()); closeLocalState(); } if (otherAddress.isOpen()) { otherAddress.close(); } } catch (AddressClosedException ex) { // send() will have closeLocalState() for us... } }