    // Copyright (C) 2007  Davis E. King (davis@dlib.net)
    // License: Boost Software License   See LICENSE.txt for the full license.
    #undef DLIB_THREADED_OBJECT_EXTENSIOn_ABSTRACT_
    #ifdef DLIB_THREADED_OBJECT_EXTENSIOn_ABSTRACT_

    #include "threads_kernel_abstract.h"

    namespace dlib
    {

    // ----------------------------------------------------------------------------------------

        class threaded_object
        {
            /*!
                INITIAL VALUE
                    - is_running() == false
                    - is_alive() == false
                    - should_respawn() == false

                WHAT THIS OBJECT REPRESENTS
                    This object represents a simple threaded object.  To use it you inherit
                    from it and define the thread() function.  Then when you call start()
                    it will spawn a thread that calls this->thread().
            !*/
        public:

            threaded_object (
            );
            /*!
                ensures
                    - #*this is properly initialized
                throws
                    - std::bad_alloc
                    - dlib::thread_error
                        the constructor may throw this exception if there is a problem
                        gathering resources to create threading objects.
            !*/

            virtual ~threaded_object (
            );
            /*!
                requires
                    - is_alive() == false
                      (i.e. in the destructor for the object you derive from this one you
                      must wait for this->thread() to end.)
                ensures
                    - all resources allocated by *this have been freed.
            !*/

            bool is_running (
            ) const;
            /*!
                requires
                    - is not called from this->thread()
                ensures
                    - if (is_alive() && this->thread() is currently supposed to be executing) then
                        - returns true
                    - else
                        - returns false
            !*/

            bool is_alive (
            ) const;
            /*!
                requires
                    - is not called from this->thread()
                ensures
                    - if (this->thread() has been called by some thread and has yet to terminate) then
                        - returns true
                    - else
                        - returns false
            !*/

            void wait (
            ) const;
            /*!
                requires
                    - is not called from this->thread()
                ensures
                    - if (is_alive() == true) then
                        - blocks until this->thread() terminates
            !*/

            void start (
            );
            /*!
                requires
                    - is not called from this->thread()
                ensures
                    - #is_alive() == true
                    - #is_running() == true
                    - #should_stop() == false
                throws
                    - std::bad_alloc or dlib::thread_error
                        If either of these exceptions are thrown then
                        #is_alive() == false and #is_running() == false
            !*/

            void set_respawn (
            );
            /*!
                requires
                    - is not called from this->thread()
                ensures
                    - #should_respawn() == true
            !*/

            bool should_respawn (
            ) const;
            /*!
                requires
                    - is not called from this->thread()
                ensures
                    - returns true if the thread will automatically restart upon termination and
                      false otherwise.  Note that every time a thread starts it sets should_respawn()
                      back to false.  Therefore, a single call to set_respawn() can cause at most
                      one respawn to occur.
            !*/

            void restart (
            );
            /*!
                requires
                    - is not called from this->thread()
                ensures
                    - This function atomically executes set_respawn() and start().  The precise meaning of this
                      is defined below.
                    - if (is_alive()) then
                        - #should_respawn() == true
                    - else
                        - #should_respawn() == false
                    - #is_alive() == true
                    - #is_running() == true
                    - #should_stop() == false
                throws
                    - std::bad_alloc or dlib::thread_error
                        If either of these exceptions are thrown then
                        #is_alive() == false and #is_running() == false
            !*/

            void pause (
            );
            /*!
                requires
                    - is not called from this->thread()
                ensures
                    - #is_running() == false
            !*/

            void stop (
            );
            /*!
                requires
                    - is not called from this->thread()
                ensures
                    - #should_stop() == true
                    - #is_running() == false
                    - #should_respawn() == false
            !*/

        protected:

            bool should_stop (
            ) const;
            /*!
                requires
                    - is only called from the thread that executes this->thread()
                ensures
                    - calls to this function block until (#is_running() == true || #should_stop() == true)
                    - if (this thread is supposed to terminate) then
                        - returns true
                    - else
                        - returns false
            !*/

        private:

            virtual void thread (
            ) = 0;
            /*!
                requires
                    - is executed in its own thread
                    - is only executed in one thread at a time
                throws
                    - does not throw any exceptions
            !*/

            // restricted functions
            threaded_object(threaded_object&);        // copy constructor
            threaded_object& operator=(threaded_object&);    // assignment operator
        };

    // ----------------------------------------------------------------------------------------

    }

    #endif // DLIB_THREADED_OBJECT_EXTENSIOn_ABSTRACT_