[glibmm] examples: dispatcher: Use std::thread and friends.



commit fbf083af25666e35b5a734b3ed52dd0f6f9d9a7a
Author: Murray Cumming <murrayc murrayc com>
Date:   Fri Nov 6 13:22:26 2015 +0100

    examples: dispatcher: Use std::thread and friends.
    
    Instead of deprecated Glib::Threads::*.

 examples/thread/dispatcher.cc  |   10 +++++++-
 examples/thread/dispatcher2.cc |   42 +++++++++++++++++++++++++++------------
 glib/src/threads.hg            |    2 +-
 3 files changed, 38 insertions(+), 16 deletions(-)
---
diff --git a/examples/thread/dispatcher.cc b/examples/thread/dispatcher.cc
index 84868db..85643b0 100644
--- a/examples/thread/dispatcher.cc
+++ b/examples/thread/dispatcher.cc
@@ -12,6 +12,7 @@
 
 #include <algorithm>
 #include <functional>
+#include <thread>
 #include <iostream>
 #include <vector>
 
@@ -45,7 +46,7 @@ private:
   // Note that the thread does not write to the member data at all.  It only
   // reads signal_increment_, which is only written to before the thread is
   // launched.  Therefore, no locking is required.
-  Glib::Threads::Thread*       thread_;
+  std::thread*        thread_;
   int                 id_;
   unsigned int        progress_;
   Glib::Dispatcher    signal_increment_;
@@ -102,12 +103,17 @@ int ThreadProgress::id() const
 void ThreadProgress::launch()
 {
   // Create a joinable thread.
-  thread_ = Glib::Threads::Thread::create(sigc::mem_fun(*this, &ThreadProgress::thread_function));
+  thread_ = new std::thread(
+    [this] ()
+    {
+     thread_function();
+    });
 }
 
 void ThreadProgress::join()
 {
   thread_->join();
+  delete thread_;
   thread_ = nullptr;
 }
 
diff --git a/examples/thread/dispatcher2.cc b/examples/thread/dispatcher2.cc
index cd0faf2..0a80bdc 100644
--- a/examples/thread/dispatcher2.cc
+++ b/examples/thread/dispatcher2.cc
@@ -22,6 +22,9 @@
 
 #include <glibmm.h>
 #include <sstream>
+#include <thread>
+#include <mutex>
+#include <condition_variable>
 #include <iostream>
 
 
@@ -47,9 +50,9 @@ private:
   Glib::Dispatcher  signal_increment_;  
   Glib::Dispatcher* signal_finished_ptr_;
 
-  Glib::Threads::Mutex       startup_mutex_;
-  Glib::Threads::Cond        startup_cond_;
-  Glib::Threads::Thread*     thread_;
+  std::mutex startup_mutex_;
+  std::condition_variable  startup_cond_;
+  std::thread* thread_;
   
   static type_signal_end signal_end_;
 
@@ -77,7 +80,8 @@ ThreadTimer::ThreadTimer()
   // Create a new Glib::Dispatcher that is attached to the default main context,
   signal_increment_ (),
   // This pointer will be initialized later by the 2nd thread.
-  signal_finished_ptr_ (nullptr)
+  signal_finished_ptr_ (nullptr),
+  thread_ (nullptr)
 {
   // Connect the cross-thread signal.
   signal_increment_.connect(sigc::mem_fun(*this, &ThreadTimer::timer_increment));
@@ -92,15 +96,21 @@ void ThreadTimer::launch()
   // order to access the Glib::Dispatcher object instantiated by the 2nd thread.
   // So, let's do some kind of hand-shake using a mutex and a condition
   // variable.
-  Glib::Threads::Mutex::Lock lock (startup_mutex_);
+  std::unique_lock<std::mutex> lock (startup_mutex_);
 
-  // Create a joinable thread -- it needs to be joined, otherwise it's a memory leak.
-  thread_ = Glib::Threads::Thread::create(
-      sigc::mem_fun(*this, &ThreadTimer::thread_function));
+  // Create a joinable thread -- it needs to be joined, otherwise its destructor will block.
+  thread_ = new std::thread(
+    [this] ()
+    {
+      thread_function();
+    });
 
   // Wait for the 2nd thread's startup notification.
-  while(!signal_finished_ptr_)
-    startup_cond_.wait(startup_mutex_);
+  startup_cond_.wait(lock,
+    [this] () -> bool
+    {
+      return signal_finished_ptr_;
+    });
 }
 
 void ThreadTimer::signal_finished_emit()
@@ -110,7 +120,11 @@ void ThreadTimer::signal_finished_emit()
 
   // wait for the thread to join
   if(thread_)
+  {
     thread_->join();
+    delete thread_;
+    thread_ = nullptr;
+  }
 
   signal_finished_ptr_ = nullptr;
 }
@@ -166,7 +180,7 @@ void ThreadTimer::thread_function()
 
   // We need to lock while creating the Glib::Dispatcher instance,
   // in order to ensure memory visibility.
-  Glib::Threads::Mutex::Lock lock (startup_mutex_);
+  std::unique_lock<std::mutex> lock (startup_mutex_);
 
   // create a new dispatcher, that is connected to the newly
   // created MainContext
@@ -177,8 +191,10 @@ void ThreadTimer::thread_function()
   signal_finished_ptr_ = &signal_finished;
 
   // Tell the launcher thread that everything is in place now.
-  startup_cond_.signal();
-  lock.release();
+  //We unlock before notifying, because that is what the documentation suggests:
+  //http://en.cppreference.com/w/cpp/thread/condition_variable
+  lock.unlock();
+  startup_cond_.notify_one();
 
   // start the mainloop
   mainloop->run();
diff --git a/glib/src/threads.hg b/glib/src/threads.hg
index 21774cc..3fa16f7 100644
--- a/glib/src/threads.hg
+++ b/glib/src/threads.hg
@@ -37,7 +37,7 @@ namespace Glib
 {
 
 /**
- * @deprecated The entire Glib::Threads API is deprecated in favour of the 
+ * @deprecated The entire Glib::Threads API is deprecated in favor of the
  * standard C++ concurrency API in C++11 and C++14.
  */
 namespace Threads


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