EAPI Eina_Lock _eo_class_creation_lock;
int _eo_log_dom = -1;
-/**
- * @typedef Eo_Class_Id
- * An Id of a class.
- * @ingroup Eo_Class
- */
-typedef uintptr_t Eo_Class_Id;
-
-typedef struct _Eo_Class _Eo_Class;
-
static _Eo_Class **_eo_classes;
static Eo_Class_Id _eo_classes_last_id;
static Eina_Bool _eo_init_count = 0;
static inline void *_eo_data_scope_get(const _Eo *obj, const _Eo_Class *klass);
static inline void *_eo_data_xref_internal(const char *file, int line, _Eo *obj, const _Eo_Class *klass, const _Eo *ref_obj);
static inline void _eo_data_xunref_internal(_Eo *obj, void *data, const _Eo *ref_obj);
-static inline _Eo *_eo_ref(_Eo *obj);
-static inline void _eo_unref(_Eo *obj);
static const _Eo_Class *_eo_op_class_get(Eo_Op op);
static const Eo_Op_Description *_eo_op_id_desc_get(Eo_Op op);
-struct _Eo_Internal {
-#ifndef HAVE_EO_ID
- EINA_MAGIC
-#endif
- Eo *parent;
- Eina_List *children;
- const _Eo_Class *klass;
-#ifdef EO_DEBUG
- Eina_Inlist *xrefs;
- Eina_Inlist *data_xrefs;
-#endif
-
- Eina_List *composite_objects;
-
- Eo_Id obj_id;
-
- int refcount;
- int datarefcount;
-
- Eina_Bool do_error:1;
- Eina_Bool condtor_done:1;
-
- Eina_Bool composite:1;
- Eina_Bool del:1;
- Eina_Bool manual_free:1;
-};
-
/* Start of Dich */
/* How we search and store the implementations in classes. */
#define EO_ALIGN_SIZE(size) eina_mempool_alignof(size)
-typedef struct _Dich_Chain1 Dich_Chain1;
-
-typedef struct
-{
- eo_op_func_type func;
- const _Eo_Class *src;
-} op_type_funcs;
-
-struct _Dich_Chain1
-{
- op_type_funcs *funcs;
-};
-
-typedef struct
-{
- const _Eo_Class *klass;
- size_t offset;
-} Eo_Extension_Data_Offset;
-
-struct _Eo_Class
-{
- EINA_MAGIC
- Eo_Class_Id class_id;
- const _Eo_Class *parent;
- const Eo_Class_Description *desc;
- Dich_Chain1 *chain; /**< The size is chain size */
-
- const _Eo_Class **extensions;
-
- Eo_Extension_Data_Offset *extn_data_off;
-
- const _Eo_Class **mro;
-
- unsigned int obj_size; /**< size of an object of this class */
- unsigned int chain_size;
- unsigned int base_id;
- unsigned int data_offset; /* < Offset of the data within object data. */
-
- Eina_Bool constructed : 1;
- /* [extensions*] + NULL */
- /* [mro*] + NULL */
- /* [extensions data offset] + NULL */
-};
-
static inline void
_dich_chain_alloc(Dich_Chain1 *chain1)
{
_eo_unref(obj);
}
-static inline _Eo *
-_eo_ref(_Eo *obj)
-{
- obj->refcount++;
- return obj;
-}
-
EAPI Eo *
eo_ref(const Eo *obj_id)
{
return (Eo *)obj_id;
}
-static inline void
-_eo_del_internal(const char *file, int line, _Eo *obj)
-{
- Eina_Bool do_err;
- /* We need that for the event callbacks that may ref/unref. */
- obj->refcount++;
-
- eo_do((Eo *) obj->obj_id, eo_event_callback_call(EO_EV_DEL, NULL, NULL));
-
- const _Eo_Class *klass = obj->klass;
-
- _eo_condtor_reset(obj);
-
- do_err = eo_do((Eo *)obj->obj_id, eo_destructor());
- if (EINA_UNLIKELY(!do_err))
- {
- ERR("in %s:%d: Object of class '%s' - One of the object destructors have failed.",
- file, line, klass->desc->name);
- }
-
- 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. */
-
- {
- Eina_List *itr, *itr_n;
- Eo *emb_obj;
- EINA_LIST_FOREACH_SAFE(obj->composite_objects, itr, itr_n, emb_obj)
- {
- eo_composite_detach(emb_obj, (Eo *)obj->obj_id);
- }
- }
-
- while (obj->children)
- {
- eo_parent_set(eina_list_data_get(obj->children), NULL); // ZZZ
- }
-
- obj->del = EINA_TRUE;
- obj->refcount--;
-}
-
-static inline void
-_eo_free(_Eo *obj)
-{
-#ifdef EO_DEBUG
- if (obj->datarefcount)
- {
- ERR("Object %p data still referenced %d time(s).", obj, obj->datarefcount);
- }
-#endif
- _eo_id_release(obj->obj_id);
- free(obj);
-}
-
-static inline void
-_eo_unref(_Eo *obj)
-{
- --(obj->refcount);
- if (obj->refcount == 0)
- {
- if (obj->del)
- {
- ERR("Object %p already deleted.", obj);
- return;
- }
-
- _eo_del_internal(__FILE__, __LINE__, obj);
-
-#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);
- ERR("Data of object 0x%lx is still referenced by object %p", (unsigned long)obj->obj_id, xref->ref_obj);
-
- free(xref);
- obj->data_xrefs = nitr;
- }
-#endif
-
- if (!obj->manual_free)
- _eo_free(obj);
- else
- _eo_ref(obj); /* If we manual free, we keep a phantom ref. */
- }
- else if (obj->refcount < 0)
- {
- ERR("Obj:%p. Refcount (%d) < 0. Too many unrefs.", obj, obj->refcount);
- return;
- }
-}
-
EAPI void
eo_unref(const Eo *obj_id)
{
obj->condtor_done = EINA_TRUE;
}
-static void
-_eo_condtor_reset(_Eo *obj)
-{
- obj->condtor_done = EINA_FALSE;
-}
-
static inline void *
_eo_data_scope_get(const _Eo *obj, const _Eo_Class *klass)
{
#include <Eina.h>
#include "Eo.h"
+#include "eo_ptr_indirection.h"
#include "eo_private.h"
EAPI Eo_Op EO_BASE_BASE_ID = 0;
}
static void
-_ev_cb_call(Eo *obj, void *class_data, va_list *list)
+_ev_cb_call(Eo *obj_id, void *class_data, va_list *list)
{
Private_Data *pd = (Private_Data *) class_data;
const Eo_Event_Description *desc = va_arg(*list, const Eo_Event_Description *);
void *event_info = va_arg(*list, void *);
Eina_Bool *ret = va_arg(*list, Eina_Bool *);
+ EO_OBJ_POINTER_RETURN(obj_id, obj);
if (ret) *ret = EINA_TRUE;
- /* FIXME: Change eo_ref to _eo_ref and unref. */
- eo_ref(obj);
+ _eo_ref(obj);
pd->walking_list++;
Eo_Callback_Description *cb;
continue;
/* Abort callback calling if the func says so. */
- if (!it->func((void *) cb->func_data, obj, desc,
+ if (!it->func((void *) cb->func_data, obj_id, desc,
(void *) event_info))
{
if (ret) *ret = EINA_FALSE;
if (cb->items.item.desc == desc)
{
/* Abort callback calling if the func says so. */
- if (!cb->items.item.func((void *) cb->func_data, obj, desc,
+ if (!cb->items.item.func((void *) cb->func_data, obj_id, desc,
(void *) event_info))
{
if (ret) *ret = EINA_FALSE;
end:
pd->walking_list--;
_eo_callbacks_clear(pd);
- eo_unref(obj);
+ _eo_unref(obj);
}
static Eina_Bool
#endif
#define DBG(...) EINA_LOG_DOM_DBG(_eo_log_dom, __VA_ARGS__)
+typedef size_t Eo_Id;
+typedef struct _Eo_Class _Eo_Class;
+typedef struct _Eo_Internal _Eo;
+
+/* Retrieves the pointer to the object from the id */
+_Eo *_eo_obj_pointer_get(const Eo_Id obj_id);
+
+/* Allocates an entry for the given object */
+Eo_Id _eo_id_allocate(const _Eo *obj);
+
+/* Releases an entry by the object id */
+void _eo_id_release(const Eo_Id obj_id);
+
+/* Free all the entries and the tables */
+void _eo_free_ids_tables();
+
void _eo_condtor_done(Eo *obj);
-typedef struct _Eo_Internal _Eo;
+struct _Eo_Internal {
+#ifndef HAVE_EO_ID
+ EINA_MAGIC
+#endif
+ Eo *parent;
+ Eina_List *children;
+ const _Eo_Class *klass;
+#ifdef EO_DEBUG
+ Eina_Inlist *xrefs;
+ Eina_Inlist *data_xrefs;
+#endif
+
+ Eina_List *composite_objects;
+
+ Eo_Id obj_id;
+
+ int refcount;
+ int datarefcount;
+
+ Eina_Bool do_error:1;
+ Eina_Bool condtor_done:1;
+
+ Eina_Bool composite:1;
+ Eina_Bool del:1;
+ Eina_Bool manual_free:1;
+};
+
+/**
+ * @typedef Eo_Class_Id
+ * An Id of a class.
+ * @ingroup Eo_Class
+ */
+typedef uintptr_t Eo_Class_Id;
+
+typedef struct _Dich_Chain1 Dich_Chain1;
+
+typedef struct
+{
+ eo_op_func_type func;
+ const _Eo_Class *src;
+} op_type_funcs;
+
+struct _Dich_Chain1
+{
+ op_type_funcs *funcs;
+};
+
+typedef struct
+{
+ const _Eo_Class *klass;
+ size_t offset;
+} Eo_Extension_Data_Offset;
+
+struct _Eo_Class
+{
+ EINA_MAGIC
+ Eo_Class_Id class_id;
+ const _Eo_Class *parent;
+ const Eo_Class_Description *desc;
+ Dich_Chain1 *chain; /**< The size is chain size */
+
+ const _Eo_Class **extensions;
+
+ Eo_Extension_Data_Offset *extn_data_off;
+
+ const _Eo_Class **mro;
+
+ unsigned int obj_size; /**< size of an object of this class */
+ unsigned int chain_size;
+ unsigned int base_id;
+ unsigned int data_offset; /* < Offset of the data within object data. */
+
+ Eina_Bool constructed : 1;
+ /* [extensions*] + NULL */
+ /* [mro*] + NULL */
+ /* [extensions data offset] + NULL */
+};
+
+static inline void
+_eo_condtor_reset(_Eo *obj)
+{
+ obj->condtor_done = EINA_FALSE;
+}
+
+static inline void
+_eo_del_internal(const char *file, int line, _Eo *obj)
+{
+ Eina_Bool do_err;
+ /* We need that for the event callbacks that may ref/unref. */
+ obj->refcount++;
+
+ eo_do((Eo *) obj->obj_id, eo_event_callback_call(EO_EV_DEL, NULL, NULL));
+
+ const _Eo_Class *klass = obj->klass;
+
+ _eo_condtor_reset(obj);
+
+ do_err = eo_do((Eo *)obj->obj_id, eo_destructor());
+ if (EINA_UNLIKELY(!do_err))
+ {
+ ERR("in %s:%d: Object of class '%s' - One of the object destructors have failed.",
+ file, line, klass->desc->name);
+ }
+
+ 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. */
+
+ {
+ Eina_List *itr, *itr_n;
+ Eo *emb_obj;
+ EINA_LIST_FOREACH_SAFE(obj->composite_objects, itr, itr_n, emb_obj)
+ {
+ eo_composite_detach(emb_obj, (Eo *)obj->obj_id);
+ }
+ }
+
+ while (obj->children)
+ {
+ eo_parent_set(eina_list_data_get(obj->children), NULL); // ZZZ
+ }
+
+ obj->del = EINA_TRUE;
+ obj->refcount--;
+}
+
+static inline void
+_eo_free(_Eo *obj)
+{
+#ifdef EO_DEBUG
+ if (obj->datarefcount)
+ {
+ ERR("Object %p data still referenced %d time(s).", obj, obj->datarefcount);
+ }
+#endif
+ _eo_id_release(obj->obj_id);
+ free(obj);
+}
+
+static inline _Eo *
+_eo_ref(_Eo *obj)
+{
+ obj->refcount++;
+ return obj;
+}
+
+static inline void
+_eo_unref(_Eo *obj)
+{
+ --(obj->refcount);
+ if (obj->refcount == 0)
+ {
+ if (obj->del)
+ {
+ ERR("Object %p already deleted.", obj);
+ return;
+ }
+
+ _eo_del_internal(__FILE__, __LINE__, obj);
+
+#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);
+ ERR("Data of object 0x%lx is still referenced by object %p", (unsigned long)obj->obj_id, xref->ref_obj);
+
+ free(xref);
+ obj->data_xrefs = nitr;
+ }
+#endif
+
+ if (!obj->manual_free)
+ _eo_free(obj);
+ else
+ _eo_ref(obj); /* If we manual free, we keep a phantom ref. */
+ }
+ else if (obj->refcount < 0)
+ {
+ ERR("Obj:%p. Refcount (%d) < 0. Too many unrefs.", obj, obj->refcount);
+ return;
+ }
+}
#endif
#include "Eo.h"
#include "eo_private.h"
-typedef size_t Eo_Id;
-
-/* Retrieves the pointer to the object from the id */
-_Eo *_eo_obj_pointer_get(const Eo_Id obj_id);
-
-/* Allocates an entry for the given object */
-Eo_Id _eo_id_allocate(const _Eo *obj);
-
-/* Releases an entry by the object id */
-void _eo_id_release(const Eo_Id obj_id);
-
-/* Free all the entries and the tables */
-void _eo_free_ids_tables();
-
/* Macro used to obtain the object pointer and return if fails. */
#ifdef HAVE_EO_ID