forked from enlightenment/efl
Eo: Added eo_manual_free* funcs.
Patch by Daniel Zaoui. SVN revision: 71281
This commit is contained in:
parent
510cada94b
commit
bff3911c08
|
@ -749,7 +749,35 @@ EAPI void eo_composite_object_detach(Eo *obj, Eo *comp_obj);
|
|||
* @see eo_composite_object_attach()
|
||||
* @see eo_composite_object_detach()
|
||||
*/
|
||||
EAPI Eina_Bool eo_composite_is(Eo *comp_obj);
|
||||
EAPI Eina_Bool eo_composite_is(const Eo *comp_obj);
|
||||
|
||||
/**
|
||||
* @brief Enable or disable the manual free feature.
|
||||
* @param obj the object to work on.
|
||||
* @param manual_free indicates if the free is manual (EINA_TRUE) or automatic (EINA_FALSE).
|
||||
*
|
||||
* The developer is in charge to call the function eo_manual_free to free the memory allocated for this object.
|
||||
*
|
||||
* Do not use, unless you really know what you are doing. It's used by Evas
|
||||
* because evas wants to keep its private data available even after the object
|
||||
* is deleted. Setting this to true makes Eo destruct the object but not free
|
||||
* the private data or the object itself.
|
||||
*
|
||||
* @see eo_manual_free()
|
||||
*/
|
||||
EAPI void eo_manual_free_set(Eo *obj, Eina_Bool manual_free);
|
||||
|
||||
/**
|
||||
* @brief Frees the object.
|
||||
* @param obj the object to work on.
|
||||
* This function must be called by the developer if the function
|
||||
* eo_manual_free_set has been called before with the parameter EINA_TRUE.
|
||||
* An error will be printed if this function is called when the manual
|
||||
* free option is not set to EINA_TRUE or the number of refs is not 0.
|
||||
*
|
||||
* @see eo_manual_free_set()
|
||||
*/
|
||||
EAPI void eo_manual_free(Eo *obj);
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
|
|
@ -44,6 +44,7 @@ struct _Eo {
|
|||
|
||||
Eina_Bool del:1;
|
||||
Eina_Bool construct_error:1;
|
||||
Eina_Bool manual_free:1;
|
||||
};
|
||||
|
||||
/* Start of Dich */
|
||||
|
@ -1193,6 +1194,13 @@ _eo_del_internal(Eo *obj)
|
|||
obj->refcount--;
|
||||
}
|
||||
|
||||
static inline void
|
||||
_eo_free(Eo *obj)
|
||||
{
|
||||
EINA_MAGIC_SET(obj, EO_DELETED_EINA_MAGIC);
|
||||
free(obj);
|
||||
}
|
||||
|
||||
static inline void
|
||||
_eo_unref(Eo *obj)
|
||||
{
|
||||
|
@ -1211,8 +1219,7 @@ _eo_unref(Eo *obj)
|
|||
}
|
||||
#endif
|
||||
|
||||
EINA_MAGIC_SET(obj, EO_DELETED_EINA_MAGIC);
|
||||
free(obj);
|
||||
if (!obj->manual_free) _eo_free(obj);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1466,7 +1473,7 @@ eo_composite_object_detach(Eo *obj, Eo *emb_obj)
|
|||
}
|
||||
|
||||
EAPI Eina_Bool
|
||||
eo_composite_is(Eo *emb_obj)
|
||||
eo_composite_is(const Eo *emb_obj)
|
||||
{
|
||||
if (!EINA_MAGIC_CHECK(emb_obj, EO_EINA_MAGIC))
|
||||
{
|
||||
|
@ -1490,4 +1497,30 @@ eo_composite_is(Eo *emb_obj)
|
|||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
eo_manual_free_set(Eo *obj, Eina_Bool manual_free)
|
||||
{
|
||||
EO_MAGIC_RETURN(obj, EO_EINA_MAGIC);
|
||||
obj->manual_free = manual_free;
|
||||
}
|
||||
|
||||
EAPI void
|
||||
eo_manual_free(Eo *obj)
|
||||
{
|
||||
EO_MAGIC_RETURN(obj, EO_EINA_MAGIC);
|
||||
|
||||
if (EINA_FALSE == obj->manual_free)
|
||||
{
|
||||
ERR("Tried to free manually the object %p while the option has not been set; see eo_manual_free_set for more information.", obj);
|
||||
return;
|
||||
}
|
||||
|
||||
if (0 != obj->refcount)
|
||||
{
|
||||
ERR("Tried deleting the object %p while still referenced(%d).", obj, eo_ref_get(obj));
|
||||
return;
|
||||
}
|
||||
|
||||
_eo_free(obj);
|
||||
}
|
||||
|
||||
|
|
|
@ -59,6 +59,76 @@ START_TEST(eo_data_fetch)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
static void
|
||||
_man_con(Eo *obj, void *data EINA_UNUSED)
|
||||
{
|
||||
eo_manual_free_set(obj, EINA_TRUE);
|
||||
eo_constructor_super(obj);
|
||||
}
|
||||
|
||||
static void
|
||||
_man_des(Eo *obj, void *data EINA_UNUSED)
|
||||
{
|
||||
eo_destructor_super(obj);
|
||||
eo_manual_free_set(obj, EINA_FALSE);
|
||||
}
|
||||
|
||||
START_TEST(eo_man_free)
|
||||
{
|
||||
eo_init();
|
||||
|
||||
/* Usually should be const, not const only for the test... */
|
||||
static Eo_Class_Description class_desc = {
|
||||
"Simple2",
|
||||
EO_CLASS_TYPE_REGULAR,
|
||||
EO_CLASS_DESCRIPTION_OPS(NULL, NULL, 0),
|
||||
NULL,
|
||||
10,
|
||||
_man_con,
|
||||
_man_des,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
const Eo_Class *klass = eo_class_new(&class_desc, EO_BASE_CLASS, NULL);
|
||||
fail_if(!klass);
|
||||
|
||||
Eo *obj = eo_add(klass, NULL);
|
||||
fail_if(!obj);
|
||||
eo_unref(obj);
|
||||
|
||||
obj = eo_add(klass, NULL);
|
||||
fail_if(!obj);
|
||||
eo_manual_free(obj);
|
||||
eo_unref(obj);
|
||||
|
||||
class_desc.destructor = NULL;
|
||||
klass = eo_class_new(&class_desc, EO_BASE_CLASS, NULL);
|
||||
fail_if(!klass);
|
||||
|
||||
obj = eo_add(klass, NULL);
|
||||
fail_if(!obj);
|
||||
eo_manual_free(obj);
|
||||
eo_unref(obj);
|
||||
|
||||
obj = eo_add(klass, NULL);
|
||||
fail_if(!obj);
|
||||
eo_unref(obj);
|
||||
eo_manual_free(obj);
|
||||
|
||||
class_desc.constructor = NULL;
|
||||
klass = eo_class_new(&class_desc, EO_BASE_CLASS, NULL);
|
||||
fail_if(!klass);
|
||||
|
||||
obj = eo_add(klass, NULL);
|
||||
fail_if(!obj);
|
||||
eo_manual_free(obj);
|
||||
eo_unref(obj);
|
||||
|
||||
eo_shutdown();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(eo_refs)
|
||||
{
|
||||
eo_init();
|
||||
|
@ -371,6 +441,11 @@ START_TEST(eo_magic_checks)
|
|||
eo_do(obj, eo_event_callback_forwarder_add(NULL, (Eo *) buf));
|
||||
eo_do(obj, eo_event_callback_forwarder_del(NULL, (Eo *) buf));
|
||||
|
||||
eo_manual_free_set((Eo *) buf, EINA_TRUE);
|
||||
eo_manual_free((Eo *) buf);
|
||||
eo_manual_free_set(NULL, EINA_TRUE);
|
||||
eo_manual_free(NULL);
|
||||
|
||||
eo_unref(obj);
|
||||
|
||||
eo_shutdown();
|
||||
|
@ -386,4 +461,5 @@ void eo_test_general(TCase *tc)
|
|||
tcase_add_test(tc, eo_refs);
|
||||
tcase_add_test(tc, eo_magic_checks);
|
||||
tcase_add_test(tc, eo_data_fetch);
|
||||
tcase_add_test(tc, eo_man_free);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue