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_attach()
|
||||||
* @see eo_composite_object_detach()
|
* @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 del:1;
|
||||||
Eina_Bool construct_error:1;
|
Eina_Bool construct_error:1;
|
||||||
|
Eina_Bool manual_free:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Start of Dich */
|
/* Start of Dich */
|
||||||
|
@ -1193,6 +1194,13 @@ _eo_del_internal(Eo *obj)
|
||||||
obj->refcount--;
|
obj->refcount--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
_eo_free(Eo *obj)
|
||||||
|
{
|
||||||
|
EINA_MAGIC_SET(obj, EO_DELETED_EINA_MAGIC);
|
||||||
|
free(obj);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
_eo_unref(Eo *obj)
|
_eo_unref(Eo *obj)
|
||||||
{
|
{
|
||||||
|
@ -1201,18 +1209,17 @@ _eo_unref(Eo *obj)
|
||||||
_eo_del_internal(obj);
|
_eo_del_internal(obj);
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
/* If for some reason it's not empty, clear it. */
|
/* If for some reason it's not empty, clear it. */
|
||||||
while (obj->xrefs)
|
while (obj->xrefs)
|
||||||
{
|
{
|
||||||
WRN("obj->xrefs is not empty, possibly a bug, please report. - An error will be reported for each xref in the stack.");
|
WRN("obj->xrefs is not empty, possibly a bug, please report. - An error will be reported for each xref in the stack.");
|
||||||
Eina_Inlist *nitr = obj->xrefs->next;
|
Eina_Inlist *nitr = obj->xrefs->next;
|
||||||
free(EINA_INLIST_CONTAINER_GET(obj->xrefs, Eo_Xref_Node));
|
free(EINA_INLIST_CONTAINER_GET(obj->xrefs, Eo_Xref_Node));
|
||||||
obj->xrefs = nitr;
|
obj->xrefs = nitr;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EINA_MAGIC_SET(obj, EO_DELETED_EINA_MAGIC);
|
if (!obj->manual_free) _eo_free(obj);
|
||||||
free(obj);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1466,7 +1473,7 @@ eo_composite_object_detach(Eo *obj, Eo *emb_obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
EAPI Eina_Bool
|
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))
|
if (!EINA_MAGIC_CHECK(emb_obj, EO_EINA_MAGIC))
|
||||||
{
|
{
|
||||||
|
@ -1490,4 +1497,30 @@ eo_composite_is(Eo *emb_obj)
|
||||||
return EINA_FALSE;
|
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
|
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)
|
START_TEST(eo_refs)
|
||||||
{
|
{
|
||||||
eo_init();
|
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_add(NULL, (Eo *) buf));
|
||||||
eo_do(obj, eo_event_callback_forwarder_del(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_unref(obj);
|
||||||
|
|
||||||
eo_shutdown();
|
eo_shutdown();
|
||||||
|
@ -386,4 +461,5 @@ void eo_test_general(TCase *tc)
|
||||||
tcase_add_test(tc, eo_refs);
|
tcase_add_test(tc, eo_refs);
|
||||||
tcase_add_test(tc, eo_magic_checks);
|
tcase_add_test(tc, eo_magic_checks);
|
||||||
tcase_add_test(tc, eo_data_fetch);
|
tcase_add_test(tc, eo_data_fetch);
|
||||||
|
tcase_add_test(tc, eo_man_free);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue