// 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_