2012-05-01 00:40:14 -07:00
|
|
|
#ifndef _EO_PRIVATE_H
|
|
|
|
#define _EO_PRIVATE_H
|
|
|
|
|
2014-09-25 07:51:17 -07:00
|
|
|
#include <Eo.h>
|
2013-09-27 04:10:43 -07:00
|
|
|
#include <Eina.h>
|
|
|
|
|
2012-06-05 05:05:06 -07:00
|
|
|
#define EO_EINA_MAGIC 0xa186bc32
|
2012-05-14 00:35:19 -07:00
|
|
|
#define EO_EINA_MAGIC_STR "Eo"
|
2012-06-05 05:05:06 -07:00
|
|
|
#define EO_FREED_EINA_MAGIC 0xa186bb32
|
|
|
|
#define EO_FREED_EINA_MAGIC_STR "Eo - Freed object"
|
|
|
|
#define EO_CLASS_EINA_MAGIC 0xa186ba32
|
2016-08-09 06:10:05 -07:00
|
|
|
#define EO_CLASS_EINA_MAGIC_STR "Efl Class"
|
2012-05-14 00:35:19 -07:00
|
|
|
|
|
|
|
#define EO_MAGIC_RETURN_VAL(d, magic, ret) \
|
|
|
|
do { \
|
|
|
|
if (!EINA_MAGIC_CHECK(d, magic)) \
|
|
|
|
{ \
|
|
|
|
EINA_MAGIC_FAIL(d, magic); \
|
|
|
|
return ret; \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
#define EO_MAGIC_RETURN(d, magic) \
|
|
|
|
do { \
|
|
|
|
if (!EINA_MAGIC_CHECK(d, magic)) \
|
|
|
|
{ \
|
|
|
|
EINA_MAGIC_FAIL(d, magic); \
|
|
|
|
return; \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
|
2012-05-01 00:40:14 -07:00
|
|
|
extern int _eo_log_dom;
|
|
|
|
|
2013-12-25 19:22:05 -08:00
|
|
|
#ifdef CRI
|
|
|
|
#undef CRI
|
2012-05-01 00:40:14 -07:00
|
|
|
#endif
|
2013-12-25 19:22:05 -08:00
|
|
|
#define CRI(...) EINA_LOG_DOM_CRIT(_eo_log_dom, __VA_ARGS__)
|
2012-05-01 00:40:14 -07:00
|
|
|
|
|
|
|
#ifdef ERR
|
|
|
|
#undef ERR
|
|
|
|
#endif
|
|
|
|
#define ERR(...) EINA_LOG_DOM_ERR(_eo_log_dom, __VA_ARGS__)
|
|
|
|
|
|
|
|
#ifdef WRN
|
|
|
|
#undef WRN
|
|
|
|
#endif
|
|
|
|
#define WRN(...) EINA_LOG_DOM_WARN(_eo_log_dom, __VA_ARGS__)
|
|
|
|
|
|
|
|
#ifdef INF
|
|
|
|
#undef INF
|
|
|
|
#endif
|
|
|
|
#define INF(...) EINA_LOG_DOM_INFO(_eo_log_dom, __VA_ARGS__)
|
|
|
|
|
|
|
|
#ifdef DBG
|
|
|
|
#undef DBG
|
|
|
|
#endif
|
|
|
|
#define DBG(...) EINA_LOG_DOM_DBG(_eo_log_dom, __VA_ARGS__)
|
|
|
|
|
2013-09-18 13:05:26 -07:00
|
|
|
typedef uintptr_t Eo_Id;
|
2016-08-10 07:23:04 -07:00
|
|
|
typedef struct _Efl_Class _Efl_Class;
|
2015-05-28 08:49:13 -07:00
|
|
|
typedef struct _Eo_Header Eo_Header;
|
2013-06-27 01:58:49 -07:00
|
|
|
|
|
|
|
/* Retrieves the pointer to the object from the id */
|
2013-09-26 14:31:39 -07:00
|
|
|
static inline _Eo_Object *_eo_obj_pointer_get(const Eo_Id obj_id);
|
2013-06-27 01:58:49 -07:00
|
|
|
|
|
|
|
/* Allocates an entry for the given object */
|
2013-09-26 14:31:39 -07:00
|
|
|
static inline Eo_Id _eo_id_allocate(const _Eo_Object *obj);
|
2013-06-27 01:58:49 -07:00
|
|
|
|
|
|
|
/* Releases an entry by the object id */
|
2013-07-01 01:09:02 -07:00
|
|
|
static inline void _eo_id_release(const Eo_Id obj_id);
|
2013-06-27 01:58:49 -07:00
|
|
|
|
|
|
|
/* Free all the entries and the tables */
|
2013-07-01 01:09:02 -07:00
|
|
|
static inline void _eo_free_ids_tables(void);
|
2013-06-27 01:58:49 -07:00
|
|
|
|
2012-06-10 07:04:53 -07:00
|
|
|
void _eo_condtor_done(Eo *obj);
|
|
|
|
|
2016-05-18 10:12:39 -07:00
|
|
|
typedef struct _Dich_Chain1 Dich_Chain1;
|
|
|
|
|
|
|
|
typedef struct _Eo_Vtable
|
|
|
|
{
|
|
|
|
Dich_Chain1 *chain;
|
|
|
|
unsigned int size;
|
|
|
|
} Eo_Vtable;
|
|
|
|
|
2016-05-19 03:33:17 -07:00
|
|
|
/* Clean the vtable. */
|
|
|
|
void _vtable_func_clean_all(Eo_Vtable *vtable);
|
|
|
|
|
2015-05-28 08:49:13 -07:00
|
|
|
struct _Eo_Header
|
2013-09-27 02:59:41 -07:00
|
|
|
{
|
2013-06-27 01:58:49 -07:00
|
|
|
#ifndef HAVE_EO_ID
|
|
|
|
EINA_MAGIC
|
|
|
|
#endif
|
2013-09-27 02:59:41 -07:00
|
|
|
Eo_Id id;
|
|
|
|
};
|
2013-09-27 02:50:06 -07:00
|
|
|
|
2013-09-27 02:59:41 -07:00
|
|
|
struct _Eo_Object
|
|
|
|
{
|
2015-05-28 08:49:13 -07:00
|
|
|
Eo_Header header;
|
2016-05-17 02:25:31 -07:00
|
|
|
EINA_INLIST;
|
2016-08-09 06:10:05 -07:00
|
|
|
const _Efl_Class *klass;
|
2013-06-27 01:58:49 -07:00
|
|
|
#ifdef EO_DEBUG
|
|
|
|
Eina_Inlist *xrefs;
|
|
|
|
Eina_Inlist *data_xrefs;
|
|
|
|
#endif
|
|
|
|
|
2016-05-18 10:12:39 -07:00
|
|
|
Eo_Vtable *vtable;
|
|
|
|
|
2014-06-13 10:09:56 -07:00
|
|
|
Eina_List *composite_objects;
|
2016-08-15 06:44:41 -07:00
|
|
|
Efl_Del_Intercept del_intercept;
|
2013-06-27 01:58:49 -07:00
|
|
|
|
2016-05-17 01:39:12 -07:00
|
|
|
short refcount;
|
2016-07-12 02:26:23 -07:00
|
|
|
short user_refcount;
|
2016-05-18 07:02:09 -07:00
|
|
|
#ifdef EO_DEBUG
|
2016-05-17 01:39:12 -07:00
|
|
|
short datarefcount;
|
2016-05-18 07:02:09 -07:00
|
|
|
#endif
|
2013-06-27 01:58:49 -07:00
|
|
|
|
|
|
|
Eina_Bool condtor_done:1;
|
2014-08-29 01:55:02 -07:00
|
|
|
Eina_Bool finalized:1;
|
2013-06-27 01:58:49 -07:00
|
|
|
|
2014-11-18 07:24:39 -08:00
|
|
|
Eina_Bool del_triggered:1;
|
|
|
|
Eina_Bool destructed:1;
|
2013-06-27 01:58:49 -07:00
|
|
|
Eina_Bool manual_free:1;
|
|
|
|
};
|
|
|
|
|
2016-08-15 09:11:13 -07:00
|
|
|
/* How we search and store the implementations in classes. */
|
|
|
|
#define DICH_CHAIN_LAST_BITS 5
|
|
|
|
#define DICH_CHAIN_LAST_SIZE (1 << DICH_CHAIN_LAST_BITS)
|
|
|
|
#define DICH_CHAIN1(x) ((x) >> DICH_CHAIN_LAST_BITS)
|
|
|
|
#define DICH_CHAIN_LAST(x) ((x) & ((1 << DICH_CHAIN_LAST_BITS) - 1))
|
|
|
|
|
2016-08-16 08:28:33 -07:00
|
|
|
typedef void (*Eo_Op_Func_Type)(Eo *, void *class_data);
|
2014-04-02 01:26:45 -07:00
|
|
|
|
2013-06-27 01:58:49 -07:00
|
|
|
typedef struct
|
|
|
|
{
|
2016-08-16 08:28:33 -07:00
|
|
|
Eo_Op_Func_Type func;
|
2016-08-09 06:10:05 -07:00
|
|
|
const _Efl_Class *src;
|
2013-06-27 01:58:49 -07:00
|
|
|
} op_type_funcs;
|
|
|
|
|
2016-08-15 09:11:13 -07:00
|
|
|
typedef struct _Dich_Chain2
|
|
|
|
{
|
|
|
|
op_type_funcs funcs[DICH_CHAIN_LAST_SIZE];
|
|
|
|
unsigned short refcount;
|
|
|
|
} Dich_Chain2;
|
|
|
|
|
2013-06-27 01:58:49 -07:00
|
|
|
struct _Dich_Chain1
|
|
|
|
{
|
2016-08-15 09:11:13 -07:00
|
|
|
Dich_Chain2 *chain2;
|
2013-06-27 01:58:49 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
2016-08-09 06:10:05 -07:00
|
|
|
const _Efl_Class *klass;
|
2013-06-27 01:58:49 -07:00
|
|
|
size_t offset;
|
|
|
|
} Eo_Extension_Data_Offset;
|
|
|
|
|
2016-08-09 06:10:05 -07:00
|
|
|
struct _Efl_Class
|
2013-06-27 01:58:49 -07:00
|
|
|
{
|
2015-05-28 08:49:13 -07:00
|
|
|
Eo_Header header;
|
2013-09-27 02:50:06 -07:00
|
|
|
|
2016-08-09 06:10:05 -07:00
|
|
|
const _Efl_Class *parent;
|
|
|
|
const Efl_Class_Description *desc;
|
2016-05-18 10:12:39 -07:00
|
|
|
Eo_Vtable vtable;
|
2013-06-27 01:58:49 -07:00
|
|
|
|
2016-08-09 06:10:05 -07:00
|
|
|
const _Efl_Class **extensions;
|
2013-06-27 01:58:49 -07:00
|
|
|
|
|
|
|
Eo_Extension_Data_Offset *extn_data_off;
|
|
|
|
|
2016-08-09 06:10:05 -07:00
|
|
|
const _Efl_Class **mro;
|
2013-06-27 01:58:49 -07:00
|
|
|
|
2013-09-10 19:23:50 -07:00
|
|
|
/* cached object for faster allocation */
|
2013-09-11 00:08:06 -07:00
|
|
|
struct {
|
|
|
|
Eina_Trash *trash;
|
2013-10-10 01:26:02 -07:00
|
|
|
Eina_Spinlock trash_lock;
|
2013-09-11 00:08:06 -07:00
|
|
|
unsigned int trash_count;
|
|
|
|
} objects;
|
|
|
|
|
|
|
|
/* cached iterator for faster allocation cycle */
|
|
|
|
struct {
|
2013-10-10 01:26:02 -07:00
|
|
|
Eina_Trash *trash;
|
|
|
|
Eina_Spinlock trash_lock;
|
|
|
|
unsigned int trash_count;
|
2013-09-11 00:08:06 -07:00
|
|
|
} iterators;
|
2013-09-10 19:23:50 -07:00
|
|
|
|
2013-06-27 01:58:49 -07:00
|
|
|
unsigned int obj_size; /**< size of an object of this class */
|
|
|
|
unsigned int base_id;
|
|
|
|
unsigned int data_offset; /* < Offset of the data within object data. */
|
Efl object: change the way we set class's functions.
This is another follow up to the investigations of T4227. As stated
there, in any PIE (a shared library is one), structures, even const ones
end up being written to because of dynamic relocation. This means that
using static const structures has actually lead to no savings, only
waste. Since we never really needed them, using them made things even
worse than just having a different API that doesn't save them.
Thus, this commit changes the way we set the functions. Instead of
passing a pre-populated struct, we now just have an initialiser function
where you set the functions. This on its own doesn't significantly reduce
the amount of dirty memory pages for a reason I have yet to uncover,
though I believe it's done as a misguided compiler optimisation.
However, this design is flexible enough so we can change to another one
that is quite ugly, but I have already tested and proven that does that.
This patch series doesn't include the better improvement (passing
everything on the stack as va_args) because the API was too ugly
for me to bear, and I would rather first make sure there is no way to
force the compiler to do the right thing here.
Unfortunately this commit gives up on useless stricter validation.
Before this commit we would make sure that we are only overriding
functions correctly defined in our hierarchy. With this one, we don't
anymore. This is not a big problem though because this is a check that
is also enforced by Eolian. So as long as you are using Eolian, you
should be fine.
Breaks API and ABI!
@feature
2016-08-24 07:59:28 -07:00
|
|
|
unsigned int ops_count; /* < Offset of the data within object data. */
|
2013-06-27 01:58:49 -07:00
|
|
|
|
|
|
|
Eina_Bool constructed : 1;
|
Efl object: change the way we set class's functions.
This is another follow up to the investigations of T4227. As stated
there, in any PIE (a shared library is one), structures, even const ones
end up being written to because of dynamic relocation. This means that
using static const structures has actually lead to no savings, only
waste. Since we never really needed them, using them made things even
worse than just having a different API that doesn't save them.
Thus, this commit changes the way we set the functions. Instead of
passing a pre-populated struct, we now just have an initialiser function
where you set the functions. This on its own doesn't significantly reduce
the amount of dirty memory pages for a reason I have yet to uncover,
though I believe it's done as a misguided compiler optimisation.
However, this design is flexible enough so we can change to another one
that is quite ugly, but I have already tested and proven that does that.
This patch series doesn't include the better improvement (passing
everything on the stack as va_args) because the API was too ugly
for me to bear, and I would rather first make sure there is no way to
force the compiler to do the right thing here.
Unfortunately this commit gives up on useless stricter validation.
Before this commit we would make sure that we are only overriding
functions correctly defined in our hierarchy. With this one, we don't
anymore. This is not a big problem though because this is a check that
is also enforced by Eolian. So as long as you are using Eolian, you
should be fine.
Breaks API and ABI!
@feature
2016-08-24 07:59:28 -07:00
|
|
|
Eina_Bool functions_set : 1;
|
2013-06-27 01:58:49 -07:00
|
|
|
/* [extensions*] + NULL */
|
|
|
|
/* [mro*] + NULL */
|
|
|
|
/* [extensions data offset] + NULL */
|
|
|
|
};
|
|
|
|
|
2013-09-23 02:07:07 -07:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
EINA_INLIST;
|
|
|
|
const Eo *ref_obj;
|
|
|
|
const char *file;
|
|
|
|
int line;
|
|
|
|
} Eo_Xref_Node;
|
|
|
|
|
2013-09-27 03:13:14 -07:00
|
|
|
static inline
|
2015-05-28 08:49:13 -07:00
|
|
|
Eo *_eo_header_id_get(const Eo_Header *header)
|
2013-09-27 03:13:14 -07:00
|
|
|
{
|
|
|
|
#ifdef HAVE_EO_ID
|
|
|
|
return (Eo *) header->id;
|
|
|
|
#else
|
|
|
|
return (Eo *) header;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline
|
2016-08-10 07:23:04 -07:00
|
|
|
Efl_Class *_eo_class_id_get(const _Efl_Class *klass)
|
2013-09-27 03:13:14 -07:00
|
|
|
{
|
2015-05-28 08:49:13 -07:00
|
|
|
return _eo_header_id_get((Eo_Header *) klass);
|
2013-09-27 03:13:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline
|
2016-05-17 02:29:14 -07:00
|
|
|
Eo *_eo_obj_id_get(const _Eo_Object *obj)
|
2013-09-27 03:13:14 -07:00
|
|
|
{
|
2015-05-28 08:49:13 -07:00
|
|
|
return _eo_header_id_get((Eo_Header *) obj);
|
2013-09-27 03:13:14 -07:00
|
|
|
}
|
|
|
|
|
2013-06-27 01:58:49 -07:00
|
|
|
static inline void
|
2013-09-26 14:31:39 -07:00
|
|
|
_eo_condtor_reset(_Eo_Object *obj)
|
2013-06-27 01:58:49 -07:00
|
|
|
{
|
|
|
|
obj->condtor_done = EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
2016-08-09 06:10:05 -07:00
|
|
|
_efl_del_internal(const char *file, int line, _Eo_Object *obj)
|
2013-06-27 01:58:49 -07:00
|
|
|
{
|
|
|
|
/* We need that for the event callbacks that may ref/unref. */
|
|
|
|
obj->refcount++;
|
|
|
|
|
2016-08-09 06:10:05 -07:00
|
|
|
const _Efl_Class *klass = obj->klass;
|
2013-06-27 01:58:49 -07:00
|
|
|
|
2016-08-09 06:10:05 -07:00
|
|
|
efl_event_callback_call(_eo_obj_id_get(obj), EFL_EVENT_DEL, NULL);
|
2013-12-25 07:13:14 -08:00
|
|
|
|
2013-06-27 01:58:49 -07:00
|
|
|
_eo_condtor_reset(obj);
|
|
|
|
|
2016-08-09 06:10:05 -07:00
|
|
|
efl_destructor(_eo_obj_id_get(obj));
|
2013-12-25 07:13:14 -08:00
|
|
|
|
2013-06-27 01:58:49 -07:00
|
|
|
if (!obj->condtor_done)
|
|
|
|
{
|
|
|
|
ERR("in %s:%d: Object of class '%s' - Not all of the object destructors have been executed.",
|
|
|
|
file, line, klass->desc->name);
|
|
|
|
}
|
|
|
|
/*FIXME: add eo_class_unref(klass) ? - just to clear the caches. */
|
|
|
|
|
|
|
|
{
|
2014-06-13 10:09:56 -07:00
|
|
|
Eina_List *itr, *itr_n;
|
|
|
|
Eo *emb_obj;
|
|
|
|
EINA_LIST_FOREACH_SAFE(obj->composite_objects, itr, itr_n, emb_obj)
|
2013-06-27 01:58:49 -07:00
|
|
|
{
|
2016-08-09 06:10:05 -07:00
|
|
|
efl_composite_detach(_eo_obj_id_get(obj), emb_obj);
|
2013-06-27 01:58:49 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-18 07:24:39 -08:00
|
|
|
obj->destructed = EINA_TRUE;
|
2013-06-27 01:58:49 -07:00
|
|
|
obj->refcount--;
|
|
|
|
}
|
|
|
|
|
2016-05-19 03:33:17 -07:00
|
|
|
static inline Eina_Bool
|
|
|
|
_obj_is_override(_Eo_Object *obj)
|
|
|
|
{
|
|
|
|
return (obj->vtable != &obj->klass->vtable);
|
|
|
|
}
|
|
|
|
|
2013-06-27 01:58:49 -07:00
|
|
|
static inline void
|
2013-09-26 14:31:39 -07:00
|
|
|
_eo_free(_Eo_Object *obj)
|
2013-06-27 01:58:49 -07:00
|
|
|
{
|
2016-08-10 07:23:04 -07:00
|
|
|
_Efl_Class *klass = (_Efl_Class*) obj->klass;
|
2013-09-10 19:23:50 -07:00
|
|
|
|
2016-02-18 11:28:41 -08:00
|
|
|
#ifdef EO_DEBUG
|
2013-06-27 01:58:49 -07:00
|
|
|
if (obj->datarefcount)
|
|
|
|
{
|
|
|
|
ERR("Object %p data still referenced %d time(s).", obj, obj->datarefcount);
|
|
|
|
}
|
2016-02-18 11:28:41 -08:00
|
|
|
#endif
|
2016-05-19 03:33:17 -07:00
|
|
|
if (_obj_is_override(obj))
|
|
|
|
{
|
|
|
|
_vtable_func_clean_all(obj->vtable);
|
|
|
|
free(obj->vtable);
|
|
|
|
obj->vtable = &klass->vtable;
|
|
|
|
}
|
|
|
|
|
2016-05-17 02:29:14 -07:00
|
|
|
_eo_id_release((Eo_Id) _eo_obj_id_get(obj));
|
2013-09-10 19:23:50 -07:00
|
|
|
|
2013-10-10 01:26:02 -07:00
|
|
|
eina_spinlock_take(&klass->objects.trash_lock);
|
2013-09-11 00:08:06 -07:00
|
|
|
if (klass->objects.trash_count <= 8)
|
2013-09-10 19:23:50 -07:00
|
|
|
{
|
2013-09-11 00:08:06 -07:00
|
|
|
eina_trash_push(&klass->objects.trash, obj);
|
|
|
|
klass->objects.trash_count++;
|
2013-09-10 19:23:50 -07:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
free(obj);
|
|
|
|
}
|
2013-10-10 01:26:02 -07:00
|
|
|
eina_spinlock_release(&klass->objects.trash_lock);
|
2013-06-27 01:58:49 -07:00
|
|
|
}
|
|
|
|
|
2013-09-26 14:31:39 -07:00
|
|
|
static inline _Eo_Object *
|
2016-08-15 06:44:41 -07:00
|
|
|
_efl_ref(_Eo_Object *obj)
|
2013-06-27 01:58:49 -07:00
|
|
|
{
|
|
|
|
obj->refcount++;
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
2016-08-15 06:44:41 -07:00
|
|
|
_efl_unref(_Eo_Object *obj)
|
2013-06-27 01:58:49 -07:00
|
|
|
{
|
|
|
|
--(obj->refcount);
|
2015-10-15 09:51:20 -07:00
|
|
|
if (EINA_UNLIKELY(obj->refcount <= 0))
|
2013-06-27 01:58:49 -07:00
|
|
|
{
|
2015-10-15 09:51:20 -07:00
|
|
|
if (obj->refcount < 0)
|
|
|
|
{
|
|
|
|
ERR("Obj:%p. Refcount (%d) < 0. Too many unrefs.", obj, obj->refcount);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-12-04 17:19:47 -08:00
|
|
|
if (obj->destructed)
|
2013-06-27 01:58:49 -07:00
|
|
|
{
|
2016-05-17 02:29:14 -07:00
|
|
|
ERR("Object %p already destructed.", _eo_obj_id_get(obj));
|
2014-11-18 07:24:39 -08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-12-04 17:19:47 -08:00
|
|
|
if (obj->del_triggered)
|
2014-11-18 07:24:39 -08:00
|
|
|
{
|
2016-08-15 06:44:41 -07:00
|
|
|
ERR("Object %p deletion already triggered. You wrongly call efl_unref() within a destructor.", _eo_obj_id_get(obj));
|
2013-06-27 01:58:49 -07:00
|
|
|
return;
|
|
|
|
}
|
2016-03-07 23:57:22 -08:00
|
|
|
|
|
|
|
if (obj->del_intercept)
|
|
|
|
{
|
2016-07-12 02:26:23 -07:00
|
|
|
Eo *obj_id = _eo_obj_id_get(obj);
|
2016-08-15 06:44:41 -07:00
|
|
|
efl_ref(obj_id);
|
2016-07-12 02:26:23 -07:00
|
|
|
obj->del_intercept(obj_id);
|
2016-03-07 23:57:22 -08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-12-04 17:19:47 -08:00
|
|
|
obj->del_triggered = EINA_TRUE;
|
2013-06-27 01:58:49 -07:00
|
|
|
|
2016-08-09 06:10:05 -07:00
|
|
|
_efl_del_internal(__FILE__, __LINE__, obj);
|
2013-06-27 01:58:49 -07:00
|
|
|
#ifdef EO_DEBUG
|
|
|
|
/* If for some reason it's not empty, clear it. */
|
|
|
|
while (obj->xrefs)
|
|
|
|
{
|
|
|
|
ERR("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;
|
|
|
|
free(EINA_INLIST_CONTAINER_GET(obj->xrefs, Eo_Xref_Node));
|
|
|
|
obj->xrefs = nitr;
|
|
|
|
}
|
|
|
|
while (obj->data_xrefs)
|
|
|
|
{
|
|
|
|
Eina_Inlist *nitr = obj->data_xrefs->next;
|
|
|
|
Eo_Xref_Node *xref = EINA_INLIST_CONTAINER_GET(obj->data_xrefs, Eo_Xref_Node);
|
2016-05-17 02:29:14 -07:00
|
|
|
ERR("Data of object 0x%lx is still referenced by object %p", (unsigned long) _eo_obj_id_get(obj), xref->ref_obj);
|
2013-06-27 01:58:49 -07:00
|
|
|
|
|
|
|
free(xref);
|
|
|
|
obj->data_xrefs = nitr;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (!obj->manual_free)
|
|
|
|
_eo_free(obj);
|
|
|
|
else
|
2016-08-15 06:44:41 -07:00
|
|
|
_efl_ref(obj); /* If we manual free, we keep a phantom ref. */
|
2013-06-27 01:58:49 -07:00
|
|
|
}
|
|
|
|
}
|
2013-04-18 04:19:02 -07:00
|
|
|
|
2012-05-01 00:40:14 -07:00
|
|
|
#endif
|