From e08d6907db8ad7d9b411e35b499ff82ce3cd9e01 Mon Sep 17 00:00:00 2001 From: Sebastian Harl Date: Sat, 17 Nov 2007 18:38:45 +0100 Subject: [PATCH] perl plugin: Added Collectd::call_by_name(). This XSUB passes on a function call to a subroutine identified by its name passed through $Collectd::cb_name. Collectd::call_by_name does not touch the stack (unless in case of an error), thus any arguments and return values are kept in place. This function is meant to be used inside Collectd.pm only. Signed-off-by: Sebastian Harl Signed-off-by: Florian Forster --- src/perl.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/perl.c b/src/perl.c index fbbe591d..4ae3cd1a 100644 --- a/src/perl.c +++ b/src/perl.c @@ -51,6 +51,10 @@ # error "Perl does not support ithreads!" #endif /* !defined(USE_ITHREADS) */ +/* clear the Perl sub's stack frame + * (this should only be used inside an XSUB) */ +#define CLEAR_STACK_FRAME PL_stack_sp = PL_stack_base + *PL_markstack_ptr + #define PLUGIN_INIT 0 #define PLUGIN_READ 1 #define PLUGIN_WRITE 2 @@ -73,6 +77,7 @@ static XS (Collectd_plugin_register_ds); static XS (Collectd_plugin_unregister_ds); static XS (Collectd_plugin_dispatch_values); static XS (Collectd_plugin_log); +static XS (Collectd_call_by_name); /* * private data types @@ -121,6 +126,7 @@ static struct { { "Collectd::plugin_unregister_data_set", Collectd_plugin_unregister_ds }, { "Collectd::plugin_dispatch_values", Collectd_plugin_dispatch_values }, { "Collectd::plugin_log", Collectd_plugin_log }, + { "Collectd::call_by_name", Collectd_call_by_name }, { "", NULL } }; @@ -735,6 +741,35 @@ static XS (Collectd_plugin_log) } /* static XS (Collectd_plugin_log) */ /* + * Collectd::call_by_name (...). + * + * Call a Perl sub identified by its name passed through $Collectd::cb_name. + */ +static XS (Collectd_call_by_name) +{ + SV *tmp = NULL; + char *name = NULL; + + if (NULL == (tmp = get_sv ("Collectd::cb_name", 0))) { + log_debug ("Collectd::call_by_name: cb_name is not set."); + CLEAR_STACK_FRAME; + return; + } + + name = SvPV_nolen (tmp); + + if (NULL == get_cv (name, 0)) { + log_err ("Collectd::call_by_name: Unknown callback \"%s\".", name); + CLEAR_STACK_FRAME; + return; + } + + /* simply pass on the subroutine call without touching the stack, + * thus leaving any arguments and return values in place */ + call_pv (name, 0); +} /* static XS (Collectd_call_by_name) */ + +/* * collectd's perl interpreter based thread implementation. * * This has been inspired by Perl's ithreads introduced in version 5.6.0. -- 2.11.0