diff --git a/src/Makefile_Eo.am b/src/Makefile_Eo.am index 2626f3f3b2..69c4466d1a 100644 --- a/src/Makefile_Eo.am +++ b/src/Makefile_Eo.am @@ -122,6 +122,8 @@ TESTS += tests/eo/test_constructors tests_eo_eo_suite_SOURCES = \ tests/eo/suite/eo_test_class_simple.c \ tests/eo/suite/eo_test_class_simple.h \ +tests/eo/suite/eo_test_class_singleton.c \ +tests/eo/suite/eo_test_class_singleton.h \ tests/eo/suite/eo_suite.c \ tests/eo/suite/eo_suite.h \ tests/eo/suite/eo_error_msgs.h \ diff --git a/src/lib/eo/eo.c b/src/lib/eo/eo.c index 88e22db8eb..c8039f4f94 100644 --- a/src/lib/eo/eo.c +++ b/src/lib/eo/eo.c @@ -683,10 +683,20 @@ _eo_add_internal_start(const char *file, int line, const Eo_Class *klass_id, Eo { ERR("Object of class '%s' - Error while constructing object", klass->desc->name); + + /* We have two refs at this point. */ _eo_unref(obj); _eo_unref(obj); return NULL; } + else if (eo_id != _eo_obj_id_get(obj)) + { + /* We have two refs at this point. */ + _eo_unref(obj); + _eo_unref(obj); + + eo_ref(eo_id); + } if (is_fallback) { diff --git a/src/tests/eo/suite/eo_test_class_singleton.c b/src/tests/eo/suite/eo_test_class_singleton.c new file mode 100644 index 0000000000..4898abc55f --- /dev/null +++ b/src/tests/eo/suite/eo_test_class_singleton.c @@ -0,0 +1,43 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "Eo.h" +#include "eo_test_class_singleton.h" +#include "eo_test_class_simple.h" + +#define MY_CLASS SINGLETON_CLASS + +static Eo *singleton_obj = NULL; + +static Eo * +_singleton_eo_constructor(Eo *eo_obj EINA_UNUSED, void *_pd EINA_UNUSED) +{ + if (!singleton_obj) + { + singleton_obj = eo_add(SIMPLE_CLASS, NULL); + } + else + { + eo_ref(singleton_obj); + } + + return singleton_obj; +} + +static Eo_Op_Description op_descs[] = { + EO_OP_FUNC_OVERRIDE(eo_constructor, _singleton_eo_constructor), +}; + +static const Eo_Class_Description class_desc = { + EO_VERSION, + "Singleton", + EO_CLASS_TYPE_REGULAR, + EO_CLASS_DESCRIPTION_OPS(op_descs), + NULL, + 0, + NULL, + NULL +}; + +EO_DEFINE_CLASS(singleton_class_get, &class_desc, EO_CLASS, NULL) diff --git a/src/tests/eo/suite/eo_test_class_singleton.h b/src/tests/eo/suite/eo_test_class_singleton.h new file mode 100644 index 0000000000..7aafb35cc5 --- /dev/null +++ b/src/tests/eo/suite/eo_test_class_singleton.h @@ -0,0 +1,7 @@ +#ifndef SINGLETON_H +#define SINGLETON_H + +#define SINGLETON_CLASS singleton_class_get() +const Eo_Class *singleton_class_get(void); + +#endif diff --git a/src/tests/eo/suite/eo_test_general.c b/src/tests/eo/suite/eo_test_general.c index a26c0d682b..959247d7de 100644 --- a/src/tests/eo/suite/eo_test_general.c +++ b/src/tests/eo/suite/eo_test_general.c @@ -10,6 +10,7 @@ #include "eo_suite.h" #include "eo_test_class_simple.h" +#include "eo_test_class_singleton.h" /* Loading this internal header for testing purposes. */ #include "eo_ptr_indirection.h" @@ -30,6 +31,25 @@ START_TEST(eo_simple) } END_TEST +START_TEST(eo_singleton) +{ + eo_init(); + + Eo *obj = eo_add(SINGLETON_CLASS, NULL); + fail_if(!obj); + + Eo *obj2 = eo_add(SINGLETON_CLASS, NULL); + fail_if(!obj2); + + ck_assert_ptr_eq(obj, obj2); + + eo_unref(obj); + eo_unref(obj2); + + eo_shutdown(); +} +END_TEST + START_TEST(eo_stack) { eo_init(); @@ -1171,6 +1191,7 @@ END_TEST void eo_test_general(TCase *tc) { tcase_add_test(tc, eo_simple); + tcase_add_test(tc, eo_singleton); tcase_add_test(tc, eo_stack); tcase_add_test(tc, eo_signals); tcase_add_test(tc, eo_data_fetch);