erlang plugin: Sample implementation of register_read.
authorFlorian Forster <octo@leeloo.lan.home.verplant.org>
Fri, 13 Nov 2009 14:56:04 +0000 (15:56 +0100)
committerFlorian Forster <octo@leeloo.lan.home.verplant.org>
Fri, 13 Nov 2009 14:56:04 +0000 (15:56 +0100)
It doesn't do anything useful yet but demonstrates how Funs (even
anonymous functions) can be called.

bindings/erlang/collectd.erl
src/erlang.c

index f4b31c6..cee7c1b 100644 (file)
@@ -1,11 +1,14 @@
 -module(collectd).
--export([dispatch_values/1]).
+-export([dispatch_values/1, register_read/1]).
 
 -include("collectd.hrl").
 
 dispatch_values (VL) when is_record (VL, value_list) ->
        call_cnode (dispatch_values, VL).
 
+register_read (Callback) ->
+       call_cnode (register_read, Callback).
+
 call_cnode(Func, Args) ->
        {any, 'collectd@leeloo.lan.home.verplant.org'} ! {Func, Args},
        receive
index c2d243f..3da9e0f 100644 (file)
@@ -504,6 +504,55 @@ static int handle_dispatch_values (ce_connection_info_t *cinfo, /* {{{ */
        return (0);
 } /* }}} int handle_dispatch_values */
 
+/* Returns non-zero only if the request could not be handled gracefully. */
+static int handle_register_read (ce_connection_info_t *cinfo, /* {{{ */
+               const ErlMessage *req)
+{
+       ETERM *eterm_cb;
+       ETERM *rpc_args;
+       ETERM *rpc_reply;
+
+       if ((cinfo == NULL) || (req == NULL))
+               return (EINVAL);
+
+       eterm_cb = erl_element (2, req->msg);
+
+       if (ERL_TYPE (eterm_cb) != ERL_FUNCTION)
+       {
+               erl_free_term (eterm_cb);
+               send_error (cinfo->fd, req->from,
+                               "Argument to `register_read' must be a callback function.");
+               return (0);
+       }
+
+       send_atom (cinfo->fd, req->from, "success");
+
+       /* FIXME: The following demonstrates how to call this function. This should
+        * be moved somewhere else, of course. */
+
+       /* --- 8< --- */
+       rpc_args = erl_format ("[~w,[]]", eterm_cb);
+       if (rpc_args == NULL)
+       {
+               erl_free_term (eterm_cb);
+               send_error (cinfo->fd, req->from,
+                               "erl_format failed. Sorry.");
+               return (0);
+       }
+
+       rpc_reply = erl_rpc (cinfo->fd,
+                       /* module = */ "erlang", /* function = */ "apply",
+                       /* arguments = */ rpc_args);
+
+       erl_free_compound (rpc_args);
+       /* Right now, the return value is not used. */
+       erl_free_compound (rpc_reply);
+       /* --- >8 --- */
+
+       erl_free_term (eterm_cb); /* XXX: This must stay here. */
+       return (0);
+} /* }}} int handle_dispatch_values */
+
 static void *handle_client_thread (void *arg) /* {{{ */
 {
        ce_connection_info_t *cinfo;
@@ -562,6 +611,8 @@ static void *handle_client_thread (void *arg) /* {{{ */
                        reply = NULL;
                        if (strcmp ("dispatch_values", ERL_ATOM_PTR (func)) == 0)
                                status = handle_dispatch_values (cinfo, &emsg);
+                       else if (strcmp ("register_read", ERL_ATOM_PTR (func)) == 0)
+                               status = handle_register_read (cinfo, &emsg);
                        else
                        {
                                ERROR ("erlang plugin: Received request for invalid function `%s'.",