#ifndef _FC_THREAD_HPP_ #define _FC_THREAD_HPP_ #include #include namespace fc { class string; class time_point; class microseconds; class thread { public: thread( const char* name = "" ); thread( thread&& m ); thread& operator=(thread&& t ); /** * Returns the current thread. */ static thread& current(); /** * @brief returns the name given by @ref set_name() for this thread */ const string& name()const; /** * @brief associates a name with this thread. */ void set_name( const string& n ); /** * @brief print debug info about the state of every context / promise. * * This method is helpful to figure out where your program is 'hung' by listing * every async operation (context) and what it is blocked on (future). * * @note debug info is more useful if you provide a description for your * async tasks and promises. */ void debug( const fc::string& d ); /** * Calls function f in this thread and returns a future that can * be used to wait on the result. * * @param f the operation to perform * @param prio the priority relative to other tasks */ template auto async( Functor&& f, const char* desc ="", priority prio = priority()) -> fc::future { typedef decltype(f()) Result; fc::task* tsk = new fc::task( fc::forward(f) ); fc::future r(fc::shared_ptr< fc::promise >(tsk,true) ); async_task(tsk,prio,desc); return r; } void poke(); /** * Calls function f in this thread and returns a future that can * be used to wait on the result. * * @param f the method to be called * @param prio the priority of this method relative to others * @param when determines when this call will happen, as soon as * possible after when */ template auto schedule( Functor&& f, const fc::time_point& when, const char* desc = "", priority prio = priority()) -> fc::future { typedef decltype(f()) Result; fc::task* tsk = new fc::task( fc::forward(f) ); fc::future r(fc::shared_ptr< fc::promise >(tsk,true) ); async_task(tsk,prio,when,desc); return r; } /** * This method will cancel all pending tasks causing them to throw cmt::error::thread_quit. * * If the current thread is not this thread, then the current thread will * wait for this thread to exit. * * This is a blocking wait via boost::thread::join * and other tasks in the current thread will not run while * waiting for this thread to quit. * * @todo make quit non-blocking of the calling thread by eliminating the call to boost::thread::join */ void quit(); /** * @return true unless quit() has been called. */ bool is_running()const; bool is_current()const; priority current_priority()const; ~thread(); private: thread( class thread_d* ); friend class promise_base; friend class thread_d; friend class mutex; friend void yield(); friend void usleep(const microseconds&); friend void sleep_until(const time_point&); friend void exec(); friend int wait_any( fc::vector&& v, const microseconds& ); friend int wait_any_until( fc::vector&& v, const time_point& tp ); void wait_until( promise_base::ptr && v, const time_point& tp ); void notify( const promise_base::ptr& v ); void yield(bool reschedule=true); void sleep_until( const time_point& t ); void exec(); int wait_any_until( fc::vector&& v, const time_point& ); void async_task( task_base* t, const priority& p, const char* desc ); void async_task( task_base* t, const priority& p, const time_point& tp, const char* desc ); class thread_d* my; }; /** * Yields to other ready tasks before returning. */ void yield(); /** * Yields to other ready tasks for u microseconds. */ void usleep( const microseconds& u ); /** * Yields until the specified time in the future. */ void sleep_until( const time_point& tp ); /** * Enters the main loop processing tasks until quit() is called. */ void exec(); /** * Wait until either f1 or f2 is ready. * * @return 0 if f1 is ready, 1 if f2 is ready or throw on error. */ int wait_any( fc::vector&& v, const microseconds& timeout_us = microseconds::max() ); int wait_any_until( fc::vector&& v, const time_point& tp ); template auto async( Functor&& f, const char* desc ="", priority prio = priority()) -> fc::future { return fc::thread::current().async( fc::forward(f), desc, prio ); } } #endif