mirror of
https://gitlab.xiph.org/xiph/icecast-common.git
synced 2024-12-04 14:46:31 -05:00
Feature: Added support for a per-instance error value and per-instance logger
This commit is contained in:
parent
cfd7b94d56
commit
b7aa541794
@ -48,6 +48,71 @@ extern "C" {
|
||||
*/
|
||||
igloo_ro_t igloo_initialize(void);
|
||||
|
||||
/* Get per-instance error value
|
||||
*
|
||||
* Parameters:
|
||||
* self
|
||||
* An instance or any object that knows an instance.
|
||||
* result
|
||||
* Pointer to where to store the result.
|
||||
* Returns:
|
||||
* igloo_ERROR_NONE if successful or error code otherwise.
|
||||
*/
|
||||
igloo_error_t igloo_instance_get_error(igloo_ro_t self, igloo_error_t *result);
|
||||
/* Set per-instance error value
|
||||
*
|
||||
* Parameters:
|
||||
* self
|
||||
* An instance or any object that knows an instance.
|
||||
* error
|
||||
* The new error value.
|
||||
* Returns:
|
||||
* igloo_ERROR_NONE if successful or error code otherwise.
|
||||
*/
|
||||
igloo_error_t igloo_instance_set_error(igloo_ro_t self, igloo_error_t error);
|
||||
|
||||
/* Set per-instance logger
|
||||
*
|
||||
* Note: The instance will only hold a weak reference. So the caller must
|
||||
* ensure that there will be a strong reference somewhere else. Otherwise
|
||||
* the logger will be released.
|
||||
*
|
||||
* Parameters:
|
||||
* self
|
||||
* An instance or any object that knows an instance.
|
||||
* logger
|
||||
* The logger to use.
|
||||
* Returns:
|
||||
* igloo_ERROR_NONE if successful or error code otherwise.
|
||||
*/
|
||||
igloo_error_t igloo_instance_set_logger(igloo_ro_t self, igloo_objecthandler_t *logger);
|
||||
|
||||
/* Get per-instance logger
|
||||
*
|
||||
* Parameters:
|
||||
* self
|
||||
* An instance or any object that knows an instance.
|
||||
* Returns:
|
||||
* A strong reference to a logger or igloo_RO_NULL.
|
||||
*/
|
||||
igloo_objecthandler_t * igloo_instance_get_logger(igloo_ro_t self);
|
||||
|
||||
/* Log a message with per-instance logger
|
||||
*
|
||||
* Note: This is much faster than using igloo_instance_get_logger() and
|
||||
* using it's return value for single log messages. If you want to push many
|
||||
* messages use igloo_instance_get_logger() and igloo_list_forward().
|
||||
*
|
||||
* Parameters:
|
||||
* self
|
||||
* An instance or any object that knows an instance.
|
||||
* msg
|
||||
* The message to log.
|
||||
* Returns:
|
||||
* igloo_ERROR_NONE if successful or error code otherwise.
|
||||
*/
|
||||
igloo_error_t igloo_instance_log(igloo_ro_t self, igloo_ro_t msg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
151
src/libigloo.c
151
src/libigloo.c
@ -29,18 +29,31 @@ typedef struct igloo_instance_tag igloo_instance_t;
|
||||
|
||||
#include "../include/igloo/ro.h"
|
||||
#include "../include/igloo/error.h"
|
||||
#include "../include/igloo/objecthandler.h"
|
||||
#include "private.h"
|
||||
|
||||
struct igloo_instance_tag {
|
||||
igloo_ro_base_t __base;
|
||||
igloo_mutex_t lock;
|
||||
igloo_error_t error;
|
||||
igloo_objecthandler_t *logger;
|
||||
};
|
||||
|
||||
static size_t igloo_initialize__refc;
|
||||
static igloo_ro_t default_instance = igloo_RO_NULL;
|
||||
|
||||
|
||||
static void igloo_initialize__free(igloo_ro_t self);
|
||||
igloo_RO_PRIVATE_TYPE(igloo_instance_t,
|
||||
igloo_RO_TYPEDECL_FREE(igloo_initialize__free)
|
||||
);
|
||||
|
||||
/* Internal forwarding */
|
||||
const igloo_ro_type_t **igloo_instance_type = &igloo_ro__type__igloo_instance_t;
|
||||
|
||||
static void igloo_initialize__free(igloo_ro_t self)
|
||||
{
|
||||
igloo_instance_t *instance = igloo_RO_TO_TYPE(self, igloo_instance_t);
|
||||
|
||||
if (igloo_RO_IS_SAME(default_instance, self)) {
|
||||
/* This is hacky, but needed to avoid free-before-unlock. */
|
||||
@ -48,6 +61,12 @@ static void igloo_initialize__free(igloo_ro_t self)
|
||||
default_instance = igloo_RO_NULL;
|
||||
}
|
||||
|
||||
|
||||
igloo_thread_mutex_lock(&(instance->lock));
|
||||
igloo_ro_weak_unref(instance->logger);
|
||||
igloo_thread_mutex_unlock(&(instance->lock));
|
||||
igloo_thread_mutex_destroy(&(instance->lock));
|
||||
|
||||
igloo_initialize__refc--;
|
||||
if (igloo_initialize__refc)
|
||||
return;
|
||||
@ -58,13 +77,6 @@ static void igloo_initialize__free(igloo_ro_t self)
|
||||
igloo_log_shutdown();
|
||||
}
|
||||
|
||||
igloo_RO_PRIVATE_TYPE(igloo_instance_t,
|
||||
igloo_RO_TYPEDECL_FREE(igloo_initialize__free)
|
||||
);
|
||||
|
||||
/* Internal forwarding */
|
||||
const igloo_ro_type_t **igloo_instance_type = &igloo_ro__type__igloo_instance_t;
|
||||
|
||||
igloo_ro_t igloo_initialize(void)
|
||||
{
|
||||
igloo_instance_t *ret;
|
||||
@ -83,6 +95,8 @@ igloo_ro_t igloo_initialize(void)
|
||||
if (!ret)
|
||||
return igloo_RO_NULL;
|
||||
|
||||
igloo_thread_mutex_create(&(ret->lock));
|
||||
|
||||
igloo_initialize__refc++;
|
||||
|
||||
if (igloo_RO_IS_NULL(default_instance)) {
|
||||
@ -104,3 +118,126 @@ igloo_ro_t igloo_get_default_instance(void)
|
||||
|
||||
return default_instance;
|
||||
}
|
||||
|
||||
static igloo_instance_t * igloo_instance_get_instance(igloo_ro_t self)
|
||||
{
|
||||
igloo_instance_t *instance;
|
||||
|
||||
if (igloo_RO_IS_NULL(self))
|
||||
self = default_instance;
|
||||
|
||||
instance = igloo_RO_TO_TYPE(igloo_ro_get_instance(self), igloo_instance_t);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
igloo_error_t igloo_instance_get_error(igloo_ro_t self, igloo_error_t *result)
|
||||
{
|
||||
igloo_instance_t *instance = igloo_instance_get_instance(self);
|
||||
|
||||
if (!instance)
|
||||
return igloo_ERROR_GENERIC;
|
||||
|
||||
igloo_thread_mutex_lock(&(instance->lock));
|
||||
if (result)
|
||||
*result = instance->error;
|
||||
igloo_thread_mutex_unlock(&(instance->lock));
|
||||
|
||||
igloo_ro_unref(instance);
|
||||
|
||||
return igloo_ERROR_NONE;
|
||||
}
|
||||
|
||||
igloo_error_t igloo_instance_set_error(igloo_ro_t self, igloo_error_t error)
|
||||
{
|
||||
igloo_instance_t *instance = igloo_instance_get_instance(self);
|
||||
|
||||
if (!instance)
|
||||
return igloo_ERROR_GENERIC;
|
||||
|
||||
igloo_thread_mutex_lock(&(instance->lock));
|
||||
instance->error = error;
|
||||
igloo_thread_mutex_unlock(&(instance->lock));
|
||||
|
||||
igloo_ro_unref(instance);
|
||||
|
||||
return igloo_ERROR_NONE;
|
||||
}
|
||||
|
||||
igloo_error_t igloo_instance_set_logger(igloo_ro_t self, igloo_objecthandler_t *logger)
|
||||
{
|
||||
igloo_instance_t *instance;
|
||||
igloo_error_t ret;
|
||||
|
||||
if (!igloo_RO_IS_NULL(logger) && !igloo_RO_IS_VALID(logger, igloo_objecthandler_t))
|
||||
return igloo_ERROR_GENERIC;
|
||||
|
||||
instance = igloo_instance_get_instance(self);
|
||||
|
||||
if (!instance)
|
||||
return igloo_ERROR_GENERIC;
|
||||
|
||||
if (!igloo_RO_IS_NULL(logger)) {
|
||||
ret = igloo_ro_weak_ref(logger);
|
||||
if (ret != igloo_ERROR_NONE) {
|
||||
igloo_ro_unref(instance);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
igloo_thread_mutex_lock(&(instance->lock));
|
||||
igloo_ro_weak_unref(instance->logger);
|
||||
instance->logger = logger;
|
||||
igloo_thread_mutex_unlock(&(instance->lock));
|
||||
|
||||
igloo_ro_unref(instance);
|
||||
|
||||
return igloo_ERROR_NONE;
|
||||
}
|
||||
|
||||
igloo_objecthandler_t * igloo_instance_get_logger(igloo_ro_t self)
|
||||
{
|
||||
igloo_instance_t *instance = igloo_instance_get_instance(self);
|
||||
igloo_objecthandler_t *ret = NULL;
|
||||
|
||||
if (!instance)
|
||||
return NULL;
|
||||
|
||||
igloo_thread_mutex_lock(&(instance->lock));
|
||||
if (igloo_ro_ref(instance->logger) == igloo_ERROR_NONE) {
|
||||
ret = instance->logger;
|
||||
}
|
||||
igloo_thread_mutex_unlock(&(instance->lock));
|
||||
|
||||
igloo_ro_unref(instance);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
igloo_error_t igloo_instance_log(igloo_ro_t self, igloo_ro_t msg)
|
||||
{
|
||||
igloo_instance_t *instance = igloo_instance_get_instance(self);
|
||||
igloo_error_t ret;
|
||||
|
||||
if (!instance)
|
||||
return igloo_ERROR_FAULT;
|
||||
|
||||
igloo_thread_mutex_lock(&(instance->lock));
|
||||
switch (igloo_objecthandler_handle(instance->logger, msg)) {
|
||||
case igloo_FILTER_RESULT_PASS:
|
||||
ret = igloo_ERROR_NONE;
|
||||
break;
|
||||
case igloo_FILTER_RESULT_DROP:
|
||||
ret = igloo_ERROR_GENERIC;
|
||||
break;
|
||||
case igloo_FILTER_RESULT_ERROR:
|
||||
default:
|
||||
ret = igloo_ERROR_GENERIC;
|
||||
break;
|
||||
}
|
||||
igloo_thread_mutex_unlock(&(instance->lock));
|
||||
|
||||
igloo_ro_unref(instance);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user