kuuko pushed a commit to branch master.

http://git.enlightenment.org/bindings/python/python-efl.git/commit/?id=5045352434529b93e26316b732bd32989fd160ce

commit 5045352434529b93e26316b732bd32989fd160ce
Author: Kai Huuhko <[email protected]>
Date:   Mon Jun 2 09:18:01 2014 +0300

    Evas: Add NULL safety to SmartObject callbacks, exposes a BUG
    
    Apparently the Python instance gets deleted before the smart hide/del
    callbacks are called (by eo callback?).
---
 efl/evas/efl.evas.pyx              |   6 ++
 efl/evas/efl.evas_object_smart.pxi | 129 +++++++++++++++++++++++++++++--------
 examples/elementary/test.py        |   7 +-
 3 files changed, 113 insertions(+), 29 deletions(-)

diff --git a/efl/evas/efl.evas.pyx b/efl/evas/efl.evas.pyx
index fa63f8a..fc96dd0 100644
--- a/efl/evas/efl.evas.pyx
+++ b/efl/evas/efl.evas.pyx
@@ -17,6 +17,10 @@
 
 cimport efl.evas.enums as enums
 from efl.utils.conversions cimport eina_list_strings_to_python_list
+from efl.eina cimport EINA_LOG_DOM_DBG, EINA_LOG_DOM_INFO, EINA_LOG_DOM_WARN
+from efl.utils.logger cimport add_logger
+
+cdef int PY_EFL_EVAS_LOG_DOMAIN = add_logger(__name__).eina_log_domain
 
 EVAS_LAYER_MIN = enums.EVAS_LAYER_MIN
 EVAS_LAYER_MAX = enums.EVAS_LAYER_MAX
@@ -152,6 +156,7 @@ EVAS_ASPECT_CONTROL_BOTH = enums.EVAS_ASPECT_CONTROL_BOTH
 EVAS_SMART_CLASS_VERSION = enums.EVAS_SMART_CLASS_VERSION
 
 def init():
+    EINA_LOG_DOM_INFO(PY_EFL_EVAS_LOG_DOMAIN, "Initializing efl.evas", NULL)
     # when changing these, also change __init__.py!
 #     if evas_object_event_callbacks_len != EVAS_CALLBACK_LAST:
 #         raise SystemError("Number of object callbacks changed from %d to 
%d." %
@@ -163,6 +168,7 @@ def init():
 
 
 def shutdown():
+    EINA_LOG_DOM_INFO(PY_EFL_EVAS_LOG_DOMAIN, "Shutting down efl.evas", NULL)
     return evas_shutdown()
 
 
diff --git a/efl/evas/efl.evas_object_smart.pxi 
b/efl/evas/efl.evas_object_smart.pxi
index 0bd5f49..d9f249d 100644
--- a/efl/evas/efl.evas_object_smart.pxi
+++ b/efl/evas/efl.evas_object_smart.pxi
@@ -30,8 +30,14 @@ _install_metaclass(EvasSmartObjectMeta, ClippedSmartObject)
 
 
 cdef void _smart_object_delete(Evas_Object *o) with gil:
-    cdef SmartObject obj
-    obj = <SmartObject>evas_object_data_get(o, "python-eo")
+    cdef:
+        void *tmp
+        SmartObject obj
+    tmp = evas_object_data_get(o, "python-eo")
+    if tmp == NULL:
+        EINA_LOG_DOM_WARN(PY_EFL_EVAS_LOG_DOMAIN, "obj is NULL!", NULL)
+        return
+    obj = <SmartObject>tmp
 
     try:
         obj._m_delete(obj)
@@ -110,8 +116,14 @@ cdef void _smart_object_delete(Evas_Object *o) with gil:
 
 cdef void _smart_object_move(Evas_Object *o,
                              Evas_Coord x, Evas_Coord y) with gil:
-    cdef SmartObject obj
-    obj = <SmartObject>evas_object_data_get(o, "python-eo")
+    cdef:
+        void *tmp
+        SmartObject obj
+    tmp = evas_object_data_get(o, "python-eo")
+    if tmp == NULL:
+        EINA_LOG_DOM_WARN(PY_EFL_EVAS_LOG_DOMAIN, "obj is NULL!", NULL)
+        return
+    obj = <SmartObject>tmp
     if obj._m_move is not None:
         try:
             obj._m_move(obj, x, y)
@@ -121,8 +133,14 @@ cdef void _smart_object_move(Evas_Object *o,
 
 cdef void _smart_object_resize(Evas_Object *o,
                                Evas_Coord w, Evas_Coord h) with gil:
-    cdef SmartObject obj
-    obj = <SmartObject>evas_object_data_get(o, "python-eo")
+    cdef:
+        void *tmp
+        SmartObject obj
+    tmp = evas_object_data_get(o, "python-eo")
+    if tmp == NULL:
+        EINA_LOG_DOM_WARN(PY_EFL_EVAS_LOG_DOMAIN, "obj is NULL!", NULL)
+        return
+    obj = <SmartObject>tmp
     if obj._m_resize is not None:
         try:
             obj._m_resize(obj, w, h)
@@ -131,8 +149,14 @@ cdef void _smart_object_resize(Evas_Object *o,
 
 
 cdef void _smart_object_show(Evas_Object *o) with gil:
-    cdef SmartObject obj
-    obj = <SmartObject>evas_object_data_get(o, "python-eo")
+    cdef:
+        void *tmp
+        SmartObject obj
+    tmp = evas_object_data_get(o, "python-eo")
+    if tmp == NULL:
+        EINA_LOG_DOM_WARN(PY_EFL_EVAS_LOG_DOMAIN, "obj is NULL!", NULL)
+        return
+    obj = <SmartObject>tmp
     if obj._m_show is not None:
         try:
             obj._m_show(obj)
@@ -141,8 +165,14 @@ cdef void _smart_object_show(Evas_Object *o) with gil:
 
 
 cdef void _smart_object_hide(Evas_Object *o) with gil:
-    cdef SmartObject obj
-    obj = <SmartObject>evas_object_data_get(o, "python-eo")
+    cdef:
+        void *tmp
+        SmartObject obj
+    tmp = evas_object_data_get(o, "python-eo")
+    if tmp == NULL:
+        EINA_LOG_DOM_WARN(PY_EFL_EVAS_LOG_DOMAIN, "obj is NULL!", NULL)
+        return
+    obj = <SmartObject>tmp
     if obj._m_hide is not None:
         try:
             obj._m_hide(obj)
@@ -152,8 +182,14 @@ cdef void _smart_object_hide(Evas_Object *o) with gil:
 
 cdef void _smart_object_color_set(Evas_Object *o,
                                   int r, int g, int b, int a) with gil:
-    cdef SmartObject obj
-    obj = <SmartObject>evas_object_data_get(o, "python-eo")
+    cdef:
+        void *tmp
+        SmartObject obj
+    tmp = evas_object_data_get(o, "python-eo")
+    if tmp == NULL:
+        EINA_LOG_DOM_WARN(PY_EFL_EVAS_LOG_DOMAIN, "obj is NULL!", NULL)
+        return
+    obj = <SmartObject>tmp
     if obj._m_color_set is not None:
         try:
             obj._m_color_set(obj, r, g, b, a)
@@ -162,9 +198,15 @@ cdef void _smart_object_color_set(Evas_Object *o,
 
 
 cdef void _smart_object_clip_set(Evas_Object *o, Evas_Object *clip) with gil:
-    cdef SmartObject obj
-    cdef Object other
-    obj = <SmartObject>evas_object_data_get(o, "python-eo")
+    cdef:
+        void *tmp
+        SmartObject obj
+        Object other
+    tmp = evas_object_data_get(o, "python-eo")
+    if tmp == NULL:
+        EINA_LOG_DOM_WARN(PY_EFL_EVAS_LOG_DOMAIN, "obj is NULL!", NULL)
+        return
+    obj = <SmartObject>tmp
     other = object_from_instance(clip)
     if obj._m_clip_set is not None:
         try:
@@ -174,8 +216,14 @@ cdef void _smart_object_clip_set(Evas_Object *o, 
Evas_Object *clip) with gil:
 
 
 cdef void _smart_object_clip_unset(Evas_Object *o) with gil:
-    cdef SmartObject obj
-    obj = <SmartObject>evas_object_data_get(o, "python-eo")
+    cdef:
+        void *tmp
+        SmartObject obj
+    tmp = evas_object_data_get(o, "python-eo")
+    if tmp == NULL:
+        EINA_LOG_DOM_WARN(PY_EFL_EVAS_LOG_DOMAIN, "obj is NULL!", NULL)
+        return
+    obj = <SmartObject>tmp
     if obj._m_clip_unset is not None:
         try:
             obj._m_clip_unset(obj)
@@ -184,8 +232,14 @@ cdef void _smart_object_clip_unset(Evas_Object *o) with 
gil:
 
 
 cdef void _smart_object_calculate(Evas_Object *o) with gil:
-    cdef SmartObject obj
-    obj = <SmartObject>evas_object_data_get(o, "python-eo")
+    cdef:
+        void *tmp
+        SmartObject obj
+    tmp = evas_object_data_get(o, "python-eo")
+    if tmp == NULL:
+        EINA_LOG_DOM_WARN(PY_EFL_EVAS_LOG_DOMAIN, "obj is NULL!", NULL)
+        return
+    obj = <SmartObject>tmp
     if obj._m_calculate is not None:
         try:
             obj._m_calculate(obj)
@@ -194,9 +248,15 @@ cdef void _smart_object_calculate(Evas_Object *o) with gil:
 
 
 cdef void _smart_object_member_add(Evas_Object *o, Evas_Object *clip) with gil:
-    cdef SmartObject obj
-    cdef Object other
-    obj = <SmartObject>evas_object_data_get(o, "python-eo")
+    cdef:
+        void *tmp
+        SmartObject obj
+        Object other
+    tmp = evas_object_data_get(o, "python-eo")
+    if tmp == NULL:
+        EINA_LOG_DOM_WARN(PY_EFL_EVAS_LOG_DOMAIN, "obj is NULL!", NULL)
+        return
+    obj = <SmartObject>tmp
     other = object_from_instance(clip)
     if obj._m_member_add is not None:
         try:
@@ -206,9 +266,15 @@ cdef void _smart_object_member_add(Evas_Object *o, 
Evas_Object *clip) with gil:
 
 
 cdef void _smart_object_member_del(Evas_Object *o, Evas_Object *clip) with gil:
-    cdef SmartObject obj
-    cdef Object other
-    obj = <SmartObject>evas_object_data_get(o, "python-eo")
+    cdef:
+        void *tmp
+        SmartObject obj
+        Object other
+    tmp = evas_object_data_get(o, "python-eo")
+    if tmp == NULL:
+        EINA_LOG_DOM_WARN(PY_EFL_EVAS_LOG_DOMAIN, "obj is NULL!", NULL)
+        return
+    obj = <SmartObject>tmp
     other = object_from_instance(clip)
     if obj._m_member_del is not None:
         try:
@@ -219,9 +285,16 @@ cdef void _smart_object_member_del(Evas_Object *o, 
Evas_Object *clip) with gil:
 
 cdef void _smart_callback(void *data,
                           Evas_Object *o, void *event_info) with gil:
-    cdef SmartObject obj
-    cdef object event, ei
-    obj = <SmartObject>evas_object_data_get(o, "python-eo")
+
+    cdef:
+        void *tmp
+        SmartObject obj
+        object event, ei
+    tmp = evas_object_data_get(o, "python-eo")
+    if tmp == NULL:
+        EINA_LOG_DOM_WARN(PY_EFL_EVAS_LOG_DOMAIN, "obj is NULL!", NULL)
+        return
+    obj = <SmartObject>tmp
     event = <object>data
     ei = <object>event_info
     lst = tuple(obj._smart_callbacks[event])
diff --git a/examples/elementary/test.py b/examples/elementary/test.py
index 462885f..d99dadd 100755
--- a/examples/elementary/test.py
+++ b/examples/elementary/test.py
@@ -5,7 +5,9 @@ import logging
 elog = logging.getLogger("efl")
 elog.setLevel(logging.INFO)
 
-elog_form = logging.Formatter("[%(name)s] %(levelname)s - %(message)s")
+elog_form = logging.Formatter(
+    "[%(name)s] %(levelname)s in %(funcName)s:%(lineno)d - %(message)s"
+    )
 elog_hdlr = logging.StreamHandler()
 elog_hdlr.setFormatter(elog_form)
 
@@ -14,6 +16,9 @@ elog.addHandler(elog_hdlr)
 eolog = logging.getLogger("efl.eo")
 eolog.setLevel(logging.INFO)
 
+evaslog = logging.getLogger("efl.evas")
+evaslog.setLevel(logging.INFO)
+
 import os
 
 from efl.evas import EVAS_HINT_EXPAND, EVAS_HINT_FILL

-- 


Reply via email to