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();
}
}
......
......@@ -159,6 +159,38 @@ namespace dlib
return should_stop_;
}
// ----------------------------------------------------------------------------------------
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()
{
auto_mutex M(self.m_);
if (self.thread_ids.is_in_domain(id))
{
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);
}
--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();
}
}
// ----------------------------------------------------------------------------------------
void multithreaded_object::
......@@ -166,10 +198,11 @@ namespace dlib
)
{
mfp mf;
const thread_id_type id = get_thread_id();
thread_id_type id = get_thread_id();
// this guy's destructor does all the necessary cleanup in this function
raii_thread_helper raii(*this, id);
try
{
// if there is a dead_thread sitting around then pull it
// out and put it into mf
{
......@@ -177,10 +210,8 @@ namespace dlib
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(mf);
thread_ids.add(id,temp);
}
}
......@@ -188,51 +219,6 @@ namespace dlib
{
// call the registered thread function
mf();
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);
}
// put this thread's registered function back into the dead_threads queue
dead_threads.enqueue(mf);
}
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 (...)
{
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);
}
--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;
}
}
......
......@@ -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
{
// 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();
}
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();
}
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