Package erjang.m.erlang

Source Code of erjang.m.erlang.ErlDist

/**
* 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.m.erlang;

import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;

import kilim.Pausable;
import erjang.BIF;
import erjang.EAbstractNode;
import erjang.EAtom;
import erjang.EFun;
import erjang.EHandle;
import erjang.EInternalPID;
import erjang.EInternalPort;
import erjang.ENode;
import erjang.EObject;
import erjang.EPeer;
import erjang.EProc;
import erjang.ERT;
import erjang.ERef;
import erjang.ESeq;
import erjang.ESmall;
import erjang.ETuple;
import erjang.ETuple2;
import erjang.ErlangError;
import erjang.Import;
import erjang.NotImplemented;
import erjang.BIF.Type;
import erjang.driver.EDriverTask;

/**
* BIFs supporting distribution
*/
public class ErlDist {
  static Logger log = Logger.getLogger("erjang.dist");

  private static DistEntry this_dist_entry = null;
  private static final EAtom am_net_kernel = EAtom.intern("net_kernel");
  private static final EAtom am_Noname = EAtom.intern("Noname");

  // initialization from node_tables
  static {
   
    this_dist_entry = new DistEntry(am_Noname, (EInternalPort) null);
   
  }
 
 
  /** distribution traps */
 

  @Import(module="net_kernel", fun="connect", arity=1)
  public static EFun net_kernel__connect__1;
 
  @Import(module="erlang", fun="dsend", arity=2)
  static EFun dsend2_trap;
 
  @Import(module="erlang", fun="dsend", arity=3)
  static EFun dsend3_trap;
 
  @Import(module="erlang", fun="dlink", arity=1)
  static EFun dlink1_trap;
 
  @Import(module="erlang", fun="dunlink", arity=1)
  static EFun dunlink1_trap;
 
  @Import(module="erlang", fun="dmonitor_node", arity=3)
  static EFun dmonitor_node3_trap;
 
  @Import(module="erlang", fun="dgroup_leader", arity=2)
  static EFun dgroup_leader2_trap;
 
  @Import(module="erlang", fun="dexit", arity=2)
  static EFun dexit2_trap;

  @Import(module="erlang", fun="dmonitor_p", arity=2)
  static EFun dmonitor_p2_trap;

  static EAtom erts_is_alive = ERT.FALSE;

  @BIF
  public static final EObject is_alive() {
    return erts_is_alive;
  }
 
  @BIF
  public static EObject nodes(EObject node) {
    throw new NotImplemented();
  }

  @BIF
  public static EObject monitor_node(EProc proc, EObject node, EObject flag, EObject opts) throws Pausable {
   
    EAtom aname = node.testAtom();
    EAtom aflag = flag.testAtom();
    ESeq sopts = opts.testSeq();
   
    if (aname == null || aflag == null || sopts == null) {
      throw ERT.badarg(node, flag);
    }
   
    EAbstractNode n = EPeer.get(aname);
    if (n == null) {
      return dmonitor_node3_trap.invoke(proc, new EObject[]{aname, aflag, opts});
    } else {     
      n.monitor_node(proc.self_handle(), aflag==ERT.TRUE);
      return ERT.TRUE;
    }
   
  }

  @BIF
  public static EObject monitor_node(EProc proc, EObject node, EObject flag) throws Pausable {
    return monitor_node(proc, node, flag, ERT.NIL);
  }

  @BIF
  public static EObject dist_exit(EObject a1, EObject a2, EObject a3) {
    throw new NotImplemented();
  }
 
  @BIF
  static public EAtom node() {
    EAtom val = ERT.getLocalNode().node();
    return val;
  }

  @BIF
  static public EAtom node(EObject name) {
   
    if (!ERT.getLocalNode().isALive()) {
      return ENode.am_nonode_at_nohost;
    }
   
    ERef ref;
    if ((ref=name.testReference()) != null)
      return ref.node();
   
    EHandle handle;
    if ((handle=name.testHandle()) != null)
      return handle.node();
   
    throw ERT.badarg(name);
  }

  @BIF(type = Type.GUARD, name = "node")
  static public EAtom node$p(EObject name) {
   
    if (!ERT.getLocalNode().isALive()) {
      return ENode.am_nonode_at_nohost;
    }
   
    EHandle handle;
    if ((handle=name.testHandle()) != null) {
      return handle.node();
    }
   
    ERef ref;
    if ((ref=name.testReference()) != null) {
      return ref.node();
    }
   
    return null;
  }

  @BIF
  public static EObject setnode(EObject arg_node, EObject arg_creation)
    throws Pausable
  {

    int creation;
    ESmall cr = arg_creation.testSmall();
    EAtom node = arg_node.testAtom();
   
    if (cr == null || node == null || cr.value > 3 || !is_node_name_atom(node)) {
      if (log.isLoggable(Level.FINE)) log.fine("cr="+cr+"; node="+node+"; is_name="+is_node_name_atom(node));
      throw ERT.badarg(arg_node, arg_creation);
    }

    EObject net_kernel = ERT.whereis(am_net_kernel);   
    EInternalPID nk = net_kernel.testInternalPID();
    if (nk == null) {
      throw new ErlangError(EAtom.intern("no_net_kernel"));
    }
   
    nk.set_dist_entry(this_dist_entry);
    // nk.add_flag( F_DISTRIBUTION );
   
    set_this_node(node, cr.value);
    erts_is_alive = ERT.TRUE;

    EAbstractNode n = EPeer.get(node);
    n.node_up(null/*??*/, ERT.NIL);

    return ERT.TRUE;
  }

  private static void set_this_node(EAtom node, int value) {
    ERT.getLocalNode().set(node, value);
  }

  private static Pattern node_name_regex = Pattern.compile("([a-zA-Z0-9_]|-)+@[^@]+");
  public static boolean is_node_name_atom(EAtom node) {
    if (node_name_regex.matcher(node.getName()).matches()) {
      return true;
    } else {
      return false;
    }
  }

  /**********************************************************************
   ** Allocate a dist entry, set node name install the connection handler
   ** setnode_3({name@host, Creation}, Cid, {Type, Version, Initial, IC, OC})
   ** Type = flag field, where the flags are specified in dist.h
   ** Version = distribution version, >= 1
   ** IC = in_cookie (ignored)
   ** OC = out_cookie (ignored)
   **
   ** Note that in distribution protocols above 1, the Initial parameter
   ** is always NIL and the cookies are always the atom '', cookies are not
   ** sent in the distribution messages but are only used in
   ** the handshake.
   **
   ***********************************************************************/

  @BIF
  public static EObject setnode(EObject node_arg, EObject cid_arg, EObject type_arg)
    throws Pausable
  {
    //System.err.println("SETNODE("+node_arg+", "+cid_arg+", "+type_arg+")");
   
    EAtom node;
    int creation = 0;
   
    ETuple2 tup;
    if ((tup=ETuple2.cast(node_arg)) != null) {
      node = tup.elem1.testAtom();
      ESmall sm = tup.elem2.testSmall();
     
      if (node == null || sm==null || !is_node_name_atom(node))
        throw ERT.badarg(node_arg, cid_arg, type_arg);
     
      creation = sm.value;
    } else if ((node=node_arg.testAtom()) != null && is_node_name_atom(node)) {
      // ok
    } else {
      throw ERT.badarg(node_arg, cid_arg, type_arg);
    }
   
    /** first arg is ok */
   
    EInternalPort port = cid_arg.testInternalPort();
    if (port == null) {
      throw ERT.badarg(node_arg, cid_arg, type_arg);
    }

    ETuple t = type_arg.testTuple();
    if (t.arity() != 4) {
      throw ERT.badarg(node_arg, cid_arg, type_arg);
    }
   
    ESmall flags = t.elm(1).testSmall();
    ESmall version = t.elm(2).testSmall();
    if (flags == null || version == null) {
      throw ERT.badarg(node_arg, cid_arg, type_arg);
    }

    EPeer n = EPeer.get_or_create(node, creation, port, flags.value, version.value);
   
    EDriverTask task = port.task();
    if (task != null) {
      task.node(n);

      /*TODO:
    send_nodes_mon_msgs(BIF_P,
                        am_nodeup,
                        BIF_ARG_1,
                        flags & DFLAG_PUBLISHED ? am_visible : am_hidden,
                        NIL);
      */

      n.node_up(null/*??*/, ERT.NIL);

      return ERT.TRUE;
    } else {
      return ERT.FALSE;
    }
  }

}
TOP

Related Classes of erjang.m.erlang.ErlDist

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.