BitShares-Core  7.0.2
BitShares blockchain node software and command-line wallet software
context.hpp
Go to the documentation of this file.
1 #pragma once
2 #include <fc/thread/thread.hpp>
4 #include <vector>
5 
6 #include <boost/version.hpp>
7 
8 #define BOOST_COROUTINES_NO_DEPRECATION_WARNING // Boost 1.61
9 #define BOOST_COROUTINE_NO_DEPRECATION_WARNING // Boost 1.62
10 
11 #if BOOST_VERSION >= 106800
12 #include <boost/context/continuation_fcontext.hpp>
13 #else
14 #include <boost/context/all.hpp>
15 #endif
16 
17 #if BOOST_VERSION >= 106100
18  #include <boost/coroutine/stack_allocator.hpp>
19  namespace bc = boost::context::detail;
20  namespace bco = boost::coroutines;
22 #else
23 # include <boost/coroutine/stack_context.hpp>
24  namespace bc = boost::context;
25  namespace bco = boost::coroutines;
26 # if !defined(NDEBUG)
27 # include <boost/assert.hpp>
28 # include <boost/coroutine/protected_stack_allocator.hpp>
29  typedef bco::protected_stack_allocator stack_allocator;
30 # else
31 # include <boost/coroutine/stack_allocator.hpp>
33 # endif
34 
35 #endif // BOOST_VERSION >= 106100
36 
37 namespace fc {
38  class thread;
39  class promise_base;
40  class task_base;
41 
47  struct context {
48  typedef fc::context* ptr;
49  bco::stack_context stack_ctx;
50 
51 #if BOOST_VERSION >= 106100
52  using context_fn = void (*)(bc::transfer_t);
53 #else
54  using context_fn = void(*)(intptr_t);
55 #endif
56 
58  : caller_context(0),
59  stack_alloc(&alloc),
60  next_blocked(0),
62  next(0),
63  ctx_thread(t),
64  canceled(false),
65 #ifndef NDEBUG
66  cancellation_reason(nullptr),
67 #endif
68  complete(false),
69  cur_task(0),
71  {
72  size_t stack_size = FC_CONTEXT_STACK_SIZE;
73  alloc.allocate(stack_ctx, stack_size);
74  my_context = bc::make_fcontext( stack_ctx.sp, stack_ctx.size, sf);
75  }
76 
78  my_context(nullptr),
79  caller_context(0),
80  stack_alloc(0),
81  next_blocked(0),
83  next(0),
84  ctx_thread(t),
85  canceled(false),
86 #ifndef NDEBUG
87  cancellation_reason(nullptr),
88 #endif
89  complete(false),
90  cur_task(0),
92  {}
93 
95  if(stack_alloc)
96  stack_alloc->deallocate( stack_ctx );
97  }
98 
99  void reinitialize()
100  {
101  canceled = false;
102 #ifndef NDEBUG
103  cancellation_reason = nullptr;
104 #endif
105  blocking_prom.clear();
106  caller_context = nullptr;
108  next_blocked = nullptr;
109  next_blocked_mutex = nullptr;
110  next = nullptr;
111  complete = false;
112  }
113 
115  blocked_promise( promise_base* p=0, bool r=true )
116  :prom(p),required(r){}
117 
119  bool required;
120  };
121 
129  void add_blocking_promise( promise_base* p, bool req = true ) {
130  for( auto i = blocking_prom.begin(); i != blocking_prom.end(); ++i ) {
131  if( i->prom == p ) {
132  i->required = req;
133  return;
134  }
135  }
136  blocking_prom.push_back( blocked_promise(p,req) );
137  }
144  if( blocking_prom.size() == 0 ) {
145  return true;
146  }
147  bool req = false;
148  for( uint32_t i = 0; i < blocking_prom.size(); ++i ) {
149  if( blocking_prom[i].prom == p ) {
150  blocking_prom[i].required = false;
151  return true;
152  }
153  req = req || blocking_prom[i].required;
154  }
155  return !req;
156  }
157 
159  for( auto i = blocking_prom.begin(); i != blocking_prom.end(); ++i ) {
160  if( i->prom == p ) {
161  blocking_prom.erase(i);
162  return;
163  }
164  }
165  }
166 
168  for( auto i = blocking_prom.begin(); i != blocking_prom.end(); ++i ) {
169  i->prom->set_exception( std::make_shared<timeout_exception>() );
170  }
171  }
173  for( auto i = blocking_prom.begin(); i != blocking_prom.end(); ++i ) {
174  i->prom->set_exception( e );
175  }
176  }
178  blocking_prom.clear();
179  }
180 
181  bool is_complete()const { return complete; }
182 
183  bc::fcontext_t my_context;
187  //promise_base* prom;
188  std::vector<blocked_promise> blocking_prom;
190  // time_point ready_time; // time that this context was put on ready queue
195  bool canceled;
196 #ifndef NDEBUG
197  const char* cancellation_reason;
198 #endif
199  bool complete;
201  uint64_t context_posted_num; // serial number set each tiem the context is added to the ready list
202  };
203 
204 } // naemspace fc
205 
fc::context::cur_task
task_base * cur_task
Definition: context.hpp:200
fc::context::remove_blocking_promise
void remove_blocking_promise(promise_base *p)
Definition: context.hpp:158
fc::context::caller_context
fc::context * caller_context
Definition: context.hpp:184
fc::context::next_blocked_mutex
fc::context * next_blocked_mutex
Definition: context.hpp:192
fc::context::context_posted_num
uint64_t context_posted_num
Definition: context.hpp:201
fc::context::complete
bool complete
Definition: context.hpp:199
fc::context::context_fn
void(*)(intptr_t) context_fn
Definition: context.hpp:54
fc::context::~context
~context()
Definition: context.hpp:94
fc::context::reinitialize
void reinitialize()
Definition: context.hpp:99
fc
Definition: api.hpp:15
fc::context::stack_ctx
bco::stack_context stack_ctx
Definition: context.hpp:49
fc::context::is_complete
bool is_complete() const
Definition: context.hpp:181
fc::context::set_exception_on_blocking_promises
void set_exception_on_blocking_promises(const exception_ptr &e)
Definition: context.hpp:172
fc::context::next
fc::context * next
Definition: context.hpp:193
FC_CONTEXT_STACK_SIZE
#define FC_CONTEXT_STACK_SIZE
Definition: thread.hpp:3
fc::context::ctx_thread
fc::thread * ctx_thread
Definition: context.hpp:194
fc::context::blocked_promise
Definition: context.hpp:114
fc::exception_ptr
std::shared_ptr< exception > exception_ptr
Definition: exception.hpp:131
fc::context::blocked_promise::blocked_promise
blocked_promise(promise_base *p=0, bool r=true)
Definition: context.hpp:115
fc::context::blocking_prom
std::vector< blocked_promise > blocking_prom
Definition: context.hpp:188
fc::context
Definition: context.hpp:47
fc::context::prio
priority prio
Definition: context.hpp:186
fc::context::next_blocked
fc::context * next_blocked
Definition: context.hpp:191
fc::context::stack_alloc
stack_allocator * stack_alloc
Definition: context.hpp:185
fc::thread
Definition: thread.hpp:39
fc::context::blocked_promise::required
bool required
Definition: context.hpp:119
thread.hpp
stack_allocator
bco::protected_stack_allocator stack_allocator
Definition: context.hpp:29
fc::task_base
Definition: task.hpp:33
fc::context::add_blocking_promise
void add_blocking_promise(promise_base *p, bool req=true)
Definition: context.hpp:129
fc::context::timeout_blocking_promises
void timeout_blocking_promises()
Definition: context.hpp:167
fc::context::ptr
fc::context * ptr
Definition: context.hpp:48
fc::context::try_unblock
bool try_unblock(promise_base *p)
Definition: context.hpp:143
fc::context::context
context(fc::thread *t)
Definition: context.hpp:77
fc::context::resume_time
time_point resume_time
Definition: context.hpp:189
fc::context::my_context
bc::fcontext_t my_context
Definition: context.hpp:183
fc::context::context
context(context_fn sf, stack_allocator &alloc, fc::thread *t)
Definition: context.hpp:57
fc::context::cancellation_reason
const char * cancellation_reason
Definition: context.hpp:197
fc::priority
Definition: priority.hpp:9
fc::time_point
Definition: time.hpp:44
fc::promise_base
Definition: future.hpp:61
exception.hpp
Defines exception's used by fc.
fc::context::clear_blocking_promises
void clear_blocking_promises()
Definition: context.hpp:177
fc::context::canceled
bool canceled
Definition: context.hpp:195
fc::context::blocked_promise::prom
promise_base * prom
Definition: context.hpp:118