291 lines
7.7 KiB
C++
291 lines
7.7 KiB
C++
// Copyright (C) 2007 Davis E. King (davis@dlib.net)
|
|
// License: Boost Software License See LICENSE.txt for the full license.
|
|
#ifndef DLIB_THREADED_OBJECT_EXTENSIOn_CPP
|
|
#define DLIB_THREADED_OBJECT_EXTENSIOn_CPP
|
|
|
|
#include "threaded_object_extension.h"
|
|
#include "create_new_thread_extension.h"
|
|
|
|
namespace dlib
|
|
{
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
threaded_object::
|
|
threaded_object (
|
|
):
|
|
s(m_),
|
|
id1(0),
|
|
is_running_(false),
|
|
is_alive_(false),
|
|
should_stop_(false),
|
|
id_valid(false)
|
|
{
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
threaded_object::
|
|
~threaded_object (
|
|
)
|
|
{
|
|
try
|
|
{
|
|
DLIB_ASSERT(is_alive() == false,
|
|
"\tthreaded_object::~threaded_object()"
|
|
<< "\n\tYou have let a threaded object destruct itself before terminating its thread"
|
|
<< "\n\tthis: " << this
|
|
);
|
|
}
|
|
catch (std::exception& e)
|
|
{
|
|
std::cerr << e.what() << std::endl;
|
|
assert(false);
|
|
abort();
|
|
}
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
bool threaded_object::
|
|
is_running (
|
|
) const
|
|
{
|
|
auto_mutex M(m_);
|
|
|
|
DLIB_ASSERT(id1 != get_thread_id() || id_valid == false,
|
|
"\tbool threaded_object::is_running()"
|
|
<< "\n\tYou can NOT call this function from the thread that executes threaded_object::thread"
|
|
<< "\n\tthis: " << this
|
|
);
|
|
|
|
return is_running_;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
bool threaded_object::
|
|
is_alive (
|
|
) const
|
|
{
|
|
auto_mutex M(m_);
|
|
|
|
DLIB_ASSERT(id1 != get_thread_id() || id_valid == false,
|
|
"\tbool threaded_object::is_alive()"
|
|
<< "\n\tYou can NOT call this function from the thread that executes threaded_object::thread"
|
|
<< "\n\tthis: " << this
|
|
);
|
|
|
|
return is_alive_;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
void threaded_object::
|
|
wait (
|
|
) const
|
|
{
|
|
auto_mutex M(m_);
|
|
|
|
DLIB_ASSERT(id1 != get_thread_id() || id_valid == false,
|
|
"\tvoid threaded_object::wait()"
|
|
<< "\n\tYou can NOT call this function from the thread that executes threaded_object::thread"
|
|
<< "\n\tthis: " << this
|
|
);
|
|
|
|
while (is_alive_)
|
|
s.wait();
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
void threaded_object::
|
|
start (
|
|
)
|
|
{
|
|
auto_mutex M(m_);
|
|
|
|
DLIB_ASSERT(id1 != get_thread_id() || id_valid == false,
|
|
"\tvoid threaded_object::start()"
|
|
<< "\n\tYou can NOT call this function from the thread that executes threaded_object::thread"
|
|
<< "\n\tthis: " << this
|
|
);
|
|
|
|
if (is_alive_ == false)
|
|
{
|
|
if (create_new_thread<threaded_object,&threaded_object::thread_helper>(*this) == false)
|
|
{
|
|
is_running_ = false;
|
|
throw thread_error();
|
|
}
|
|
}
|
|
is_alive_ = true;
|
|
is_running_ = true;
|
|
should_stop_ = false;
|
|
s.broadcast();
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
void threaded_object::
|
|
restart (
|
|
)
|
|
{
|
|
auto_mutex M(m_);
|
|
|
|
DLIB_ASSERT(id1 != get_thread_id() || id_valid == false,
|
|
"\tvoid threaded_object::restart()"
|
|
<< "\n\tYou can NOT call this function from the thread that executes threaded_object::thread"
|
|
<< "\n\tthis: " << this
|
|
);
|
|
|
|
if (is_alive_ == false)
|
|
{
|
|
if (create_new_thread<threaded_object,&threaded_object::thread_helper>(*this) == false)
|
|
{
|
|
is_running_ = false;
|
|
throw thread_error();
|
|
}
|
|
should_respawn_ = false;
|
|
}
|
|
else
|
|
{
|
|
should_respawn_ = true;
|
|
}
|
|
is_alive_ = true;
|
|
is_running_ = true;
|
|
should_stop_ = false;
|
|
s.broadcast();
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
void threaded_object::
|
|
set_respawn (
|
|
)
|
|
{
|
|
auto_mutex M(m_);
|
|
|
|
DLIB_ASSERT(id1 != get_thread_id() || id_valid == false,
|
|
"\tvoid threaded_object::set_respawn()"
|
|
<< "\n\tYou can NOT call this function from the thread that executes threaded_object::thread"
|
|
<< "\n\tthis: " << this
|
|
);
|
|
|
|
should_respawn_ = true;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
bool threaded_object::
|
|
should_respawn (
|
|
) const
|
|
{
|
|
auto_mutex M(m_);
|
|
|
|
DLIB_ASSERT(id1 != get_thread_id() || id_valid == false,
|
|
"\tbool threaded_object::should_respawn()"
|
|
<< "\n\tYou can NOT call this function from the thread that executes threaded_object::thread"
|
|
<< "\n\tthis: " << this
|
|
);
|
|
|
|
return should_respawn_;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
void threaded_object::
|
|
pause (
|
|
)
|
|
{
|
|
auto_mutex M(m_);
|
|
|
|
DLIB_ASSERT(id1 != get_thread_id() || id_valid == false,
|
|
"\tvoid threaded_object::pause()"
|
|
<< "\n\tYou can NOT call this function from the thread that executes threaded_object::thread"
|
|
<< "\n\tthis: " << this
|
|
);
|
|
|
|
is_running_ = false;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
void threaded_object::
|
|
stop (
|
|
)
|
|
{
|
|
auto_mutex M(m_);
|
|
|
|
DLIB_ASSERT(id1 != get_thread_id() || id_valid == false,
|
|
"\tvoid threaded_object::stop()"
|
|
<< "\n\tYou can NOT call this function from the thread that executes threaded_object::thread"
|
|
<< "\n\tthis: " << this
|
|
);
|
|
|
|
should_stop_ = true;
|
|
is_running_ = false;
|
|
should_respawn_ = false;
|
|
s.broadcast();
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
bool threaded_object::
|
|
should_stop (
|
|
) const
|
|
{
|
|
auto_mutex M(m_);
|
|
DLIB_ASSERT(is_alive_ && id1 == get_thread_id() && id_valid == true,
|
|
"\tbool threaded_object::should_stop()"
|
|
<< "\n\tYou can only call this function from the thread that executes threaded_object::thread"
|
|
<< "\n\tthis: " << this
|
|
);
|
|
while (is_running_ == false && should_stop_ == false)
|
|
s.wait();
|
|
return should_stop_;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
void threaded_object::
|
|
thread_helper(
|
|
)
|
|
{
|
|
#ifdef ENABLE_ASSERTS
|
|
id1 = get_thread_id();
|
|
id_valid = true;
|
|
#endif
|
|
while (true)
|
|
{
|
|
m_.lock();
|
|
should_respawn_ = false;
|
|
m_.unlock();
|
|
|
|
thread();
|
|
|
|
auto_mutex M(m_);
|
|
|
|
if (should_respawn_)
|
|
continue;
|
|
|
|
#ifdef ENABLE_ASSERTS
|
|
id_valid = false;
|
|
#endif
|
|
|
|
is_alive_ = false;
|
|
is_running_ = false;
|
|
should_stop_ = false;
|
|
s.broadcast();
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------------------
|
|
|
|
}
|
|
|
|
#endif // DLIB_THREADED_OBJECT_EXTENSIOn_CPP
|
|
|