BitShares-Core  4.0.0
BitShares blockchain implementation and command-line interface software
task.cpp
Go to the documentation of this file.
1 #include <fc/thread/task.hpp>
5 #include <fc/fwd_impl.hpp>
6 #include "context.hpp"
7 
8 #include <fc/log/logger.hpp>
9 #include <boost/exception/all.hpp>
10 
11 #ifdef _MSC_VER
12 # include <fc/thread/thread.hpp>
13 # include <Windows.h>
14 #endif
15 
16 namespace fc {
18  :
19  promise_base("task_base"),
20  _posted_num(0),
21  _active_context(nullptr),
22  _next(nullptr),
23  _task_specific_data(nullptr),
24  _promise_impl(nullptr),
25  _functor(func),
26  _retain_count(0){
27  }
28 
29  void task_base::run() {
30 #ifdef _MSC_VER
31  __try {
32 #endif
33  run_impl();
34 #ifdef _MSC_VER
35  } __except (get_unhandled_structured_exception_filter() ? get_unhandled_structured_exception_filter()(GetExceptionCode(), GetExceptionInformation()) : EXCEPTION_CONTINUE_SEARCH) {
36  ExitProcess(1);
37  }
38 #endif
39  }
40 
42  try {
43  if( !canceled() )
45  else
46 #ifdef NDEBUG
47  FC_THROW_EXCEPTION( canceled_exception, "task ${description} canceled before starting", ("description", get_desc()));
48 #else
49  FC_THROW_EXCEPTION( canceled_exception, "task ${description} canceled before starting, reason ${reason}",
50  ("description", get_desc())
51  ("reason", _cancellation_reason ? _cancellation_reason : "[none given]"));
52 #endif
53  }
54  catch ( const exception& e )
55  {
57  }
58  catch ( ... )
59  {
60  set_exception( std::make_shared<unhandled_exception>( FC_LOG_MESSAGE( warn, "unhandled exception: ${diagnostic}", ("diagnostic",boost::current_exception_diagnostic_information()) ) ) );
61  }
62  }
63 
64  void task_base::cancel(const char* reason /* = nullptr */)
65  {
66  promise_base::cancel(reason);
67  if (_active_context)
68  {
70  {
71  // this task is blocked on a mutex, we probably don't handle this correctly
73  }
74  _active_context->canceled = true;
75 #ifndef NDEBUG
77 #endif
78  _active_context->ctx_thread->notify_task_has_been_canceled();
79  }
80  }
81 
85  }
86 
88  { synchronized( *_spinlock )
89  _active_context = c;
90  }
91  }
92 
94  {
96  {
97  for (auto iter = _task_specific_data->begin(); iter != _task_specific_data->end(); ++iter)
98  if (iter->cleanup)
99  iter->cleanup(iter->value);
100  delete _task_specific_data;
101  _task_specific_data = nullptr;
102  }
103  }
104 
106  if( _retain_count.fetch_add(1, boost::memory_order_relaxed) == 0 )
107  _self = shared_from_this();
108  }
110  if( _retain_count.fetch_sub(1, boost::memory_order_release) == 1 )
111  _self.reset();
112  }
113 }
void retain()
Definition: task.cpp:105
const char * get_desc() const
Definition: future.cpp:26
virtual void cancel(const char *reason FC_CANCELATION_REASON_DEFAULT_ARG) override
Definition: task.cpp:64
void set_exception(const fc::exception_ptr &e)
Definition: future.cpp:44
const char * _cancellation_reason
Definition: future.hpp:101
void release()
Definition: task.cpp:109
void * _promise_impl
Definition: task.hpp:82
const char * cancellation_reason
Definition: context.hpp:196
Used to generate a useful error report when an exception is thrown.At each level in the stack where t...
Definition: exception.hpp:56
virtual void cancel(const char *reason FC_CANCELATION_REASON_DEFAULT_ARG)
Definition: future.cpp:30
void(* _destroy_functor)(void *)
Definition: task.hpp:84
virtual std::shared_ptr< exception > dynamic_copy_exception() const
Definition: exception.cpp:267
task_base(void *func)
Definition: task.cpp:17
fc::context * next_blocked_mutex
Definition: context.hpp:191
#define FC_THROW_EXCEPTION(EXCEPTION, FORMAT,...)
Definition: exception.hpp:378
std::vector< detail::specific_data_info > * _task_specific_data
Definition: task.hpp:68
Defines exception&#39;s used by fc.
void _set_active_context(context *)
Definition: task.cpp:87
void(* _run_functor)(void *, void *)
Definition: task.hpp:85
void cleanup_task_specific_data()
Definition: task.cpp:93
Definition: api.hpp:15
void * _functor
Definition: task.hpp:83
context * _active_context
Definition: task.hpp:64
#define FC_LOG_MESSAGE(LOG_LEVEL, FORMAT,...)
A helper method for generating log messages.
virtual ~task_base()
Definition: task.cpp:82
bool canceled() const
Definition: future.hpp:69
fc::thread * ctx_thread
Definition: context.hpp:193
void run_impl()
Definition: task.cpp:41
void run()
Definition: task.cpp:29
bool canceled
Definition: context.hpp:194