diff options
author | Kjell Ahlstedt <kjell.ahlstedt@bredband.net> | 2012-02-28 16:13:03 +0100 |
---|---|---|
committer | Kjell Ahlstedt <kjell.ahlstedt@bredband.net> | 2012-02-28 16:13:03 +0100 |
commit | 5a59b62212f0b8875da815a5d136d7a0c2899fdf (patch) | |
tree | d5d66f3df76df93b244cce2dd789537afae3fc34 | |
parent | 423e6fbb104bb08ab876f1642b043de996467f0b (diff) | |
download | glibmm-5a59b62212f0b8875da815a5d136d7a0c2899fdf.tar.gz |
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.
-rw-r--r-- | ChangeLog | 23 | ||||
-rw-r--r-- | examples/network/resolver.cc | 3 | ||||
-rw-r--r-- | examples/network/socket-client.cc | 2 | ||||
-rw-r--r-- | examples/network/socket-server.cc | 2 | ||||
-rw-r--r-- | examples/thread/dispatcher.cc | 2 | ||||
-rw-r--r-- | examples/thread/dispatcher2.cc | 2 | ||||
-rw-r--r-- | examples/thread/thread.cc | 4 | ||||
-rw-r--r-- | glib/src/thread.ccg | 24 | ||||
-rw-r--r-- | glib/src/threads.ccg | 14 | ||||
-rw-r--r-- | glib/src/threads.hg | 19 |
10 files changed, 67 insertions, 28 deletions
@@ -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 1d6303ca..d1ef97a3 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 b1f08715..29122573 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 d99a176a..d5078596 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 7725b3ee..1ed0c9c2 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 63b06d33..d42e2246 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 581bdf5c..6cfa904e 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 09e53b9c..990ec6b9 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 78369d53..7133a3d6 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 c19547e1..44905a00 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 = 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). |