From bc46e9c97600b6bda89f5f61eab9db338e7d5e10 Mon Sep 17 00:00:00 2001 From: Philipp Schafft Date: Sat, 14 Sep 2019 19:47:26 +0000 Subject: [PATCH] Feature: support passing any object as instance and asking an instance for itself --- src/libigloo.c | 3 +++ src/private.h | 4 ++++ src/ro.c | 19 +++++++++++++++---- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/libigloo.c b/src/libigloo.c index 863a34d..94be2d0 100644 --- a/src/libigloo.c +++ b/src/libigloo.c @@ -52,6 +52,9 @@ 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; diff --git a/src/private.h b/src/private.h index 2751c23..eb6ebad 100644 --- a/src/private.h +++ b/src/private.h @@ -36,6 +36,10 @@ void igloo_resolver_shutdown(void); void igloo_log_initialize(void); void igloo_log_shutdown(void); +/* Instance type internal forwarding */ +const igloo_ro_type_t **igloo_instance_type; +#define igloo_IS_INSTANCE(x) (igloo_RO_GET_TYPE((x)) == *igloo_instance_type) + /* Basic interface */ #define igloo_interface_base(type) \ /* The base object. */ \ diff --git a/src/ro.c b/src/ro.c index 14ef69e..7b9e62e 100644 --- a/src/ro.c +++ b/src/ro.c @@ -102,9 +102,14 @@ igloo_ro_t igloo_ro_new__raw(const igloo_ro_type_t *type, const char *name, } if (!igloo_RO_IS_NULL(instance)) { - if (igloo_ro_ref(instance) != igloo_ERROR_NONE) { - igloo_ro_unref(base); - return igloo_RO_NULL; + if (!igloo_IS_INSTANCE(instance)) { + /* In this case we're fine if this returns igloo_RO_NULL. */ + instance = igloo_ro_get_instance(instance); + } else { + if (igloo_ro_ref(instance) != igloo_ERROR_NONE) { + igloo_ro_unref(base); + return igloo_RO_NULL; + } } base->instance = instance; @@ -335,7 +340,13 @@ igloo_ro_t igloo_ro_get_instance(igloo_ro_t self) igloo_thread_mutex_unlock(&(base->lock)); return igloo_RO_NULL; } - ret = base->instance; + + if (igloo_IS_INSTANCE(base)) { + ret = (igloo_ro_t)base; + } else { + ret = base->instance; + } + if (!igloo_RO_IS_NULL(ret)) { if (igloo_ro_ref(ret) != igloo_ERROR_NONE) { igloo_thread_mutex_unlock(&(base->lock));