/** * This file is part of Erjang - A JVM-based Erlang VM * * Copyright (c) 2009 by Trifork * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. **/ package erjang; import java.util.logging.Level; import kilim.Pausable; import kilim.Task; /** * An EHandle is either an EPort or an EPID. EHandles can be sent messages */ public abstract class EHandle extends EObject { protected final EAbstractNode node; protected EAtom name = ERT.am_undefined; protected EHandle(EAbstractNode node) { if (node == null) throw new IllegalArgumentException("node cannot be null"); this.node = node; } public EHandle testHandle() { return this; } ETask<?> task() { throw new Error("only local handles can provide task reference"); } public boolean exists() { ETask<?> task = task(); return task != null && task.exists(); } /** * @param sender TODO * @param msg * @throws Pausable */ public int send(EHandle sender, EObject msg) throws Pausable { ETask<?> task = task(); if (task != null) { task.mbox.put(msg); return task.mbox.size(); } else { if (ERT.ipclog.isLoggable(Level.FINE)) { ERT.ipclog.fine("sending message to dead process/port ignored "+this+" ! "+msg); } return 0; } } public void sendb(EObject msg) { ETask<?> task = task(); if (task != null) { task.mbox().putb(msg); } } /** * @param is_erlang_exit2 TODO * @param self * @param result * @throws Pausable * @throws Pausable */ public void exit_signal(EHandle from, EObject reason, boolean is_erlang_exit2) throws Pausable { ETask<?> task = task(); if (task != null) { task.send_exit(from, reason, is_erlang_exit2); } } /** * A one-way link message. (other is already linked to this handle). * * @param other * @throws Pausable * @throws Pausable */ public abstract boolean link_oneway(EHandle other) throws Pausable; public abstract void unlink_oneway(EHandle other) throws Pausable; /** * @param ref TODO * @param selfHandle * @throws Pausable */ public abstract boolean add_monitor(EHandle observer, ERef ref) throws Pausable; /** * @param other * @return */ public static EHandle cast(EObject other) { EHandle h = other.testHandle(); if (h == null) { h = ERT.whereis(other).testHandle(); } return h; } /** * @param aname */ public void setName(EAtom aname) { this.name = aname; } /** * @return */ public ELocalHandle testLocalHandle() { return null; } /** * @return */ public EAtom node() { return node.node(); } /** * @param r * @throws Pausable */ public abstract void remove_monitor(EHandle sender, ERef r, boolean flush) throws Pausable; public abstract void send_monitor_exit(EHandle from, ERef ref, EObject reason) throws Pausable; }