emotion: fix some race condition.
authorcedric <cedric>
Thu, 11 Aug 2011 16:16:10 +0000 (16:16 +0000)
committercedric <cedric@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 11 Aug 2011 16:16:10 +0000 (16:16 +0000)
git-svn-id: http://svn.enlightenment.org/svn/e/trunk/emotion@62355 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/modules/gstreamer/emotion_alloc.c
src/modules/gstreamer/emotion_gstreamer.c
src/modules/gstreamer/emotion_gstreamer.h

index 2736fb1..cf376e2 100644 (file)
@@ -40,6 +40,7 @@ emotion_gstreamer_message_alloc(Emotion_Gstreamer_Video *ev,
    send = malloc(sizeof (Emotion_Gstreamer_Message));
    if (!send) return NULL;
 
+   ev->out++;
    send->ev = ev;
    send->msg = gst_message_ref(msg);
 
@@ -49,6 +50,11 @@ emotion_gstreamer_message_alloc(Emotion_Gstreamer_Video *ev,
 void
 emotion_gstreamer_message_free(Emotion_Gstreamer_Message *send)
 {
+   send->ev->in++;
+
+   if (send->ev->in == send->ev->out && send->ev->delete_me)
+     em_shutdown(send->ev);
+
    gst_message_unref(send->msg);
    free(send);
 }
index e65d822..f0449cf 100644 (file)
@@ -19,8 +19,6 @@ static unsigned char  em_init                     (Evas_Object     *obj,
                                                    void           **emotion_video,
                                                    Emotion_Module_Options *opt);
 
-static int            em_shutdown                 (void           *video);
-
 static unsigned char  em_file_open                (const char     *file,
                                                    Evas_Object     *obj,
                                                    void            *video);
@@ -334,6 +332,7 @@ em_init(Evas_Object            *obj,
    ev->vis = EMOTION_VIS_NONE;
    ev->volume = 0.8;
    ev->play_started = 0;
+   ev->delete_me = EINA_FALSE;
 
    *emotion_video = ev;
 
@@ -345,7 +344,7 @@ failure:
    return 0;
 }
 
-static int
+int
 em_shutdown(void *video)
 {
    Emotion_Gstreamer_Video *ev;
@@ -362,6 +361,12 @@ em_shutdown(void *video)
         ev->thread = NULL;
      }
 
+   if (ev->in != ev->out)
+     {
+        ev->delete_me = EINA_TRUE;
+        return 1;
+     }
+
    if (ev->eos_bus)
      {
         gst_object_unref(GST_OBJECT(ev->eos_bus));
@@ -1403,7 +1408,7 @@ _eos_main_fct(void *data)
    ev = send->ev;
    msg = send->msg;
 
-   if (ev->play_started)
+   if (ev->play_started && !ev->delete_me)
      {
         _emotion_playback_started(ev->obj);
         ev->play_started = 0;
@@ -1425,25 +1430,29 @@ _eos_main_fct(void *data)
            break;
         }
       case GST_MESSAGE_EOS:
-         ev->play = 0;
-         _emotion_decode_stop(ev->obj);
-         _emotion_playback_finished(ev->obj);
+         if (!ev->delete_me)
+           {
+              ev->play = 0;
+              _emotion_decode_stop(ev->obj);
+              _emotion_playback_finished(ev->obj);
+           }
          break;
       case GST_MESSAGE_TAG:
-        {
-           GstTagList *new_tags;
-           gst_message_parse_tag(msg, &new_tags);
-           if (new_tags)
-             {
-                gst_tag_list_foreach(new_tags,
-                                     (GstTagForeachFunc)_for_each_tag,
-                                     ev);
-                gst_tag_list_free(new_tags);
-             }
-           break;
-        }
+         if (!ev->delete_me)
+           {
+              GstTagList *new_tags;
+              gst_message_parse_tag(msg, &new_tags);
+              if (new_tags)
+                {
+                   gst_tag_list_foreach(new_tags,
+                                        (GstTagForeachFunc)_for_each_tag,
+                                        ev);
+                   gst_tag_list_free(new_tags);
+                }
+           }
+         break;
       case GST_MESSAGE_ASYNC_DONE:
-         _emotion_seek_done(ev->obj);
+         if (!ev->delete_me) _emotion_seek_done(ev->obj);
          break;
       default:
          ERR("bus say: %s [%i]",
index 40b2e5e..9feea1e 100644 (file)
@@ -86,11 +86,15 @@ struct _Emotion_Gstreamer_Video
 
    Emotion_Vis       vis;
 
+   int               in;
+   int               out;
+
    Eina_Bool         play         : 1;
    Eina_Bool         play_started : 1;
    Eina_Bool         video_mute   : 1;
    Eina_Bool         audio_mute   : 1;
    Eina_Bool         pipeline_parsed : 1;
+   Eina_Bool         delete_me    : 1;
 };
 
 struct _EvasVideoSink {
@@ -193,4 +197,6 @@ void emotion_gstreamer_message_free(Emotion_Gstreamer_Message *send);
 Eina_Bool _emotion_gstreamer_video_pipeline_parse(Emotion_Gstreamer_Video *ev,
                                                   Eina_Bool force);
 
+int em_shutdown(void *video);
+
 #endif /* __EMOTION_GSTREAMER_H__ */