forked from enlightenment/efl
eo: Fix deadlocks with composite objects
This happens with shared objects. The situation seems to be: 1. object has composited object a of class A in thread 1 2. call something on object a from thread 2, deadlock In fact, do anything from thread 2 on a shared object and you deadlock.
This commit is contained in:
parent
6ce60a0de5
commit
9c95eda748
|
@ -466,12 +466,11 @@ end:
|
||||||
Eo *emb_obj_id;
|
Eo *emb_obj_id;
|
||||||
EINA_LIST_FOREACH(obj->composite_objects, itr, emb_obj_id)
|
EINA_LIST_FOREACH(obj->composite_objects, itr, emb_obj_id)
|
||||||
{
|
{
|
||||||
_Eo_Object *emb_obj = _eo_obj_pointer_get((Eo_Id)emb_obj_id);
|
EO_OBJ_POINTER(emb_obj_id, emb_obj);
|
||||||
|
if (EINA_UNLIKELY(!emb_obj)) continue;
|
||||||
if (!emb_obj) continue;
|
|
||||||
|
|
||||||
func = _vtable_func_get(emb_obj->vtable, cache->op);
|
func = _vtable_func_get(emb_obj->vtable, cache->op);
|
||||||
if (func == NULL) continue;
|
if (func == NULL) goto composite_continue;
|
||||||
|
|
||||||
if (EINA_LIKELY(func->func && func->src))
|
if (EINA_LIKELY(func->func && func->src))
|
||||||
{
|
{
|
||||||
|
@ -481,8 +480,11 @@ end:
|
||||||
call->data = _efl_data_scope_get(emb_obj, func->src);
|
call->data = _efl_data_scope_get(emb_obj, func->src);
|
||||||
/* We reffed it above, but no longer need/use it. */
|
/* We reffed it above, but no longer need/use it. */
|
||||||
_efl_unref(obj);
|
_efl_unref(obj);
|
||||||
|
EO_OBJ_DONE(emb_obj_id);
|
||||||
return EINA_TRUE;
|
return EINA_TRUE;
|
||||||
}
|
}
|
||||||
|
composite_continue:
|
||||||
|
EO_OBJ_DONE(emb_obj_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1438,21 +1438,22 @@ _efl_object_event_global_freeze_count_get(Eo *klass EINA_UNUSED, void *pd EINA_U
|
||||||
EOLIAN static Eina_Bool
|
EOLIAN static Eina_Bool
|
||||||
_efl_object_composite_attach(Eo *parent_id, Efl_Object_Data *pd EINA_UNUSED, Eo *comp_obj_id)
|
_efl_object_composite_attach(Eo *parent_id, Efl_Object_Data *pd EINA_UNUSED, Eo *comp_obj_id)
|
||||||
{
|
{
|
||||||
|
Eo *emb_obj_id = NULL;
|
||||||
|
|
||||||
EO_OBJ_POINTER_RETURN_VAL(comp_obj_id, comp_obj, EINA_FALSE);
|
EO_OBJ_POINTER_RETURN_VAL(comp_obj_id, comp_obj, EINA_FALSE);
|
||||||
EO_OBJ_POINTER(parent_id, parent);
|
EO_OBJ_POINTER_GOTO(parent_id, parent, err_parent);
|
||||||
// very unlikely so improve l1 instr cache by using goto
|
|
||||||
if (!parent) goto err_parent;
|
/* FIXME: composite should fail if domains are different */
|
||||||
|
|
||||||
/* Don't composite if we already have a composite object of this type */
|
/* Don't composite if we already have a composite object of this type */
|
||||||
{
|
{
|
||||||
Eina_List *itr;
|
Eina_List *itr;
|
||||||
Eo *emb_obj_id;
|
|
||||||
EINA_LIST_FOREACH(parent->composite_objects, itr, emb_obj_id)
|
EINA_LIST_FOREACH(parent->composite_objects, itr, emb_obj_id)
|
||||||
{
|
{
|
||||||
EO_OBJ_POINTER_RETURN_VAL(emb_obj_id, emb_obj, EINA_FALSE);
|
EO_OBJ_POINTER_GOTO(emb_obj_id, emb_obj, err_klass);
|
||||||
// unlikely so improve l1 instr cache by using goto
|
if (EINA_UNLIKELY(emb_obj->klass == comp_obj->klass)) goto err_klass;
|
||||||
if (emb_obj->klass == comp_obj->klass) goto err_klass;
|
|
||||||
}
|
}
|
||||||
|
emb_obj_id = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Efl_Object_Data *comp_pd = efl_data_scope_get(comp_obj_id, EFL_OBJECT_CLASS);
|
Efl_Object_Data *comp_pd = efl_data_scope_get(comp_obj_id, EFL_OBJECT_CLASS);
|
||||||
|
@ -1466,11 +1467,13 @@ _efl_object_composite_attach(Eo *parent_id, Efl_Object_Data *pd EINA_UNUSED, Eo
|
||||||
|
|
||||||
parent->composite_objects = eina_list_prepend(parent->composite_objects, comp_obj_id);
|
parent->composite_objects = eina_list_prepend(parent->composite_objects, comp_obj_id);
|
||||||
|
|
||||||
|
if (emb_obj_id) EO_OBJ_DONE(emb_obj_id);
|
||||||
EO_OBJ_DONE(parent_id);
|
EO_OBJ_DONE(parent_id);
|
||||||
EO_OBJ_DONE(comp_obj_id);
|
EO_OBJ_DONE(comp_obj_id);
|
||||||
return EINA_TRUE;
|
return EINA_TRUE;
|
||||||
|
|
||||||
err_klass:
|
err_klass:
|
||||||
|
if (emb_obj_id) EO_OBJ_DONE(emb_obj_id);
|
||||||
EO_OBJ_DONE(parent_id);
|
EO_OBJ_DONE(parent_id);
|
||||||
err_parent:
|
err_parent:
|
||||||
EO_OBJ_DONE(comp_obj_id);
|
EO_OBJ_DONE(comp_obj_id);
|
||||||
|
@ -1481,9 +1484,7 @@ EOLIAN static Eina_Bool
|
||||||
_efl_object_composite_detach(Eo *parent_id, Efl_Object_Data *pd EINA_UNUSED, Eo *comp_obj_id)
|
_efl_object_composite_detach(Eo *parent_id, Efl_Object_Data *pd EINA_UNUSED, Eo *comp_obj_id)
|
||||||
{
|
{
|
||||||
EO_OBJ_POINTER_RETURN_VAL(comp_obj_id, comp_obj, EINA_FALSE);
|
EO_OBJ_POINTER_RETURN_VAL(comp_obj_id, comp_obj, EINA_FALSE);
|
||||||
EO_OBJ_POINTER(parent_id, parent);
|
EO_OBJ_POINTER_GOTO(parent_id, parent, err_parent);
|
||||||
// very unlikely so improve l1 instr cache by using goto
|
|
||||||
if (!parent) goto err_parent;
|
|
||||||
|
|
||||||
// unlikely so improve l1 instr cache by using goto
|
// unlikely so improve l1 instr cache by using goto
|
||||||
if (!efl_composite_part_is(comp_obj_id)) goto err_part;
|
if (!efl_composite_part_is(comp_obj_id)) goto err_part;
|
||||||
|
|
|
@ -1371,7 +1371,7 @@ thr1(void *data, Eina_Thread t EINA_UNUSED)
|
||||||
{
|
{
|
||||||
Data *d = data;
|
Data *d = data;
|
||||||
Efl_Id_Domain dom;
|
Efl_Id_Domain dom;
|
||||||
Eo *objs2;
|
Eo *s1, *s2;
|
||||||
|
|
||||||
fail_if(efl_domain_switch(EFL_ID_DOMAIN_THREAD) != EINA_TRUE);
|
fail_if(efl_domain_switch(EFL_ID_DOMAIN_THREAD) != EINA_TRUE);
|
||||||
fail_if(efl_domain_get() != EFL_ID_DOMAIN_THREAD);
|
fail_if(efl_domain_get() != EFL_ID_DOMAIN_THREAD);
|
||||||
|
@ -1382,12 +1382,28 @@ thr1(void *data, Eina_Thread t EINA_UNUSED)
|
||||||
printf("VERIFY finalized_get()\n");
|
printf("VERIFY finalized_get()\n");
|
||||||
fail_if(!efl_finalized_get(d->objs));
|
fail_if(!efl_finalized_get(d->objs));
|
||||||
|
|
||||||
printf("VERIFY parent_set(invalid)\n");
|
printf("VERIFY parent_set(invalid) -- WILL SHOW ERRORS\n");
|
||||||
efl_domain_current_push(EFL_ID_DOMAIN_SHARED);
|
efl_domain_current_push(EFL_ID_DOMAIN_SHARED);
|
||||||
objs2 = efl_add(DOMAIN_CLASS, NULL);
|
s1 = efl_add(DOMAIN_CLASS, NULL);
|
||||||
efl_domain_current_pop();
|
efl_domain_current_pop();
|
||||||
efl_del(objs2);
|
efl_del(s1);
|
||||||
efl_parent_set(d->objs, objs2);
|
efl_parent_set(d->objs, s1);
|
||||||
|
printf("END OF ERRORS\n");
|
||||||
|
|
||||||
|
printf("VERIFY composite\n");
|
||||||
|
efl_domain_current_push(EFL_ID_DOMAIN_SHARED);
|
||||||
|
s1 = efl_add(SIMPLE_CLASS, NULL, simple_a_set(efl_added, 7));
|
||||||
|
s2 = efl_add(SIMPLE_CLASS, NULL, simple_a_set(efl_added, 42));
|
||||||
|
efl_domain_current_pop();
|
||||||
|
|
||||||
|
efl_composite_attach(d->objs, s1);
|
||||||
|
int i1 = simple_a_get(d->objs);
|
||||||
|
int i2 = simple_a_get(s1);
|
||||||
|
fail_if(i1 != i2);
|
||||||
|
fail_if(efl_composite_attach(d->objs, s2));
|
||||||
|
efl_del(s1);
|
||||||
|
fail_if(!efl_composite_attach(d->objs, s2));
|
||||||
|
efl_del(s2);
|
||||||
|
|
||||||
printf("SET ON LOCAL\n");
|
printf("SET ON LOCAL\n");
|
||||||
domain_a_set(obj, 1234);
|
domain_a_set(obj, 1234);
|
||||||
|
@ -1430,7 +1446,7 @@ thr1(void *data, Eina_Thread t EINA_UNUSED)
|
||||||
static void
|
static void
|
||||||
_timeout(int val EINA_UNUSED)
|
_timeout(int val EINA_UNUSED)
|
||||||
{
|
{
|
||||||
printf("TIMED OUT!\n");
|
EINA_LOG_CRIT("TIMED OUT!");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue