Commit e1b3a927 authored by Davis King's avatar Davis King

Removed two try/catch blocks from the threading code. One was replaced with

the RAII equivalent and the other was the final catch block to log uncaught exceptions
from the user and then abort the program.  The code now lets the exception escape
to the operating system so that it is easier to debug uncaught exceptions.

--HG--
extra : convert_revision : svn%3Afdd8eb12-d10e-0410-9acb-85c331704f74/trunk%403201
parent f9c83710
......@@ -271,6 +271,7 @@ namespace
test5 a5;
}
DLIB_TEST(count == (i+1)*3);
print_spinner();
}
count = 0;
......@@ -285,6 +286,7 @@ namespace
dlib::sleep(50);
}
DLIB_TEST(count == (i+1)*3);
print_spinner();
}
}
......
......@@ -161,78 +161,64 @@ namespace dlib
// ----------------------------------------------------------------------------------------
void multithreaded_object::
thread_helper(
)
multithreaded_object::raii_thread_helper::
raii_thread_helper(
multithreaded_object& self_,
thread_id_type id_
) : self(self_), id(id_){}
multithreaded_object::raii_thread_helper::
~raii_thread_helper()
{
mfp mf;
const thread_id_type id = get_thread_id();
try
auto_mutex M(self.m_);
if (self.thread_ids.is_in_domain(id))
{
// if there is a dead_thread sitting around then pull it
// out and put it into mf
{
auto_mutex M(m_);
if (dead_threads.size() > 0)
{
dead_threads.dequeue(mf);
mfp temp;
thread_id_type id_temp = id;
temp = mf;
thread_ids.add(id_temp,temp);
}
}
mfp temp;
thread_id_type id_temp;
self.thread_ids.remove(id,id_temp,temp);
// put this thread's registered function back into the dead_threads queue
self.dead_threads.enqueue(temp);
}
if (mf.is_set())
{
// call the registered thread function
mf();
--self.threads_started;
// If this is the last thread to terminate then
// signal that that is the case.
if (self.threads_started == 0)
{
self.is_running_ = false;
self.should_stop_ = false;
self.s.broadcast();
}
}
auto_mutex M(m_);
if (thread_ids.is_in_domain(id))
{
mfp temp;
thread_id_type id_temp;
thread_ids.remove(id,id_temp,temp);
// ----------------------------------------------------------------------------------------
}
void multithreaded_object::
thread_helper(
)
{
mfp mf;
thread_id_type id = get_thread_id();
// put this thread's registered function back into the dead_threads queue
dead_threads.enqueue(mf);
}
// this guy's destructor does all the necessary cleanup in this function
raii_thread_helper raii(*this, id);
auto_mutex M(m_);
--threads_started;
// If this is the last thread to terminate then
// signal that that is the case.
if (threads_started == 0)
{
is_running_ = false;
should_stop_ = false;
s.broadcast();
}
}
catch (...)
// if there is a dead_thread sitting around then pull it
// out and put it into mf
{
auto_mutex M(m_);
if (thread_ids.is_in_domain(id))
if (dead_threads.size() > 0)
{
mfp temp;
thread_id_type id_temp;
thread_ids.remove(id,id_temp,temp);
dead_threads.dequeue(mf);
mfp temp(mf);
thread_ids.add(id,temp);
}
}
--threads_started;
// If this is the last thread to terminate then
// signal that that is the case.
if (threads_started == 0)
{
is_running_ = false;
should_stop_ = false;
s.broadcast();
}
throw;
if (mf.is_set())
{
// call the registered thread function
mf();
}
}
......
......@@ -113,6 +113,16 @@ namespace dlib
private:
class raii_thread_helper
{
public:
raii_thread_helper(multithreaded_object& self_, thread_id_type id_);
~raii_thread_helper();
multithreaded_object& self;
thread_id_type id;
};
void thread_helper(
);
......
......@@ -225,35 +225,11 @@ namespace dlib
self.data_empty.signal();
self.data_mutex.unlock();
// call funct with its intended parameter
try
{
funct(param);
self.call_end_handlers();
}
catch (std::exception& e)
{
std::cerr << "An exception was thrown in a thread and was not caught. Its what() string is:\n"
<< e.what() << std::endl;
self.data_mutex.lock();
--self.total_count;
self.destructed.signal();
self.data_mutex.unlock();
abort();
}
catch (...)
{
std::cerr << "An exception was thrown in a thread and was not caught." << std::endl;
self.data_mutex.lock();
--self.total_count;
self.destructed.signal();
self.data_mutex.unlock();
abort();
}
// Call funct with its intended parameter. If this function throws then
// we intentionally let the exception escape the thread and result in whatever
// happens when it gets caught by the OS (generally the program is terminated).
funct(param);
self.call_end_handlers();
self.data_mutex.lock();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment