diff options
Diffstat (limited to 'common/elapi/elapi_internal.c')
-rw-r--r-- | common/elapi/elapi_internal.c | 247 |
1 files changed, 151 insertions, 96 deletions
diff --git a/common/elapi/elapi_internal.c b/common/elapi/elapi_internal.c index 3007fc2e..8b1071e8 100644 --- a/common/elapi/elapi_internal.c +++ b/common/elapi/elapi_internal.c @@ -105,60 +105,19 @@ int elapi_tgt_free_cb(const char *target, return EOK; } - - -int elapi_sink_cb(const char *sink, - int sink_len, - int type, - void *data, - int length, - void *passed_data, - int *stop) -{ - TRACE_FLOW_STRING("elapi_sink_cb", "Entry."); - - /* FIXME THIS IS A PLACEHOLDER FUNCTION FOR NOW */ - - /* Skip header */ - if (type == COL_TYPE_COLLECTION) { - TRACE_FLOW_STRING("elapi_sink_cb - skip header", "Exit."); - return EOK; - } - - printf("Sink: %s\n", sink); - - TRACE_FLOW_STRING("elapi_sink_cb", "Exit."); - return EOK; -} - -/* Internal sink cleanup function */ -int elapi_sink_free_cb(const char *sink, - int sink_len, - int type, - void *data, - int length, - void *passed_data, - int *stop) -{ - TRACE_FLOW_STRING("elapi_sink_free_cb", "Entry."); - - /* FIXME THIS IS A PLACEHOLDER FUNCTION FOR NOW */ - - printf("Cleaning Sink: %s\n", sink); - - TRACE_FLOW_STRING("elapi_sink_free_cb", "Exit."); - return EOK; -} - /* Function to add a sink to the collection */ +/* This function belongs to this module. + * It adds sink into the collection + * of sinks inside dispatcher and puts + * reference into the target's reference list. + */ /* FIXME - other arguments might be added later */ int elapi_sink_add(struct collection_item **sink_ref, char *sink, struct elapi_dispatcher *handle) { int error = EOK; - struct elapi_sink_ctx sink_context; - struct collection_item *provider_cfg_item = NULL; + struct elapi_sink_ctx *sink_context = NULL; TRACE_FLOW_STRING("elapi_sink_add", "Entry"); @@ -183,42 +142,36 @@ int elapi_sink_add(struct collection_item **sink_ref, if (!(*sink_ref)) { TRACE_FLOW_STRING("No such sink yet, adding new sink:", sink); - /* First check if this sink is properly configured and get its provider */ - error = get_config_item(sink, - ELAPI_SINK_PROVIDER, - handle->ini_config, - &provider_cfg_item); - if (error) { - TRACE_ERROR_NUMBER("Attempt to read provider attribute returned error", error); + /* Create a sink object */ + error = elapi_sink_create(&sink_context, sink, handle->ini_config); + if (error != 0) { + TRACE_ERROR_NUMBER("Failed to add sink data as property", error); + /* If create failed there is nothing to destroy */ return error; } - /* Do we have provider? */ - if (provider_cfg_item == NULL) { - /* There is no provider - return error */ - TRACE_ERROR_STRING("Required key is missing in the configuration.", "Fatal Error!"); - return ENOENT; + /* If there was an internal error but sink is optional + * no error is returned but context is NULL. + * We need to check for this situation. + */ + if (sink_context) { + TRACE_FLOW_STRING("Loaded sink:", sink); + /* We got a valid sink so add it to the collection */ + error = col_add_binary_property_with_ref(handle->sink_list, + NULL, + sink, + (void *)(&sink_context), + sizeof(struct elapi_sink_ctx *), + sink_ref); + if (error != 0) { + TRACE_ERROR_NUMBER("Failed to add sink data as property", error); + elapi_sink_destroy(sink_context); + return error; + } } - - - /* FIXME: PLACEHOLDER - * This is the area where the actual sink is loaded. - * CODE WILL BE ADDED HERE... - */ - sink_context.async_mode = 0; - sink_context.in_queue = NULL; - sink_context.pending = NULL; - - /* We got a valid sink so add it to the collection */ - error = col_add_binary_property_with_ref(handle->sink_list, - NULL, - sink, - (void *)(&sink_context), - sizeof(struct elapi_sink_ctx), - sink_ref); - if (error != 0) { - TRACE_ERROR_NUMBER("Failed to add sink data as property", error); - return error; + else { + *sink_ref = NULL; + TRACE_FLOW_STRING("Setting sink reference to NULL", ""); } } @@ -258,6 +211,7 @@ int elapi_tgt_create(struct elapi_tgt_ctx **context, char **sinks; char **current_sink; struct collection_item *sink_ref; + unsigned count; TRACE_FLOW_STRING("elapi_tgt_create", "Entry."); @@ -281,7 +235,7 @@ int elapi_tgt_create(struct elapi_tgt_ctx **context, /* Allocate context */ target_context = (struct elapi_tgt_ctx *)malloc(sizeof(struct elapi_tgt_ctx)); if (target_context == NULL) { - TRACE_ERROR_NUMBER("Memory allocation failed. Error", target_context); + TRACE_ERROR_NUMBER("Memory allocation failed. Error", ENOMEM); return ENOMEM; } @@ -362,22 +316,45 @@ int elapi_tgt_create(struct elapi_tgt_ctx **context, return error; } - /* Add reference to it into the target object */ - error = col_add_binary_property(target_context->sink_ref_list, NULL, - *current_sink, (void *)(&sink_ref), - sizeof(struct collection_item *)); - if (error != 0) { - TRACE_ERROR_NUMBER("Failed to add sink reference", error); - elapi_tgt_destroy(target_context); - free_string_config_array(sinks); - return error; + /* It might be that is was an error wit the optional sink so + * we need to check if the reference is not NULL; + */ + if (sink_ref) { + /* Add reference to it into the target object */ + error = col_add_binary_property(target_context->sink_ref_list, NULL, + *current_sink, (void *)(&sink_ref), + sizeof(struct collection_item *)); + if (error != 0) { + TRACE_ERROR_NUMBER("Failed to add sink reference", error); + elapi_tgt_destroy(target_context); + free_string_config_array(sinks); + return error; + } + } + else { + TRACE_INFO_STRING("Sink reference is NULL.", "Skipping the sink"); } - current_sink++; } free_string_config_array(sinks); + /* Get count of the references in the list */ + error = col_get_collection_count(target_context->sink_ref_list, &count); + if (error) { + TRACE_ERROR_NUMBER("Failed to get count", error); + elapi_tgt_destroy(target_context); + return error; + } + + /* Check count */ + if (count <= 1) { + /* Nothing but header? - Bad! */ + TRACE_ERROR_NUMBER("No sinks loaded for target!", "This is a fatal error!"); + elapi_tgt_destroy(target_context); + return ENOENT; + } + *context = target_context; TRACE_FLOW_STRING("elapi_tgt_create", "Exit."); @@ -503,6 +480,54 @@ void elapi_dump_ini_err(struct collection_item *error_list) TRACE_FLOW_STRING("elapi_dump_ini_err", "Exit"); } +/****************************************************************************/ +/* Functions below are added for debugging purposes */ +/****************************************************************************/ +#ifdef ELAPI_UTEST + +void elapi_print_sink_ctx(struct elapi_sink_ctx *sink_context) +{ + /* This will not print well on 64 bit but it is just debugging + * so it is OK to have it. + */ + printf("Printing sink context using address %X\n", (uint32_t)(sink_context)); + + printf("Mode: %s\n", sink_context->async_mode ? "true" : "false"); + if (sink_context->in_queue) col_print_collection(sink_context->in_queue); + else printf("Queue is not initialized.\n"); + + if (sink_context->pending) col_print_collection(sink_context->pending); + else printf("Pending list is not initialized.\n"); + + if (sink_context->sink_cfg.provider) printf("Provider: %s\n", + sink_context->sink_cfg.provider); + else printf("Provider is not defined.\n"); + + printf("Is provider required? %s\n", ((sink_context->sink_cfg.required > 0) ? "Yes" : "No")); + printf("On error: %s\n", ((sink_context->sink_cfg.onerror == 0) ? "retry" : "fail")); + printf("Timout: %d\n", sink_context->sink_cfg.timeout); + printf("Sync configuration: %s\n", sink_context->sink_cfg.synch ? "true" : "false"); + + if (sink_context->sink_cfg.priv_ctx) printf("Private context allocated.\n"); + else printf("Private context is NULL.\n"); + + if (sink_context->sink_cfg.libhandle) printf("Lib handle is allocated.\n"); + else printf("Lib handle is NULL.\n"); + + if (sink_context->sink_cfg.ability) printf("Capability function is present\n"); + else printf("NO capability function.\n"); + + if (sink_context->sink_cfg.cpb_cb.init_cb) printf("Init callback is OK.\n"); + else printf("Init callback is missing.\n"); + + if (sink_context->sink_cfg.cpb_cb.submit_cb) printf("Submit callback is OK.\n"); + else printf("Submit callback is missing.\n"); + + if (sink_context->sink_cfg.cpb_cb.close_cb) printf("Close callback is OK.\n"); + else printf("Close callback is missing.\n"); + + +} /* Handler for printing target internals */ static int elapi_sink_ref_dbg_cb(const char *sink, @@ -525,19 +550,38 @@ static int elapi_sink_ref_dbg_cb(const char *sink, printf("\nReferenced sink name is: %s\n", col_get_item_property(sink_item, NULL)); - sink_context = (struct elapi_sink_ctx *)(col_get_item_data(sink_item)); + sink_context = *((struct elapi_sink_ctx **)(col_get_item_data(sink_item))); - printf("Mode: %s\n", sink_context->async_mode ? "true" : "false"); - if (sink_context->in_queue) col_print_collection(sink_context->in_queue); - else printf("Queue is not initialized.\n"); + elapi_print_sink_ctx(sink_context); - if (sink_context->pending) col_print_collection(sink_context->pending); - else printf("Pending list is not initialized.\n"); return EOK; } +/* Handler for printing sink internals */ +static int elapi_sink_dbg_cb(const char *sink, + int sink_len, + int type, + void *data, + int length, + void *passed_data, + int *stop) +{ + struct elapi_sink_ctx *sink_context; + /* Skip header */ + if (type == COL_TYPE_COLLECTION) { + return EOK; + } + + sink_context = *((struct elapi_sink_ctx **)(data)); + + printf("\nSink name is: %s\n", sink); + + elapi_print_sink_ctx(sink_context); + + return EOK; +} /* Handler for printing target internals */ static int elapi_tgt_dbg_cb(const char *target, @@ -569,6 +613,7 @@ static int elapi_tgt_dbg_cb(const char *target, } + /* Internal function to print dispatcher internals - useful for testing */ void elapi_print_dispatcher(struct elapi_dispatcher *handle) { @@ -604,7 +649,17 @@ void elapi_print_dispatcher(struct elapi_dispatcher *handle) elapi_tgt_dbg_cb, NULL); } + printf("\n\nDeep sink inspection:\n\n"); + if (handle->sink_list) { + (void)col_traverse_collection(handle->sink_list, + COL_TRAVERSE_ONELEVEL, + elapi_sink_dbg_cb, + NULL); + } /* FIXME: Async data... */ printf("DISPATCHER END\n\n"); + fflush(stdout); } + +#endif |