summaryrefslogtreecommitdiff
path: root/libs/glibmm2/examples/thread/dispatcher.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libs/glibmm2/examples/thread/dispatcher.cc')
-rw-r--r--libs/glibmm2/examples/thread/dispatcher.cc226
1 files changed, 0 insertions, 226 deletions
diff --git a/libs/glibmm2/examples/thread/dispatcher.cc b/libs/glibmm2/examples/thread/dispatcher.cc
deleted file mode 100644
index dafd16a36b..0000000000
--- a/libs/glibmm2/examples/thread/dispatcher.cc
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Glib::Dispatcher example -- cross thread signalling
- * by Daniel Elstner <daniel.kitta@gmail.com>
- *
- * modified to only use glibmm
- * by J. Abelardo Gutierrez <jabelardo@cantv.net>
- *
- * Copyright (c) 2002-2003 Free Software Foundation
- */
-
-#include <glibmm.h>
-
-#include <algorithm>
-#include <functional>
-#include <iostream>
-#include <vector>
-
-namespace
-{
-
-/*
- * Note that it does not make sense for this class to inherit from
- * sigc::trackable, as doing so would only give a false sense of security.
- * Once the thread launch has been triggered, the object has to stay alive
- * until the thread has been joined again. The code running in the thread
- * assumes the existence of the object. If it is destroyed earlier, the
- * program will crash, with sigc::trackable or without it.
- */
-class ThreadProgress
-{
-public:
- explicit ThreadProgress(int id);
- virtual ~ThreadProgress();
-
- int id() const;
- void launch();
- void join();
- bool unfinished() const;
-
- sigc::signal<void>& signal_finished();
-
-private:
- enum { ITERATIONS = 100 };
-
- // 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
- // lauched. Therefore, no locking is required.
- Glib::Thread* thread_;
- int id_;
- unsigned int progress_;
- Glib::Dispatcher signal_increment_;
- sigc::signal<void> signal_finished_;
-
- void progress_increment();
- void thread_function();
-};
-
-class Application : public sigc::trackable
-{
-public:
- Application();
- virtual ~Application();
-
- void run();
-
-private:
- Glib::RefPtr<Glib::MainLoop> main_loop_;
- std::vector<ThreadProgress*> progress_threads_;
-
- void launch_threads();
- void on_progress_finished(ThreadProgress* thread_progress);
-};
-
-template <class T>
-class DeletePtr : public std::unary_function<void, T>
-{
-public:
- void operator()(T ptr) const { delete ptr; }
-};
-
-ThreadProgress::ThreadProgress(int id)
-:
- thread_ (0),
- id_ (id),
- progress_ (0)
-{
- // Connect to the cross-thread signal.
- signal_increment_.connect(sigc::mem_fun(*this, &ThreadProgress::progress_increment));
-}
-
-ThreadProgress::~ThreadProgress()
-{
- // It is an error if the thread is still running at this point.
- g_return_if_fail(thread_ == 0);
-}
-
-int ThreadProgress::id() const
-{
- return id_;
-}
-
-void ThreadProgress::launch()
-{
- // Create a joinable thread.
- thread_ = Glib::Thread::create(sigc::mem_fun(*this, &ThreadProgress::thread_function), true);
-}
-
-void ThreadProgress::join()
-{
- thread_->join();
- thread_ = 0;
-}
-
-bool ThreadProgress::unfinished() const
-{
- return (progress_ < ITERATIONS);
-}
-
-sigc::signal<void>& ThreadProgress::signal_finished()
-{
- return signal_finished_;
-}
-
-void ThreadProgress::progress_increment()
-{
- ++progress_;
- std::cout << "Thread " << id_ << ": " << progress_ << '%' << std::endl;
-
- if (progress_ >= ITERATIONS)
- signal_finished_();
-}
-
-void ThreadProgress::thread_function()
-{
- Glib::Rand rand;
-
- for (int i = 0; i < ITERATIONS; ++i)
- {
- Glib::usleep(rand.get_int_range(2000, 20000));
-
- // Tell the main thread to increment the progress value.
- signal_increment_();
- }
-}
-
-Application::Application()
-:
- main_loop_ (Glib::MainLoop::create()),
- progress_threads_ (5)
-{
- // Note that unless you're targetting an embedded platform, you can assume
- // exceptions to be enabled. The #ifdef is only here to make the example
- // compile in either case; you may ignore it otherwise.
-#ifdef GLIBMM_EXCEPTIONS_ENABLED
- try
-#endif
- {
- for (std::vector<ThreadProgress*>::size_type i = 0; i < progress_threads_.size(); ++i)
- {
- ThreadProgress *const progress = new ThreadProgress(i + 1);
- progress_threads_[i] = progress;
-
- progress->signal_finished().connect(
- sigc::bind<1>(sigc::mem_fun(*this, &Application::on_progress_finished), progress));
- }
- }
-#ifdef GLIBMM_EXCEPTIONS_ENABLED
- catch (...)
- {
- // In your own code, you should preferably use a smart pointer
- // to ensure exception safety.
- std::for_each(progress_threads_.begin(), progress_threads_.end(),
- DeletePtr<ThreadProgress*>());
- throw;
- }
-#endif
-}
-
-Application::~Application()
-{
- std::for_each(progress_threads_.begin(), progress_threads_.end(),
- DeletePtr<ThreadProgress*>());
-}
-
-void Application::run()
-{
- // Install a one-shot idle handler to launch the threads.
- Glib::signal_idle().connect(
- sigc::bind_return(sigc::mem_fun(*this, &Application::launch_threads), false));
-
- main_loop_->run();
-}
-
-void Application::launch_threads()
-{
- std::cout << "Launching " << progress_threads_.size() << " threads:" << std::endl;
-
- std::for_each(progress_threads_.begin(), progress_threads_.end(),
- std::mem_fun(&ThreadProgress::launch));
-}
-
-void Application::on_progress_finished(ThreadProgress* thread_progress)
-{
- thread_progress->join();
-
- std::cout << "Thread " << thread_progress->id() << ": finished." << std::endl;
-
- // Quit if it was the last thread to be joined.
- if (std::find_if(progress_threads_.begin(), progress_threads_.end(),
- std::mem_fun(&ThreadProgress::unfinished)) == progress_threads_.end())
- {
- main_loop_->quit();
- }
-}
-
-} // anonymous namespace
-
-int main(int, char**)
-{
- Glib::thread_init();
-
- Application application;
- application.run();
-
- return 0;
-}