> +/**
> + * @brief Get the native domain for the current thread
> + *
> + * @return The native domain
> + *
> + * This will return the native eo object allocation domain for the current
> + * thread. This can only be changed with efl_domain_switch() and this can
> + * only be called before any objects are created/allocated on the thread
> + * where it is called. Calling it after this point will result in
> + * undefined behavior, so be sure to call this immediaetly after a thread
> + * begins to execute, before anything else. You must not change the domain
> + * of the main thread.


the function being documented is `efl_domain_get()`, but text is
mostly about `efl_domain_switch()`. also, from the restriction to not
change it, maybe add the EINA_CONST attribute?


> +/**
> + * @brief Get the native domain for the current thread

copy&pasta?


> + * @param domain The domain to switch to
> + * @return EINA_TRUE if the switch succeeds, and EINA_FALSE if it fails
> + *
> + * Permanently switch the native domain for allocated objects for the calling
> + * thread. All objects created on this thread UNLESS it has switched to a
> + * new domain temporarily with efl_domain_current_set(),
> + * efl_domain_current_push() or efl_domain_current_pop(),
> + * efl_domain_data_adopt() and efl_domain_data_return().

also, maybe it's just me, but this text is not clear enough.

should it be "native domain for NEW allocated objects"? AFAIU it's not
going to modify existing objects.

Also, why _switch() and not _set()?



> +/**
> + * @brief Get the current domain used for allocating new objects
> + * @return The current domain
> + *
> + * Get the currently used domain that is at the top of the domain stack.
> + * There is actually a stack of domans to use you can alter via
> + * efl_domain_current_push() and efl_domain_current_pop(). This only gets
> + * the domain for the current thread.
> + *
> + * @see efl_domain_get()
> + */
> +EAPI Efl_Id_Domain    efl_domain_current_get(void);

would "effective" be a better name? Like in unix users


> +/**
> + * @brief Set the current domain used for allocating new objects
> + * @return EINA_TRUE if it succeeds, and EINA_FALSE on failure
> + *
> + * Temporarily switch the current domain being used for allocation. There
> + * is actually a stack of domans to use you can alter via
> + * efl_domain_current_push() and efl_domain_current_pop(). This only applies
> + * to the calling thread.
> + *
> + * @see efl_domain_get()
> + */
> +EAPI Eina_Bool        efl_domain_current_set(Efl_Id_Domain domain);

here I'm confused. If it's a stack, what does "set"? Reset the stack?
Same as push? Change the last?


> +/**
> + * @brief Get an opaque handle to the local native domain eoid data
> + * @return A handle to the local native domain data or NULl on failure
> + *
> + * This gets a handle to the domain data for the current thread, intended
> + * to be used by another thread to adopt with efl_domain_data_adopt().
> + * Once you use efl_domain_data_adopt() the thread that called
> + * efl_domain_data_get() should suspend and not execute anything
> + * related to eo or efl objects until the thread that adopted the data
> + * called efl_domain_data_return() to return the data to its owner and
> + * stop making it available to that thread.
> + *
> + * @see efl_domain_get()
> + */
> +EAPI Efl_Domain_Data *efl_domain_data_get(void);


> +
> +/**
> + * @brief Adopt a single extra domain to be the current domain
> + * @param datas_in The domain data to adopt
> + * @return The domain that was adopted or EFL_ID_DOMAIN_INVALID on failure
> + *
> + * This will adopt the given domain data pointed to by @p data_in
> + * as an extra domain locally. The adopted domain must have a domain ID
> + * that is not the same as the current thread domain or local domain. You
> + * may not adopt a domain that clashes with the current domain. If you
> + * set, push or pop domains so these might clash (be the same) then
> + * undefined behaviour will occur.
> + *
> + * This will also push the adopted domain as the current domain so that
> + * all newly created objects (unless their parent is of a differing domain)
> + * will be part of this adopted domain. You can still access objects from
> + * your local domain as well, but be aware that creation will require
> + * some switch of domain by push, pop or set. Return the domain with
> + * efl_domain_data_return() when done.
> + *
> + * @see efl_domain_get()
> + */
> +EAPI Efl_Id_Domain    efl_domain_data_adopt(Efl_Domain_Data *data_in);
> +
> +/**
> + * @brief Return a domain to its original owning thread
> + * @param domain The domain to return
> + * @return EINA_TRUE on success EINA_FALSE on failure
> + *
> + * This returns the domain specified by @p domain to the thread it came
> + * from, allowing that thread after this to continue execution. This
> + * will implicitly pop the current domain from the stack, assuming that
> + * the current domain is the same one pushed implicitly by
> + * efl_domain_data_adopt(). You cannot return your own native local
> + * domain, only the one that was adopted by efl_domain_data_adopt().
> + *
> + * @see efl_domain_get()
> + */
> +EAPI Eina_Bool        efl_domain_data_return(Efl_Id_Domain domain);

why not return the same parameter that you did adopt? That is, Efl_Domain_Data.



> +/**
> + * @prief Check if 2 objects are compatible
> + * @param obj The basic object
> + * @param obj_target The alternat object that may be referenced by @p obj
> + * @return EINA_TRUE if compatible, EINA_FALSE if not
> + *
> + * This checks to see if 2 objects are compatible and could be parent or
> + * children of eachoter, could reference eachoter etc.. There is only a
> + * need to call this if you got objects from multiple domains (an
> + * adopted domain with efl_domain_data_adopt() or the shared domain
> + * EFL_ID_DOMAIN_SHARED where objects may be accessed by any thread).
> + *
> + * @see efl_domain_get()
> + */
> +EAPI Eina_Bool        efl_compatible(const Eo *obj, const Eo *obj_target);

namespace this with "domain"... otherwise people will easily be
confused, like a variation of "efl_isa()" that compares based on type.


>  EAPI Eina_Bool
>  efl_isa(const Eo *eo_id, const Efl_Class *klass_id)
>  {
> -   eina_spinlock_take(&_eoid_lock);
> -   if (cached_isa_id == eo_id && cached_klass == klass_id)
> +   Efl_Id_Domain domain;
> +   Eo_Id_Data *data;
> +   Eo_Id_Table_Data *tdata;
> +   Eina_Bool isa = EINA_FALSE;
> +
> +   domain = ((Eo_Id)eo_id >> SHIFT_DOMAIN) & MASK_DOMAIN;

macro EOID_DOMAIN(eo_id) or EOID_DOMAIN_GET()?


> +        // Caching the result as we do a lot of serial efl_isa due to 
> evas_object_image using it.

insightful, but also a hint we should review evas_object_image to need
to use it? Maybe another interface it would just call, instead of
manually checking the type to decide?



> +        eina_spinlock_take(&(tdata->lock));
>
> -   // Caching the result as we do a lot of serial efl_isa due to 
> evas_object_image using it.
> -   cached_isa_id = eo_id;
> -   cached_klass = klass_id;
> +        if ((tdata->cache.isa_id == eo_id) &&
> +            (tdata->cache.klass == klass_id))
> +          {
> +             isa = tdata->cache.isa;
> +             goto shared_ok;
> +          }
> +        eina_spinlock_release(&(tdata->lock));
>
> -   /* Currently implemented by reusing the LAST op id. Just marking it with
> -    * _eo_class_isa_func. */
> -   cached_isa = (func && (func->func == _eo_class_isa_func));
> +        EO_OBJ_POINTER_RETURN_VAL(eo_id, obj, EINA_FALSE);
> +        EO_CLASS_POINTER_RETURN_VAL(klass_id, klass, EINA_FALSE);
> +        const op_type_funcs *func = _vtable_func_get
> +          (obj->vtable, klass->base_id + klass->ops_count);
>
> -   eina_spinlock_release(&_eoid_lock);
> +        eina_spinlock_take(&(tdata->lock));
>
> -   return cached_isa;
> +        // Caching the result as we do a lot of serial efl_isa due to 
> evas_object_image using it.
> +        tdata->cache.isa_id = eo_id;
> +        tdata->cache.klass = klass_id;
> +        // Currently implemented by reusing the LAST op id. Just marking it 
> with
> +        // _eo_class_isa_func.
> +        isa = tdata->cache.isa = (func && (func->func == 
> _eo_class_isa_func));
> +shared_ok:
> +        eina_spinlock_release(&(tdata->lock));
> +     }
> +   return isa;

except for the nasty locks, this code is essentially the same as the
one above. Why not a

static inline Eina_Bool _efl_isa_unlocked(Eo_Id_Table_Data *tdata,
const Eo *eo_id, const Efl_Class *klass_id)
{
 // do the cache comparison
}

Then efl_isa() would fetch tdata and do the:
    if (EINA_LIKELY(domain != ...)) {
     return _efl_isa_unlocked(tdata, eo_id, klass_id);
    else {
       Eina_Bool isa;
       eina_spinlock_take(&(tdata->lock));
       isa = _efl_isa_unlocked(tdata, eo_id, klass_id);
       eina_spinlock_release(&(tdata->lock));
       return isa;
     }


> +EAPI Eina_Bool
> +efl_domain_switch(Efl_Id_Domain domain)
> +{
> +   Eo_Id_Data *data = _eo_table_data_get();
> +   if ((domain < EFL_ID_DOMAIN_MAIN) || (domain > EFL_ID_DOMAIN_THREAD) ||
> +       (domain == EFL_ID_DOMAIN_SHARED))
> +     {
> +        ERR("Invalid domain %i being switched to", domain);
> +        return EINA_FALSE;
> +     }
> +   if (data)
> +     {
> +        if (data->local_domain == domain) return EINA_TRUE;
> +        _eo_free_ids_tables(data);
> +     }
> +   data = _eo_table_data_new(domain);
> +   eina_tls_set(_eo_table_data, data);

DBG("switched to domain=%i", domain), so we can more easily spot bugs in logs?

> +static inline Eina_Bool
> +_efl_domain_push(Eo_Id_Data *data, Efl_Id_Domain domain)
> +{
> +   if (data->stack_top >= (sizeof(data->domain_stack) - 1))
> +     {
> +        ERR("Failed to push domain %i on stack. Out of stack space at %i",
> +            domain, data->stack_top);
> +        return EINA_FALSE;
> +     }
> +   data->stack_top++;
> +   data->domain_stack[data->stack_top] = domain;

I'd also add a DBG() here, at least in this initial phase of
development... but the performance shouldn't be hurt in release mode,
as DBG should be stripped out.


> +static inline void
> +_efl_domain_pop(Eo_Id_Data *data)
> +{
> +   if (data->stack_top > 0) data->stack_top--;
> +}

and here, a DBG("data=%p popped, new domain %i, stack=%u", data,
data->stack[data->stack_top], data->stack_top)

if you think these debug will pollute too much the output, then create
a new log domain for "efl_domain".


> +EAPI Eina_Bool
> +efl_domain_current_set(Efl_Id_Domain domain)
> +{
> +   Eo_Id_Data *data = _eo_table_data_get();
> +   if ((domain < EFL_ID_DOMAIN_MAIN) || (domain > EFL_ID_DOMAIN_THREAD))
> +     {
> +        ERR("Invalid domain %i being set", domain);
> +        return EINA_FALSE;
> +     }
> +   data->domain_stack[data->stack_top] = domain;

reading the doc is unclear this is the actual implementation or why is
it needed.


> +   data->tables[data_foreign->local_domain] =
> +     data_foreign->tables[data_foreign->local_domain];
> +   _efl_domain_push(data, data_foreign->local_domain);

DBG("data=%p domain=%i stack_top=%u, data_foreign=%p domain=%i"...)

will help debug :-)


> +   return data->domain_stack[data->stack_top];
> +}
> +
> +EAPI Eina_Bool
> +efl_domain_data_return(Efl_Id_Domain domain)
> +{
> +   Eo_Id_Data *data = _eo_table_data_get();
> +
> +   if ((domain < EFL_ID_DOMAIN_MAIN) || (domain > EFL_ID_DOMAIN_THREAD))
> +     {
> +        ERR("Invalid domain %i being returned to owning thread", domain);
> +        return EINA_FALSE;
> +     }
> +   if (domain == data->local_domain)
> +     {
> +        ERR("Cannot return the local domain back to its owner");
> +        return EINA_FALSE;
> +     }
> +   data->tables[domain] = NULL;
> +   _efl_domain_pop(data);
> +   return EINA_TRUE;
> +}

the doc is kinda of misleading... you're just not using it anymore,
but the owner thread is not affected anyhow by this function. Just the
local thread.



> +_Eo_Object *
> +_eo_obj_pointer_get(const Eo_Id obj_id)
> +{
> +#ifdef HAVE_EO_ID
> +   _Eo_Id_Entry *entry;
> +   _Eo_Object *ptr;
> +   Generation_Counter generation;
> +   Table_Index mid_table_id, table_id, entry_id;
> +   Eo_Id tag_bit;
> +   Eo_Id_Data *data;
> +   Eo_Id_Table_Data *tdata;
> +   unsigned char domain;
> +
> +   // NULL objects will just be sensibly ignored. not worth complaining
> +   // every single time.
> +
> +   domain = (obj_id >> SHIFT_DOMAIN) & MASK_DOMAIN;
> +   data = _eo_table_data_get();
> +   tdata = _eo_table_data_table_get(data, domain);
> +   if (!tdata) goto err_invalid;
> +
> +   if (EINA_LIKELY(domain != EFL_ID_DOMAIN_SHARED))
> +     {
> +        if (obj_id == tdata->cache.id)
> +          {
> +             ptr = tdata->cache.object;
> +             return ptr;
> +          }
> +
> +        // get tag bit to check later down below - pipelining
> +        tag_bit = (obj_id) & MASK_OBJ_TAG;
> +        if (!obj_id) goto err_null;
> +        else if (!tag_bit) goto err_invalid;
> +
> +        EO_DECOMPOSE_ID(obj_id, mid_table_id, table_id, entry_id, 
> generation);
> +
> +        // Check the validity of the entry
> +        if (tdata->eo_ids_tables[mid_table_id])
> +          {
> +             _Eo_Ids_Table *tab = TABLE_FROM_IDS;
> +
> +             if (tab)
> +               {
> +                  entry = &(tab->entries[entry_id]);
> +                  if (entry->active && (entry->generation == generation))
> +                    {
> +                       // Cache the result of that lookup
> +                       tdata->cache.object = entry->ptr;
> +                       tdata->cache.id = obj_id;
> +                       ptr = entry->ptr;
> +                       return ptr;
> +                    }
> +               }
> +          }
> +        goto err;

same here, make this block a "_unlocked()" static inline.


> +     }
> +   else
> +     {
> +        eina_spinlock_take(&(tdata->lock));

and call it here inside the lock.


>  /* Shifts macros to manipulate the Eo id */
> +#define SHIFT_DOMAIN          (BITS_MID_TABLE_ID + BITS_TABLE_ID + \
> +                               BITS_ENTRY_ID + BITS_GENERATION_COUNTER)
>  #define SHIFT_MID_TABLE_ID    (BITS_TABLE_ID + \
>                                 BITS_ENTRY_ID + BITS_GENERATION_COUNTER)
>  #define SHIFT_TABLE_ID        (BITS_ENTRY_ID + BITS_GENERATION_COUNTER)
> @@ -91,12 +95,14 @@ typedef uint32_t Generation_Counter;
>
>  /* Maximum ranges - a few tables and entries are dropped to minimize the 
> amount
>   * of wasted bytes, see _eo_id_mem_alloc */
> +#define MAX_DOMAIN            (1 << BITS_DOMAIN)
>  #define MAX_MID_TABLE_ID      (1 << BITS_MID_TABLE_ID)
>  #define MAX_TABLE_ID          ((1 << BITS_TABLE_ID) - DROPPED_TABLES )
>  #define MAX_ENTRY_ID          ((1 << BITS_ENTRY_ID) - DROPPED_ENTRIES)
>  #define MAX_GENERATIONS       (1 << BITS_GENERATION_COUNTER)
>
>  /* Masks */
> +#define MASK_DOMAIN           (MAX_DOMAIN - 1)
>  #define MASK_MID_TABLE_ID     (MAX_MID_TABLE_ID - 1)
>  #define MASK_TABLE_ID         ((1 << BITS_TABLE_ID) - 1)
>  #define MASK_ENTRY_ID         ((1 << BITS_ENTRY_ID) - 1)
> @@ -236,110 +242,155 @@ typedef struct
>     _Eo_Id_Entry entries[MAX_ENTRY_ID];
>  } _Eo_Ids_Table;


argh, this gets ugly... did you consider to map the eo_id to a struct like:

struct _Eo_Id {
    unsigned long domain: 2;
    unsigned long generation: ...;
    ...
};

at least it's more readable... with a simple cast :-)




> -/* Spare empty table */
> -extern _Eo_Ids_Table *_empty_table;
> +struct _Eo_Id_Table_Data
> +{
> +   /* Tables handling pointers indirection */
> +   _Eo_Ids_Table     **eo_ids_tables[MAX_MID_TABLE_ID];
> +   /* Current table used for following allocations */
> +   _Eo_Ids_Table      *current_table;
> +   /* Spare empty table */
> +   _Eo_Ids_Table      *empty_table;
> +   /* Cached eoid lookups */
> +   struct
> +     {
> +        Eo_Id             id;
> +        _Eo_Object       *object;
> +        const Eo         *isa_id;
> +        const Efl_Class  *klass;
> +        Eina_Bool         isa;
> +     }
> +   cache;
> +   /* Next generation to use when assigning a new entry to a Eo pointer */
> +   Generation_Counter  generation;
> +   /* Optional lock around objects and eoid table - only used if shared */
> +   Eina_Spinlock       lock;
> +   /* are we shared so we need lock/unlock? */
> +   Eina_Bool           shared : 1;
> +};

you could omit shared and lock from the struct. Since shared is
inferred from the domain and you know that. And the lock is only for
the shared domain, so it can go as a global.


> +static inline Eo_Id_Table_Data *
> +_eo_table_data_table_new(Efl_Id_Domain domain)
> +{
> +   Eo_Id_Table_Data *tdata;
>
> -#define EO_COMPOSE_FINAL_ID(PARTIAL_ID, ENTRY, GENERATION)     \
> -    (PARTIAL_ID                                             |  \
> -     ((ENTRY & MASK_ENTRY_ID) << SHIFT_ENTRY_ID)            |  \
> -     (GENERATION & MASK_GENERATIONS ))
> +   tdata = calloc(1, sizeof(Eo_Id_Table_Data));
> +   if (!tdata) return NULL;
> +   if (domain == EFL_ID_DOMAIN_SHARED)
> +     {
> +        if (!eina_spinlock_new(&(tdata->lock)))
> +          {
> +             free(tdata);
> +             return NULL;
> +          }
> +        tdata->shared = EINA_TRUE;

here you could move the eina_spinlock_new() to eo_init() outside of
the data_table_new().


> +static inline Eo_Id_Data *
> +_eo_table_data_new(Efl_Id_Domain domain)
> +{
> +   Eo_Id_Data *data;
> +
> +   data = calloc(1, sizeof(Eo_Id_Data));
> +   if (!data) return NULL;
> +   data->local_domain = domain;
> +   data->domain_stack[data->stack_top] = data->local_domain;
> +   data->tables[data->local_domain] =
> +     _eo_table_data_table_new(data->local_domain);
> +   if (domain != EFL_ID_DOMAIN_SHARED)
> +     data->tables[EFL_ID_DOMAIN_SHARED] =
> +     _eo_table_data_shared->tables[EFL_ID_DOMAIN_SHARED];

hum... here you could omit the "if", always assign. Then on the
_data_adopt() you can remove the "if"  as it will hit the "already
adopted" case.


> -   eina_spinlock_take(&_eoid_lock);
> -   if (obj_id == cached_id)
> +static inline Eina_Bool
> +_eo_id_domain_compatible(const Eo *o1, const Eo *o2)
> +{
> +   Efl_Id_Domain domain1 = ((Eo_Id)o1 >> SHIFT_DOMAIN) & MASK_DOMAIN;
> +   Efl_Id_Domain domain2 = ((Eo_Id)o2 >> SHIFT_DOMAIN) & MASK_DOMAIN;
> +   if (domain1 != domain2)
>       {
> -        ptr = cached_object;
> -        eina_spinlock_release(&_eoid_lock);
> -        return ptr;
> +        ERR("Object %p and %p are not compatible. Domain %i and %i do not 
> match",
> +            o1, o2, domain1, domain2);
> +        return EINA_FALSE;

hum... this shouldn't be an ERR... it's called by the user, that may
want to check if it is and you'll generate an error.

Maybe add it for the users of _eo_id_domain_compatible() inside our code.



>  /* Gives a fake id that serves as a marker if eo id is off. */
>  static inline Eo_Id
> -_eo_id_allocate(const _Eo_Object *obj)
> +_eo_id_allocate(const _Eo_Object *obj, const Eo *parent_id)
>  {
>  #ifdef HAVE_EO_ID
>     _Eo_Id_Entry *entry = NULL;
> +   Eo_Id_Data *data;
> +   Eo_Id_Table_Data *tdata;
> +   Eo_Id id;
>
> -   eina_spinlock_take(&_eoid_lock);
> -   if (_current_table)
> -     entry = _get_available_entry(_current_table);
> -
> -   if (!entry)
> +   data = _eo_table_data_get();
> +   if (parent_id)
>       {
> -        entry = _search_tables();
> +        Efl_Id_Domain domain = ((Eo_Id)parent_id >> SHIFT_DOMAIN) & 
> MASK_DOMAIN;
> +        tdata = _eo_table_data_table_get(data, domain);
>       }
> +   else tdata = _eo_table_data_current_table_get(data);
> +   if (!tdata) return 0;
>
> -   if (!_current_table || !entry)
> +   if (EINA_LIKELY(!tdata->shared))
>       {
> -        eina_spinlock_release(&_eoid_lock);
> -        return 0;
> +        if (tdata->current_table)
> +          entry = _get_available_entry(tdata->current_table);
> +
> +        if (!entry) entry = _search_tables(tdata);
> +
> +        if (!tdata->current_table || !entry)
> +          {
> +             return 0;
> +          }
> +
> +        UNPROTECT(tdata->current_table);
> +        /* [1;max-1] thus we never generate an Eo_Id equal to 0 */
> +        tdata->generation++;
> +        if (tdata->generation == MAX_GENERATIONS) tdata->generation = 1;
> +        /* Fill the entry and return it's Eo Id */
> +        entry->ptr = (_Eo_Object *)obj;
> +        entry->active = 1;
> +        entry->generation = tdata->generation;
> +        PROTECT(tdata->current_table);
> +        id = EO_COMPOSE_FINAL_ID(tdata->current_table->partial_id,
> +                                 (entry - tdata->current_table->entries),
> +                                 data->domain_stack[data->stack_top],
> +                                 entry->generation);
>       }
> +   else
> +     {
> +        eina_spinlock_take(&(tdata->lock));

add the _locked, call it both above and here.



> -   eina_spinlock_take(&_eoid_lock);
> -   /* Check the validity of the entry */
> -   if (_eo_ids_tables[mid_table_id] && (table = TABLE_FROM_IDS))
> +   if (EINA_LIKELY(domain != EFL_ID_DOMAIN_SHARED))
>       {
> -        entry = &(table->entries[entry_id]);
> -        if (entry && entry->active && (entry->generation == generation))
> +        // Check the validity of the entry
> +        if (tdata->eo_ids_tables[mid_table_id] && (table = TABLE_FROM_IDS))
>            {
> -             UNPROTECT(table);
> -             table->free_entries++;
> -             /* Disable the entry */
> -             entry->active = 0;
> -             entry->next_in_fifo = -1;
> -             /* Push the entry into the fifo */
> -             if (table->fifo_tail == -1)
> -               {
> -                  table->fifo_head = table->fifo_tail = entry_id;
> -               }
> -             else
> -               {
> -                  table->entries[table->fifo_tail].next_in_fifo = entry_id;
> -                  table->fifo_tail = entry_id;
> -               }
> -             PROTECT(table);
> -             if (table->free_entries == MAX_ENTRY_ID)
> +             entry = &(table->entries[entry_id]);
> +             if (entry && entry->active && (entry->generation == generation))
>                 {
> -                  UNPROTECT(_eo_ids_tables[mid_table_id]);
> -                  TABLE_FROM_IDS = NULL;
> -                  PROTECT(_eo_ids_tables[mid_table_id]);
> -                  /* Recycle or free the empty table */
> -                  if (!_empty_table)
> -                    _empty_table = table;
> +                  UNPROTECT(table);
> +                  table->free_entries++;
> +                  // Disable the entry
> +                  entry->active = 0;
> +                  entry->next_in_fifo = -1;
> +                  // Push the entry into the fifo
> +                  if (table->fifo_tail == -1)
> +                    table->fifo_head = table->fifo_tail = entry_id;
>                    else
> -                    _eo_id_mem_free(table);
> -                  if (_current_table == table)
> -                    _current_table = NULL;
> +                    {
> +                       table->entries[table->fifo_tail].next_in_fifo = 
> entry_id;
> +                       table->fifo_tail = entry_id;
> +                    }
> +                  PROTECT(table);
> +                  if (table->free_entries == MAX_ENTRY_ID)
> +                    {
> +                       UNPROTECT(tdata->eo_ids_tables[mid_table_id]);
> +                       TABLE_FROM_IDS = NULL;
> +                       PROTECT(tdata->eo_ids_tables[mid_table_id]);
> +                       // Recycle or free the empty table
> +                       if (!tdata->empty_table) tdata->empty_table = table;
> +                       else _eo_id_mem_free(table);
> +                       if (tdata->current_table == table)
> +                         tdata->current_table = NULL;
> +                    }
> +                  // In case an object is destroyed, wipe out the cache
> +                  if (tdata->cache.id == obj_id)
> +                    {
> +                       tdata->cache.id = 0;
> +                       tdata->cache.object = NULL;
> +                    }
> +                  if ((Eo_Id)tdata->cache.isa_id == obj_id)
> +                    {
> +                       tdata->cache.isa_id = NULL;
> +                       tdata->cache.klass = NULL;;
> +                       tdata->cache.isa = EINA_FALSE;
> +                    }
> +                  return;
>                 }
> -
> -             // In case an object is destroyed, wipe out the cache
> -             if (cached_id == obj_id)
> +          }
> +     }
> +   else
> +     {
> +        eina_spinlock_take(&(tdata->lock));

add _locked, will avoid us hitting bugs in the future :-)




-- 
Gustavo Sverzut Barbieri
--------------------------------------
Mobile: +55 (16) 99354-9890

------------------------------------------------------------------------------
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to