[erlang-questions] C nodes and global registration

Ariel Segall asegall@REDACTED
Mon Jan 5 22:25:50 CET 2009

We're building an Erlang application that requires access to some C libraries, and have been attempting to implement the Erlang C node instructions from the EI User's Guide. Our C node and Erlang node can pass messages to each other with no problems, but attempting to register the C node with a global name consistently fails.

When we call erl_global_register from the C side, it returns a failure and our Erlang node has the following error report: 

Error in process <0.45.0> on node 'e1@REDACTED' with exit value: {badarg,[{erlang,monitor,[process,<5159.5.0>]},{global,'-do_monitor/1-fun-0-',1}]}

When we instead use the global:register_name function from the Erlang shell, to associate our C node's PID with the desired name, register_name returns "yes" (success) but we again get the monitor error. In either case, our name does not show up in the list of registered processes.

My best guess as to what's going on here is that the C node can't be monitored, and the global registration code removes or refuses the registration when it can't establish that the C node is still alive. We've found several examples online that seem to use the C erl_global_register function with no trouble, however, and none of them even mention additional monitoring code.

Here's the relevant section of C code up to the failure; when attempting to do global registration from Erlang, we comment out the last two lines.

  int BUFSIZE = 1024;
  int identification_number = 99;
  int creation=1;
  int loop=1;
  char *cookie="secret";
  const char *thisnodename;
  int openport, sockfd, rc, portdescriptor;
  int port=1333;
  ErlConnect conn;
  char buf[BUFSIZE];
  ErlMessage emsg;
  ETERM *self, *ans[3], *answer, *dest;
  // Initialize connection
  erl_init(NULL, 0);
  if (erl_connect_init(identification_number, cookie, creation) == -1)
    erl_err_quit("erl_connect_init failed");
  fprintf(stderr, "Completed erlang intialization\n");
// Start TCP server
  if ((openport = initserver(port)) <=0)
    erl_err_quit("Initialization of server failed");
  fprintf(stderr, "Completed TCP server initialization with port result %d\n", openport);
  portdescriptor = erl_publish(port);
  if (portdescriptor == -1)
    erl_err_quit("erl_publish failed");
  fprintf(stderr, "Completed Erlang publishing\n");
 if ((sockfd = erl_accept(openport, &conn)) == ERL_ERROR)
    erl_err_quit("erl_accept failed");
  fprintf(stderr, "Connected to %s\n", conn.nodename);
  //Register the TPM interface as a global name for easy accessibility
  thisnodename = erl_thisnodename();
  fprintf(stderr, "Calculated own nodename of %s\n", thisnodename);
  self = erl_mk_pid(thisnodename, sockfd, 0, erl_thiscreation());
    if (erl_global_register(sockfd, "tpm_interface", self) !=0)
      erl_err_quit("Failed to register process");

(Code after the registration attempt has been removed for clarity.)

We'd appreciate any suggestions.


More information about the erlang-questions mailing list