[glibmm] Fix exceptions thrown by Thread::create() and Threads::Thread::create.



commit 5a59b62212f0b8875da815a5d136d7a0c2899fdf
Author: Kjell Ahlstedt <kjell ahlstedt bredband net>
Date:   Tue Feb 28 16:13:03 2012 +0100

    Fix exceptions thrown by Thread::create() and Threads::Thread::create.
    
    * glib/src/thread.ccg: create(): Call g_thread_try_new() instead of
    g_thread_new(). Throw a Glib::ThreadError when appropriate, instead of calling
    Glib::Error::throw_exception(), which would throw Glib::Threads::ThreadError.
    * glib/src/threads.ccg:create(): Call g_thread_try_new() instead of
    g_thread_new(). Remove parameter 'joinable'.
    * glib/src/threads.hg: Remove parameter 'joinable'. Remove comments about
    non-joinable threads and thread priorities.
    * examples/network/resolver.cc:
    * examples/network/socket-client.cc:
    * examples/network/socket-server.cc:
    * examples/thread/dispatcher.cc:
    * examples/thread/dispatcher2.cc:
    * examples/thread/thread.cc: Remove parameter 'joinable' in calls to
    Glib::Threads::Thread::create(). Bug #640029.

 ChangeLog                         |   23 +++++++++++++++++++++--
 examples/network/resolver.cc      |    3 +--
 examples/network/socket-client.cc |    2 +-
 examples/network/socket-server.cc |    2 +-
 examples/thread/dispatcher.cc     |    2 +-
 examples/thread/dispatcher2.cc    |    2 +-
 examples/thread/thread.cc         |    4 ++--
 glib/src/thread.ccg               |   24 +++++++++++++++++++++---
 glib/src/threads.ccg              |   14 +++++++++++---
 glib/src/threads.hg               |   19 +++++++------------
 10 files changed, 67 insertions(+), 28 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index d417621..c00328f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,24 @@
 2012-02-28  Kjell Ahlstedt  <kjell ahlstedt bredband net>
- 
+
+	Fix exceptions thrown by Thread::create() and Threads::Thread::create.
+
+	* glib/src/thread.ccg: create(): Call g_thread_try_new() instead of
+	g_thread_new(). Throw a Glib::ThreadError when appropriate, instead of calling
+	Glib::Error::throw_exception(), which would throw Glib::Threads::ThreadError.
+	* glib/src/threads.ccg:create(): Call g_thread_try_new() instead of
+	g_thread_new(). Remove parameter 'joinable'.
+	* glib/src/threads.hg: Remove parameter 'joinable'. Remove comments about
+	non-joinable threads and thread priorities.
+	* examples/network/resolver.cc:
+	* examples/network/socket-client.cc:
+	* examples/network/socket-server.cc:
+	* examples/thread/dispatcher.cc:
+	* examples/thread/dispatcher2.cc:
+	* examples/thread/thread.cc: Remove parameter 'joinable' in calls to
+	Glib::Threads::Thread::create(). Bug #640029.
+
+2012-02-28  Kjell Ahlstedt  <kjell ahlstedt bredband net>
+
 	Fix the build with --disable-deprecated-api.
 
 	* glib/glibmm/main.cc: Call get_time() instead of the deprecated
@@ -15,7 +34,7 @@
 	* tools/m4/class_shared.m4: Define _IS_DEPRECATED. Bug #640029.
 
 2012-02-28  Kjell Ahlstedt  <kjell ahlstedt bredband net>
- 
+
 	generate_wrap_init.pl: Improve reg. of exception classes in sub-namespaces.
 
 	* tools/generate_wrap_init.pl.in: When there are exception classes in sub-
diff --git a/examples/network/resolver.cc b/examples/network/resolver.cc
index 1d6303c..d1ef97a 100644
--- a/examples/network/resolver.cc
+++ b/examples/network/resolver.cc
@@ -214,8 +214,7 @@ start_threaded_lookups (char **argv, int argc)
     for (i = 0; i < argc; i++)
     {
         Glib::Threads::Thread::create (sigc::bind (sigc::ptr_fun (lookup_thread),
-                                          argv[i]),
-                              false);
+                                          argv[i]));
     }
 }
 
diff --git a/examples/network/socket-client.cc b/examples/network/socket-client.cc
index b1f0871..2912257 100644
--- a/examples/network/socket-client.cc
+++ b/examples/network/socket-client.cc
@@ -128,7 +128,7 @@ main (int argc,
     if (cancel_timeout)
     {
         cancellable = Gio::Cancellable::create ();
-        Glib::Threads::Thread::create (sigc::bind (sigc::ptr_fun (cancel_thread), cancellable), false);
+        Glib::Threads::Thread::create (sigc::bind (sigc::ptr_fun (cancel_thread), cancellable));
     }
 
     loop = Glib::MainLoop::create ();
diff --git a/examples/network/socket-server.cc b/examples/network/socket-server.cc
index d99a176..d507859 100644
--- a/examples/network/socket-server.cc
+++ b/examples/network/socket-server.cc
@@ -124,7 +124,7 @@ main (int argc,
     if (cancel_timeout)
     {
         cancellable = Gio::Cancellable::create ();
-        Glib::Threads::Thread::create (sigc::bind (sigc::ptr_fun (cancel_thread), cancellable), false);
+        Glib::Threads::Thread::create (sigc::bind (sigc::ptr_fun (cancel_thread), cancellable));
     }
 
     loop = Glib::MainLoop::create ();
diff --git a/examples/thread/dispatcher.cc b/examples/thread/dispatcher.cc
index 7725b3e..1ed0c9c 100644
--- a/examples/thread/dispatcher.cc
+++ b/examples/thread/dispatcher.cc
@@ -102,7 +102,7 @@ int ThreadProgress::id() const
 void ThreadProgress::launch()
 {
   // Create a joinable thread.
-  thread_ = Glib::Threads::Thread::create(sigc::mem_fun(*this, &ThreadProgress::thread_function), true);
+  thread_ = Glib::Threads::Thread::create(sigc::mem_fun(*this, &ThreadProgress::thread_function));
 }
 
 void ThreadProgress::join()
diff --git a/examples/thread/dispatcher2.cc b/examples/thread/dispatcher2.cc
index 63b06d3..d42e224 100644
--- a/examples/thread/dispatcher2.cc
+++ b/examples/thread/dispatcher2.cc
@@ -97,7 +97,7 @@ void ThreadTimer::launch()
 
   // 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), true);
+      sigc::mem_fun(*this, &ThreadTimer::thread_function));
 
   // Wait for the 2nd thread's startup notification.
   while(signal_finished_ptr_ == NULL)
diff --git a/examples/thread/thread.cc b/examples/thread/thread.cc
index 581bdf5..6cfa904 100644
--- a/examples/thread/thread.cc
+++ b/examples/thread/thread.cc
@@ -98,10 +98,10 @@ int main(int, char**)
   MessageQueue queue;
 
   Glib::Threads::Thread *const producer = Glib::Threads::Thread::create(
-      sigc::mem_fun(queue, &MessageQueue::producer), true);
+      sigc::mem_fun(queue, &MessageQueue::producer));
 
   Glib::Threads::Thread *const consumer = Glib::Threads::Thread::create(
-      sigc::mem_fun(queue, &MessageQueue::consumer), true);
+      sigc::mem_fun(queue, &MessageQueue::consumer));
 
   producer->join();
   consumer->join();
diff --git a/glib/src/thread.ccg b/glib/src/thread.ccg
index 09e53b9..990ec6b 100644
--- a/glib/src/thread.ccg
+++ b/glib/src/thread.ccg
@@ -76,8 +76,21 @@ Thread* Thread::create(const sigc::slot<void>& slot, bool /* joinable */)
   // Make a copy of slot on the heap
   sigc::slot_base *const slot_copy = new sigc::slot<void>(slot);
 
-  GThread *const thread = g_thread_new(NULL, 
-      &call_thread_entry_slot, slot_copy);
+  GError* error = 0;
+
+  GThread *const thread = g_thread_try_new(NULL,
+      &call_thread_entry_slot, slot_copy, &error);
+
+  if(error)
+  {
+    delete slot_copy;
+    // Glib::Error::throw_exception() will probably wrap G_THREAD_ERROR in a
+    // Glib::Threads::ThreadError instance, but we want a Glib::ThreadError.
+    if (error->domain == G_THREAD_ERROR)
+      throw Glib::ThreadError(error);
+    else
+      Glib::Error::throw_exception(error);
+  }
 
   return reinterpret_cast<Thread*>(thread);
 }
@@ -98,7 +111,12 @@ Thread* Thread::create(const sigc::slot<void>& slot, unsigned long stack_size,
   if(error)
   {
     delete slot_copy;
-    Glib::Error::throw_exception(error);
+    // Glib::Error::throw_exception() will probably wrap G_THREAD_ERROR in a
+    // Glib::Threads::ThreadError instance, but we want a Glib::ThreadError.
+    if (error->domain == G_THREAD_ERROR)
+      throw Glib::ThreadError(error);
+    else
+      Glib::Error::throw_exception(error);
   }
 
   return reinterpret_cast<Thread*>(thread);
diff --git a/glib/src/threads.ccg b/glib/src/threads.ccg
index 78369d5..7133a3d 100644
--- a/glib/src/threads.ccg
+++ b/glib/src/threads.ccg
@@ -65,13 +65,21 @@ namespace Threads
 /**** Glib::Thread *********************************************************/
 
 // static
-Thread* Thread::create(const sigc::slot<void>& slot, bool /* joinable */)
+Thread* Thread::create(const sigc::slot<void>& slot)
 {
   // Make a copy of slot on the heap
   sigc::slot_base *const slot_copy = new sigc::slot<void>(slot);
 
-  GThread *const thread = g_thread_new(NULL, 
-      &call_thread_entry_slot, slot_copy);
+  GError* error = 0;
+
+  GThread *const thread = g_thread_try_new(NULL,
+      &call_thread_entry_slot, slot_copy, &error);
+
+  if(error)
+  {
+    delete slot_copy;
+    Glib::Error::throw_exception(error);
+  }
 
   return reinterpret_cast<Thread*>(thread);
 }
diff --git a/glib/src/threads.hg b/glib/src/threads.hg
index c19547e..44905a0 100644
--- a/glib/src/threads.hg
+++ b/glib/src/threads.hg
@@ -53,10 +53,8 @@ _WRAP_GERROR(ThreadError, GThreadError, G_THREAD_ERROR, NO_GTYPE)
 
 /** Represents a running thread.
  * An instance of this class can only be obtained with create(), self(),
- * or wrap(GThread*).  It's not possible to delete a Thread object.  If the
- * thread is @em not joinable, its resources will be freed automatically
- * when it exits.  Otherwise, if the thread @em is joinable, you must call
- * join() to avoid a memory leak.
+ * or wrap(GThread*).  It's not possible to delete a Thread object.
+ * You must call join() to avoid a memory leak.
  *
  * @note g_thread_exit() is not wrapped, because that function exits a thread
  * without any cleanup.  That's especially dangerous in C++ code, since the
@@ -74,9 +72,8 @@ public:
   class Exit;
 
   //See http://bugzilla.gnome.org/show_bug.cgi?id=512348 about the sigc::trackable issue.
-  /** Creates a new thread with the priority <tt>THREAD_PRIORITY_NORMAL</tt>.
-   * If @a joinable is @c true, you can wait for this thread's termination by
-   * calling join().  Otherwise the thread will just disappear, when ready.
+  /** Creates a new thread.
+   * You can wait for this thread's termination by calling join().
    *
    * The new thread executes the function or method @a slot points to.  You can
    * pass additional arguments using sigc::bind().  If the thread was created
@@ -87,11 +84,10 @@ public:
    * class concerned should not derive from sigc::trackable.
    *
    * @param slot A slot to execute in the new thread.
-   * @param joinable This parameter is now ignored because Threads are now always joinable.
    * @return The new Thread* on success.
    * @throw Glib::Threads::ThreadError
    */
-  static Thread* create(const sigc::slot<void>& slot, bool joinable = true);
+  static Thread* create(const sigc::slot<void>& slot);
 
   /** Returns the Thread* corresponding to the calling thread.
    * @return The current thread.
@@ -102,8 +98,7 @@ public:
    * Waits until the thread finishes, i.e. the slot, as given to create(),
    * returns or g_thread_exit() is called by the thread.  (Calling
    * g_thread_exit() in a C++ program should be avoided.)  All resources of
-   * the thread including the Glib::Threads::Thread object are released.  The thread
-   * must have been created with <tt>joinable&nbsp;=&nbsp;true</tt>.
+   * the thread including the Glib::Threads::Thread object are released.
    */
   void join();
 
@@ -140,7 +135,7 @@ private:
 class Thread::Exit
 {};
 
-/** @relates Glib::Thread */
+/** @relates Glib::Threads::Thread */
 Thread* wrap(GThread* gobject);
 
 /** Represents a mutex (mutual exclusion).



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