summaryrefslogtreecommitdiffstats
path: root/ml/dlib/dlib/threads/threaded_object_extension.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ml/dlib/dlib/threads/threaded_object_extension.cpp')
-rw-r--r--ml/dlib/dlib/threads/threaded_object_extension.cpp290
1 files changed, 290 insertions, 0 deletions
diff --git a/ml/dlib/dlib/threads/threaded_object_extension.cpp b/ml/dlib/dlib/threads/threaded_object_extension.cpp
new file mode 100644
index 000000000..a7326c11d
--- /dev/null
+++ b/ml/dlib/dlib/threads/threaded_object_extension.cpp
@@ -0,0 +1,290 @@
+// 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
+