# HG changeset patch
# User Jay Gagnon <grendel(a)linux.vnet.ibm.com>
# Date 1204056960 18000
# Node ID 79e8d86c710722cb49c0557a1966c72f910641b5
# Parent 568bffb0a58444972a9ae262f45c9b2b9068bbfc
[CU] (#2) 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 :)
Changes from 1 to 2:
cu_ prefix to classname_from_inst call
removed superfluous _ctx assignment in a couple stdi_foo calls
adding provider name to enable/disable messages
Signed-off-by: Jay Gagnon <grendel(a)linux.vnet.ibm.com>
diff -r 568bffb0a584 -r 79e8d86c7107 std_indication.c
--- a/std_indication.c Tue Feb 26 15:16:00 2008 -0500
+++ b/std_indication.c Tue Feb 26 15:16:00 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,169 @@ 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 = cu_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 = cu_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;
+ 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;
+ 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("%s: indications enabled", mi->ft->miName);
+ _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("%s: indications disabled", mi->ft->miName);
+ _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 568bffb0a584 -r 79e8d86c7107 std_indication.h
--- a/std_indication.h Tue Feb 26 15:16:00 2008 -0500
+++ b/std_indication.h Tue Feb 26 15:16:00 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; \