ekiga r6249 - in trunk: . lib/engine/display/common lib/engine/display/dx lib/engine/display/x



Author: mschneid
Date: Thu May  8 06:45:37 2008
New Revision: 6249
URL: http://svn.gnome.org/viewvc/ekiga?rev=6249&view=rev

Log:
Fix #528632. Only create display thread once for Ekiga's lifetime.


Modified:
   trunk/ChangeLog
   trunk/lib/engine/display/common/display-manager-common.cpp
   trunk/lib/engine/display/common/display-manager-common.h
   trunk/lib/engine/display/dx/display-manager-dx.cpp
   trunk/lib/engine/display/x/display-manager-x.cpp

Modified: trunk/lib/engine/display/common/display-manager-common.cpp
==============================================================================
--- trunk/lib/engine/display/common/display-manager-common.cpp	(original)
+++ trunk/lib/engine/display/common/display-manager-common.cpp	Thu May  8 06:45:37 2008
@@ -58,66 +58,61 @@
 
 void GMDisplayManager::start ()
 {
-  Ekiga::DisplayManager::start();
-
-  /* State for last frame */
-  last_frame.display = UNSET;
-  last_frame.local_width = 0;
-  last_frame.local_height = 0;
-  last_frame.remote_width = 0;
-  last_frame.remote_height = 0;  
-  last_frame.zoom = 0;
-  last_frame.embedded_x = 0;
-  last_frame.embedded_y = 0;  
-
-  current_frame.local_width = 0;
-  current_frame.local_height = 0;
-  current_frame.remote_width = 0;
-  current_frame.remote_height = 0;
-
-  /* Initialisation */
-  end_thread = false;
-  video_disabled = false;
-  first_frame_received = false;
-  update_required.local = false;
-  update_required.remote = false;
-
-//  this->Resume ();
-  this->Restart ();
-  thread_sync_point.Wait ();
+  init_thread = true;
+  run_thread.Signal();
+  thread_initialised.Wait();
 }
 
-void GMDisplayManager::stop () {
-  end_thread = true;
-  /* Wait for the Main () method to be terminated */
-  frame_available_sync_point.Signal();
-  PWaitAndSignal m(quit_mutex);
-
-  /* This is common to all output classes */
-  lframeStore.SetSize (0);
-  rframeStore.SetSize (0);
+void GMDisplayManager::stop () 
+{
 
-  Ekiga::DisplayManager::stop();
+  uninit_thread = true;
+  run_thread.Signal();
+  thread_uninitialised.Wait();
 }
 
 void
 GMDisplayManager::Main ()
 {
-  bool do_sync;
+  bool do_sync = false;
+  bool initialised_thread = false;
   UpdateRequired sync_required;
 
-  PWaitAndSignal m(quit_mutex);
-  thread_sync_point.Signal ();
+  PWaitAndSignal m(thread_ended);
+  thread_created.Signal ();
 
   while (!end_thread) {
-    frame_available_sync_point.Wait(250);
-    var_mutex.Wait ();
-      do_sync = first_frame_received;
-      if (first_frame_received)
-        sync_required = redraw();
-    var_mutex.Signal ();
-    if (do_sync)
-      sync(sync_required);
+    if (initialised_thread)
+      run_thread.Wait(250);
+    else
+      run_thread.Wait();
+
+    if (init_thread) {
+      init();
+      init_thread = false;
+      initialised_thread = true;
+      thread_initialised.Signal();
+    }
+
+    if (initialised_thread) {
+      var_mutex.Wait ();
+        do_sync = first_frame_received;
+        if (first_frame_received)
+          sync_required = redraw();
+      var_mutex.Signal ();
+      if (do_sync)
+        sync(sync_required);
+    }
+
+    if (uninit_thread) {
+      var_mutex.Wait ();
+      close_frame_display ();
+      var_mutex.Signal ();
+      uninit();
+      uninit_thread = false;
+      initialised_thread = false;
+      thread_uninitialised.Signal();
+    }
   }
 
   var_mutex.Wait ();
@@ -193,9 +188,40 @@
   if ((local_display_info.display == REMOTE_VIDEO) && local)
       return;
 
-  frame_available_sync_point.Signal();
+  run_thread.Signal();
+}
+
+
+void GMDisplayManager::init()
+{
+  /* State for last frame */
+  last_frame.display = UNSET;
+  last_frame.local_width = 0;
+  last_frame.local_height = 0;
+  last_frame.remote_width = 0;
+  last_frame.remote_height = 0;  
+  last_frame.zoom = 0;
+  last_frame.embedded_x = 0;
+  last_frame.embedded_y = 0;  
+
+  current_frame.local_width = 0;
+  current_frame.local_height = 0;
+  current_frame.remote_width = 0;
+  current_frame.remote_height = 0;
+
+  /* Initialisation */
+  video_disabled = false;
+  first_frame_received = false;
+  update_required.local = false;
+  update_required.remote = false;
+
 }
 
+void GMDisplayManager::uninit () {
+  /* This is common to all output classes */
+  lframeStore.SetSize (0);
+  rframeStore.SetSize (0);
+}
 
 bool 
 GMDisplayManager::frame_display_change_needed ()

Modified: trunk/lib/engine/display/common/display-manager-common.h
==============================================================================
--- trunk/lib/engine/display/common/display-manager-common.h	(original)
+++ trunk/lib/engine/display/common/display-manager-common.h	Thu May  8 06:45:37 2008
@@ -186,16 +186,26 @@
    */
   virtual void sync(UpdateRequired sync_required) = 0;
 
+  /* DESCRIPTION  :  /
+   * BEHAVIOR     :  Initialises the display
+   * PRE          :  /
+   */
+  virtual void init ();
+
+  /* DESCRIPTION  :  /
+   * BEHAVIOR     :  Uninitialises the frame containers
+   * PRE          :  /
+   */
+  virtual void uninit ();
+
   virtual void get_display_info (DisplayInfo & _display_info) {
         PWaitAndSignal m(display_info_mutex);
         _display_info = display_info;
   }
 
-
-  PMutex display_info_mutex; /* To protect the DisplayInfo object */
-
   /* This variable has to be protected by display_info_mutex */
   DisplayInfo display_info;
+  PMutex display_info_mutex; /* To protect the DisplayInfo object */
 
   PBYTEArray lframeStore;
   PBYTEArray rframeStore;
@@ -203,17 +213,22 @@
   FrameInfo last_frame;
   FrameInfo current_frame;
   
-  bool end_thread;
   bool first_frame_received;
   bool video_disabled;
   UpdateRequired update_required;
 
+  PSyncPoint run_thread;                  /* To signal the thread shall execute its tasks */
+  bool end_thread;
+  bool init_thread;
+  bool uninit_thread;
+
+  PSyncPoint thread_created;              /* To signal that the thread has been created */
+  PSyncPoint thread_initialised;          /* To signal that the thread has been initialised */
+  PSyncPoint thread_uninitialised;        /* To signal that the thread has been uninitialised */
+  PMutex     thread_ended;                /* To exit */
+  
   PMutex var_mutex;      /* To protect variables that are read and written
 			    from various threads */
-  PMutex quit_mutex;     /* To exit */
-
-  PSyncPoint frame_available_sync_point;     /* To signal a new frame has to be displayed  */
-  PSyncPoint thread_sync_point;              /* To signal that the thread has been created */
 
   Ekiga::ServiceCore & core;
   Ekiga::Runtime & runtime;

Modified: trunk/lib/engine/display/dx/display-manager-dx.cpp
==============================================================================
--- trunk/lib/engine/display/dx/display-manager-dx.cpp	(original)
+++ trunk/lib/engine/display/dx/display-manager-dx.cpp	Thu May  8 06:45:37 2008
@@ -41,17 +41,17 @@
 : GMDisplayManager(_core)
 {
   dxWindow = NULL;
-  this->Resume ();
-  thread_sync_point.Wait ();
-  end_thread = true;
 
-  /* Wait for the Main () method to be terminated */
-  frame_available_sync_point.Signal();
-  PWaitAndSignal m(quit_mutex);
+  end_thread = false;
+  this->Resume ();
+  thread_created.Wait ();
 }
 
 GMDisplayManager_dx::~GMDisplayManager_dx ()
 {
+  end_thread = true;
+  run_thread.Signal();
+  thread_ended.Wait();
 }
 
 bool

Modified: trunk/lib/engine/display/x/display-manager-x.cpp
==============================================================================
--- trunk/lib/engine/display/x/display-manager-x.cpp	(original)
+++ trunk/lib/engine/display/x/display-manager-x.cpp	Thu May  8 06:45:37 2008
@@ -54,10 +54,18 @@
   lDisplay = XOpenDisplay (NULL);
 
   pip_window_available = true;
+
+  end_thread = false;
+  this->Resume ();
+  thread_created.Wait ();
 }
 
 GMDisplayManager_x::~GMDisplayManager_x ()
 {
+  end_thread = true;
+  run_thread.Signal();
+  thread_ended.Wait();
+
   if (lDisplay) 
     XCloseDisplay (lDisplay);
   if (rDisplay)



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]