#include <glibmm.h>
namespace
{
class ThreadProgress
{
public:
explicit ThreadProgress(int id);
virtual ~ThreadProgress();
int id() const;
void join();
bool unfinished() const;
private:
enum { ITERATIONS = 100 };
int id_;
unsigned int progress_;
void progress_increment();
void thread_function();
};
{
public:
Application();
virtual ~Application();
void run();
private:
void launch_threads();
void on_progress_finished(ThreadProgress* thread_progress);
};
template <class T>
{
public:
void operator()(T ptr) const { delete ptr; }
};
ThreadProgress::ThreadProgress(int id)
:
thread_ (0),
id_ (id),
progress_ (0)
{
signal_increment_.connect(
sigc::mem_fun(*
this, &ThreadProgress::progress_increment));
}
ThreadProgress::~ThreadProgress()
{
g_return_if_fail(thread_ == 0);
}
int ThreadProgress::id() const
{
return id_;
}
{
}
void ThreadProgress::join()
{
thread_->join();
thread_ = 0;
}
bool ThreadProgress::unfinished() const
{
return (progress_ < ITERATIONS);
}
{
return signal_finished_;
}
void ThreadProgress::progress_increment()
{
++progress_;
std::cout <<
"Thread " << id_ <<
": " << progress_ <<
'%' <<
std::endl;
if (progress_ >= ITERATIONS)
signal_finished_();
}
void ThreadProgress::thread_function()
{
for (int i = 0; i < ITERATIONS; ++i)
{
signal_increment_();
}
}
Application::Application()
:
progress_threads_ (5)
{
try
{
{
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));
}
}
catch (...)
{
std::for_each(progress_threads_.begin(), progress_threads_.end(),
DeletePtr<ThreadProgress*>());
throw;
}
}
Application::~Application()
{
std::for_each(progress_threads_.begin(), progress_threads_.end(),
DeletePtr<ThreadProgress*>());
}
void Application::run()
{
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(),
}
void Application::on_progress_finished(ThreadProgress* thread_progress)
{
thread_progress->join();
std::cout <<
"Thread " << thread_progress->id() <<
": finished." <<
std::endl;
if (
std::find_if(progress_threads_.begin(), progress_threads_.end(),
std::mem_fun(&ThreadProgress::unfinished)) == progress_threads_.end())
{
main_loop_->quit();
}
}
}
int main(int, char**)
{
Application application;
application.run();
return 0;
}