
# HG changeset patch # User Jay Gagnon <grendel@linux.vnet.ibm.com> # Date 1203957417 18000 # Node ID f30365d472ed40da0af04d7ea3671ba3ac113580 # Parent af61b6c75b143067444f4eefe694d1e9709d2ccb [CU] Turn std_indication's awesome knob to eleven The new std_indication handles Enable/DisableIndications and Activate/DeactivateFilter correctly, even on a per-indication basis when one provider handles more than one indication. Those functions also now have default_foo equivalents in std_indication, as many providers (especially raise-style ones) will have no special needs there. Changes required to make it work: new struct to track which of a providers indications are active in the filter little macro to make declaring the new filter struct nice and clean new std_indication_ctx members for filters and global (per-provider) enabled flags stdi_foo functions that do the default behavior and dispatch work moving ind_args and CMPI_EI_VOID ifdef into std_indication My apologies for: how much there is in this one patch the reordering going on in std_indication.h, which I know isn't very PCO, I have some ready-made excuses for those that require them :) Signed-off-by: Jay Gagnon <grendel@linux.vnet.ibm.com> diff -r af61b6c75b14 -r f30365d472ed std_indication.c --- a/std_indication.c Wed Feb 13 08:26:56 2008 -0800 +++ b/std_indication.c Mon Feb 25 11:36:57 2008 -0500 @@ -32,10 +32,65 @@ #include "std_indication.h" +void stdi_free_ind_args (struct ind_args **args) +{ + free((*args)->ns); + free((*args)->classname); + free(*args); + *args = NULL; +} + +static struct std_ind_filter *get_ind_filter(struct std_ind_filter **list, + const char *ind_name) +{ + int i; + struct std_ind_filter *filter = NULL; + + for (i = 0; list[i] != NULL; i++) { + if (STREQC((list[i])->ind_name, ind_name)) { + filter = list[i]; + break; + } + } + + if (filter == NULL) + CU_DEBUG("get_ind_filter: failed to find %s", ind_name); + + return filter; +} + +static bool is_ind_enabled(struct std_indication_ctx *ctx, + const char *ind_name, + CMPIStatus *s) +{ + bool ret = false; + struct std_ind_filter *filter; + + if (!ctx->enabled) { + CU_DEBUG("Indications disabled for this provider"); + ret = false; + goto out; + } + + filter = get_ind_filter(ctx->filters, ind_name); + if (filter == NULL) { + cu_statusf(ctx->brkr, s, + CMPI_RC_ERR_FAILED, + "No std_ind_filter for %s", ind_name); + goto out; + } + + ret = filter->active; + if (!ret) + CU_DEBUG("Indication '%s' not in active filter", ind_name); + out: + return ret; +} + static CMPIStatus trigger(struct std_indication_ctx *ctx, const CMPIContext *context) { - if (ctx->handler->trigger_fn == NULL) + if (ctx->handler == NULL || ctx->handler->trigger_fn == NULL) return (CMPIStatus){CMPI_RC_OK, NULL}; return ctx->handler->trigger_fn(context); @@ -61,20 +116,171 @@ static CMPIStatus raise(struct std_indic const CMPIContext *context, const CMPIArgs *argsin) { + bool enabled; CMPIInstance *inst; - - if (!ctx->enabled) { - CU_DEBUG("Indication disabled, not raising."); - return (CMPIStatus) {CMPI_RC_OK, NULL}; - } - - if (cu_get_inst_arg(argsin, "Indication", &inst) != CMPI_RC_OK) - return (CMPIStatus){CMPI_RC_ERR_FAILED, NULL}; - - if (ctx->handler->raise_fn == NULL) - return default_raise(ctx->brkr, context, inst); - - return ctx->handler->raise_fn(ctx->brkr, context, inst); + CMPIStatus s = {CMPI_RC_OK, NULL}; + const char *ind_name = NULL; + + if (cu_get_inst_arg(argsin, "Indication", &inst) != CMPI_RC_OK) { + cu_statusf(ctx->brkr, &s, + CMPI_RC_ERR_FAILED, + "Could not get indication to raise"); + goto out; + } + + ind_name = classname_from_inst(inst); + if (ind_name == NULL) { + cu_statusf(ctx->brkr, &s, + CMPI_RC_ERR_FAILED, + "Couldn't get indication name for enable check."); + } + + enabled = is_ind_enabled(ctx, ind_name, &s); + if (s.rc != CMPI_RC_OK) { + CU_DEBUG("Problem checking enabled: '%s'", CMGetCharPtr(s.msg)); + goto out; + } + + if (!enabled) + goto out; + + if (ctx->handler == NULL || ctx->handler->raise_fn == NULL) + s = default_raise(ctx->brkr, context, inst); + else + s = ctx->handler->raise_fn(ctx->brkr, context, inst); + + out: + return s; +} +CMPIStatus stdi_deliver(const CMPIBroker *broker, + const CMPIContext *ctx, + struct ind_args *args, + CMPIInstance *ind) +{ + bool enabled; + const char *ind_name; + CMPIStatus s = {CMPI_RC_OK, NULL}; + + ind_name = classname_from_inst(ind); + if (ind_name == NULL) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "Couldn't get indication name for enable check."); + } + + enabled = is_ind_enabled(args->_ctx, ind_name, &s); + if (s.rc != CMPI_RC_OK) { + CU_DEBUG("Problem checking enabled: '%s'", CMGetCharPtr(s.msg)); + goto out; + } + + if (enabled) + s = CBDeliverIndication(broker, ctx, args->ns, ind); + + out: + return s; +} + +CMPIStatus stdi_set_ind_filter_state(struct std_indication_ctx *ctx, + char *ind_name, + bool state) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + struct std_ind_filter *filter; + + filter = get_ind_filter(ctx->filters, ind_name); + if (filter == NULL) { + cu_statusf(ctx->brkr, &s, + CMPI_RC_ERR_FAILED, + "Provider has no indication '%s'", ind_name); + goto out; + } + + filter->active = state; + + out: + return s; +} + +CMPIStatus stdi_activate_filter(CMPIIndicationMI* mi, + const CMPIContext* ctx, + const CMPISelectExp* se, + const char *ns, + const CMPIObjectPath* op, + CMPIBoolean first) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + struct std_indication_ctx *_ctx; + _ctx = (struct std_indication_ctx *)mi->hdl; + char *cn = NULL; + + _ctx = (struct std_indication_ctx *)mi->hdl; + cn = CLASSNAME(op); + s = stdi_set_ind_filter_state(_ctx, cn, true); + + if (_ctx->handler != NULL && _ctx->handler->activate_fn != NULL) { + CU_DEBUG("Calling handler->activate_fn"); + s = _ctx->handler->activate_fn(mi, ctx, se, ns, op, first); + goto out; + } + + out: + return s; +} + +CMPIStatus stdi_deactivate_filter(CMPIIndicationMI* mi, + const CMPIContext* ctx, + const CMPISelectExp* se, + const char *ns, + const CMPIObjectPath* op, + CMPIBoolean last) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + struct std_indication_ctx *_ctx; + _ctx = (struct std_indication_ctx *)mi->hdl; + char *cn = NULL; + + _ctx = (struct std_indication_ctx *)mi->hdl; + cn = CLASSNAME(op); + s = stdi_set_ind_filter_state(_ctx, cn, false); + + if (_ctx->handler != NULL && _ctx->handler->deactivate_fn != NULL) { + s = _ctx->handler->deactivate_fn(mi, ctx, se, ns, op, last); + goto out; + } + + out: + return s; +} + +_EI_RTYPE stdi_enable_indications (CMPIIndicationMI* mi, + const CMPIContext *ctx) +{ + struct std_indication_ctx *_ctx; + _ctx = (struct std_indication_ctx *)mi->hdl; + + CU_DEBUG("enabling indications"); + _ctx->enabled = true; + + if (_ctx->handler != NULL && _ctx->handler->enable_fn != NULL) + return _ctx->handler->enable_fn(mi, ctx); + + _EI_RET(); +} + +_EI_RTYPE stdi_disable_indications (CMPIIndicationMI* mi, + const CMPIContext *ctx) +{ + struct std_indication_ctx *_ctx; + _ctx = (struct std_indication_ctx *)mi->hdl; + + CU_DEBUG("disabling indications"); + _ctx->enabled = false; + + if (_ctx->handler != NULL && _ctx->handler->disable_fn != NULL) + return _ctx->handler->disable_fn(mi, ctx); + + _EI_RET(); } CMPIStatus stdi_handler(CMPIMethodMI *self, diff -r af61b6c75b14 -r f30365d472ed std_indication.h --- a/std_indication.h Wed Feb 13 08:26:56 2008 -0800 +++ b/std_indication.h Mon Feb 25 11:36:57 2008 -0500 @@ -26,8 +26,74 @@ #include <cmpimacs.h> #include <stdio.h> +#include "config.h" + #include "libcmpiutil.h" #include "std_invokemethod.h" + +#ifdef CMPI_EI_VOID +# define _EI_RTYPE void +# define _EI_RET() return +#else +# define _EI_RTYPE CMPIStatus +# define _EI_RET() return (CMPIStatus){CMPI_RC_OK, NULL} +#endif + +typedef CMPIStatus (*raise_indication_t)(const CMPIBroker *broker, + const CMPIContext *ctx, + const CMPIInstance *ind); + +typedef CMPIStatus (*trigger_indication_t)(const CMPIContext *ctx); + +typedef CMPIStatus (*activate_function_t) (CMPIIndicationMI* mi, + const CMPIContext* ctx, + const CMPISelectExp* se, + const char *ns, + const CMPIObjectPath* op, + CMPIBoolean first); + +typedef CMPIStatus (*deactivate_function_t) (CMPIIndicationMI* mi, + const CMPIContext* ctx, + const CMPISelectExp* se, + const char *ns, + const CMPIObjectPath* op, + CMPIBoolean last); + +typedef _EI_RTYPE (*enable_function_t) (CMPIIndicationMI* mi, + const CMPIContext *ctx); + +typedef _EI_RTYPE (*disable_function_t) (CMPIIndicationMI* mi, + const CMPIContext *ctx); + +struct std_indication_handler { + raise_indication_t raise_fn; + trigger_indication_t trigger_fn; + activate_function_t activate_fn; + deactivate_function_t deactivate_fn; + enable_function_t enable_fn; + disable_function_t disable_fn; +}; + +struct std_ind_filter { + char *ind_name; + bool active; +}; + +struct std_indication_ctx { + const CMPIBroker *brkr; + struct std_indication_handler *handler; + struct std_ind_filter **filters; + bool enabled; +}; + +struct ind_args { + CMPIContext *context; + char *ns; + char *classname; + struct std_indication_ctx *_ctx; +}; + +void stdi_free_ind_args (struct ind_args **args); CMPIStatus stdi_trigger_indication(const CMPIBroker *broker, const CMPIContext *context, @@ -39,6 +105,31 @@ CMPIStatus stdi_raise_indication(const C const char *type, const char *ns, const CMPIInstance *ind); + +CMPIStatus stdi_deliver(const CMPIBroker *broker, + const CMPIContext *ctx, + struct ind_args *args, + CMPIInstance *ind); + +CMPIStatus stdi_activate_filter(CMPIIndicationMI* mi, + const CMPIContext* ctx, + const CMPISelectExp* se, + const char *ns, + const CMPIObjectPath* op, + CMPIBoolean first); + +CMPIStatus stdi_deactivate_filter(CMPIIndicationMI* mi, + const CMPIContext* ctx, + const CMPISelectExp* se, + const char *ns, + const CMPIObjectPath* op, + CMPIBoolean last); + +_EI_RTYPE stdi_enable_indications (CMPIIndicationMI* mi, + const CMPIContext *ctx); + +_EI_RTYPE stdi_disable_indications (CMPIIndicationMI* mi, + const CMPIContext *ctx); CMPIStatus stdi_handler(CMPIMethodMI *self, const CMPIContext *context, @@ -52,27 +143,22 @@ CMPIStatus stdi_cleanup(CMPIMethodMI *se const CMPIContext *context, CMPIBoolean terminating); -typedef CMPIStatus (*raise_indication_t)(const CMPIBroker *broker, - const CMPIContext *ctx, - const CMPIInstance *ind); - -typedef CMPIStatus (*trigger_indication_t)(const CMPIContext *ctx); - -struct std_indication_handler { - raise_indication_t raise_fn; - trigger_indication_t trigger_fn; -}; - -struct std_indication_ctx { - const CMPIBroker *brkr; - struct std_indication_handler *handler; - bool enabled; -}; - -#define STDI_IndicationMIStub(pfx, pn, _broker, hook, _handler) \ - static struct std_indication_ctx _ctx = { \ +CMPIStatus stdi_set_ind_filter_state(struct std_indication_ctx *ctx, + char *ind_name, + bool state); + +/* This doesn't work, but should be made to. */ +#define DECLARE_FILTER(ident, name) \ + static struct std_ind_filter ident = { \ + .ind_name = name, \ + .active = false, \ + }; \ + +#define STDI_IndicationMIStub(pfx, pn, _broker, hook, _handler, filters)\ + static struct std_indication_ctx pn##_ctx = { \ .brkr = NULL, \ .handler = _handler, \ + .filters = filters, \ .enabled = false, \ }; \ \ @@ -83,9 +169,10 @@ struct std_indication_ctx { pfx##IndicationCleanup, \ pfx##AuthorizeFilter, \ pfx##MustPoll, \ - pfx##ActivateFilter, \ - pfx##DeActivateFilter, \ - CMIndicationMIStubExtensions(pfx) \ + stdi_activate_filter, \ + stdi_deactivate_filter, \ + stdi_enable_indications, \ + stdi_disable_indications, \ }; \ CMPIIndicationMI * \ pn##_Create_IndicationMI(const CMPIBroker *, \ @@ -96,10 +183,10 @@ struct std_indication_ctx { const CMPIContext *ctx, \ CMPIStatus *rc) { \ static CMPIIndicationMI mi = { \ - &_ctx, \ + &pn##_ctx, \ &indMIFT__, \ }; \ - _ctx.brkr = brkr; \ + pn##_ctx.brkr = brkr; \ _broker = brkr; \ hook; \ return &mi; \ @@ -121,10 +208,10 @@ struct std_indication_ctx { const CMPIContext *ctx, \ CMPIStatus *rc) { \ static CMPIMethodMI mi = { \ - &_ctx, \ + &pn##_ctx, \ &methMIFT__, \ }; \ - _ctx.brkr = brkr; \ + pn##_ctx.brkr = brkr; \ _broker = brkr; \ hook; \ return &mi; \