Subordination
A framework for distributed programming
kernel.hh
1 #ifndef SUBORDINATION_KERNEL_KERNEL_HH
2 #define SUBORDINATION_KERNEL_KERNEL_HH
3 
4 #include <memory>
5 
6 #include <unistdx/net/pstream>
7 
8 #include <subordination/kernel/mobile_kernel.hh>
9 
10 namespace sbn {
11 
12  struct kernel: public mobile_kernel {
13 
14  typedef mobile_kernel base_kernel;
15  using mobile_kernel::id_type;
16 
17  inline const kernel*
18  principal() const {
19  return this->isset(kernel_flag::principal_is_id)
20  ? nullptr : this->_principal;
21  }
22 
23  inline kernel*
24  principal() {
25  return this->_principal;
26  }
27 
28  inline id_type
29  principal_id() const {
30  return this->_principal_id;
31  }
32 
33  inline void
34  set_principal_id(id_type id) {
35  this->_principal_id = id;
36  this->setf(kernel_flag::principal_is_id);
37  }
38 
39  inline void
40  principal(kernel* rhs) {
41  this->_principal = rhs;
42  this->unsetf(kernel_flag::principal_is_id);
43  }
44 
45  inline const kernel*
46  parent() const {
47  return this->_parent;
48  }
49 
50  inline kernel*
51  parent() {
52  return this->_parent;
53  }
54 
55  inline id_type
56  parent_id() const {
57  return this->_parent_id;
58  }
59 
60  inline void
61  parent(kernel* p) {
62  this->_parent = p;
63  this->unsetf(kernel_flag::parent_is_id);
64  }
65 
66  inline size_t
67  hash() const {
68  const bool b = this->isset(kernel_flag::principal_is_id);
69  size_t ret;
70  if (b) {
71  ret = this->_principal_id;
72  } else {
73  ret = this->_principal && this->_principal->has_id()
74  ? this->_principal->id()
75  : size_t(this->_principal) / alignof(size_t);
76  }
77  return ret;
78  }
79 
80  inline bool
81  moves_upstream() const noexcept {
82  return this->return_code() == exit_code::undefined &&
83  !this->_principal &&
84  this->_parent;
85  }
86 
87  inline bool
88  moves_downstream() const noexcept {
89  return this->return_code() != exit_code::undefined &&
90  this->_principal &&
91  this->_parent;
92  }
93 
94  inline bool
95  moves_somewhere() const noexcept {
96  return this->return_code() == exit_code::undefined &&
97  this->_principal &&
98  this->_parent;
99  }
100 
101  inline bool
102  moves_everywhere() const noexcept {
103  return !this->_principal && !this->_parent;
104  }
105 
106  void
107  read(sys::pstream& in) override;
108 
109  void
110  write(sys::pstream& out) const override;
111 
112  virtual void
113  act();
114 
115  virtual void
116  react(kernel* child);
117 
118  virtual void
119  error(kernel* rhs);
120 
121  friend std::ostream&
122  operator<<(std::ostream& out, const kernel& rhs);
123 
124  inline const kernel_header&
125  header() const noexcept {
126  return static_cast<const kernel_header&>(*this);
127  }
128 
129  inline kernel_header&
130  header() noexcept {
131  return static_cast<kernel_header&>(*this);
132  }
133 
134  public:
135 
137 
138  inline kernel*
139  call(kernel* rhs) noexcept {
140  rhs->parent(this);
141  return rhs;
142  }
143 
144  inline kernel*
145  carry_parent(kernel* rhs) noexcept {
146  rhs->parent(this);
147  rhs->setf(kernel_flag::carries_parent);
148  return rhs;
149  }
150 
151  inline void
152  return_to_parent(exit_code ret = exit_code::success) noexcept {
153  return_to(_parent, ret);
154  if (this->from()) {
155  this->to(this->from());
156  }
157  }
158 
159  inline void
160  return_to(kernel* rhs, exit_code ret = exit_code::success) noexcept {
161  this->principal(rhs);
162  this->return_code(ret);
163  }
164 
165  inline void
166  recurse() noexcept {
167  this->principal(this);
168  }
169 
170  template<class It>
171  void
172  mark_as_deleted(It result) noexcept {
173  if (!this->isset(kernel_flag::deleted)) {
174  this->setf(kernel_flag::deleted);
175  if (this->_parent) {
176  this->_parent->mark_as_deleted(result);
177  }
178  *result = std::unique_ptr<kernel>(this);
179  ++result;
180  }
181  }
182 
183  private:
184 
185  union {
186  kernel* _parent = nullptr;
187  id_type _parent_id;
188  };
189  union {
190  kernel* _principal = nullptr;
191  id_type _principal_id;
192  };
193 
194  };
195 
196  std::ostream&
197  operator<<(std::ostream& out, const kernel& rhs);
198 
199  inline sys::pstream&
200  operator<<(sys::pstream& out, const kernel& rhs) {
201  rhs.write(out);
202  return out;
203  }
204 
205  inline sys::pstream&
206  operator>>(sys::pstream& in, kernel& rhs) {
207  rhs.read(in);
208  return in;
209  }
210 
211 }
212 
213 #endif // vim:filetype=cpp
Definition: kernel_header.hh:14
Definition: mobile_kernel.hh:9
T write(T... args)
Definition: kernel.hh:12
kernel * call(kernel *rhs) noexcept
New API.
Definition: kernel.hh:139
Definition: error.hh:9
T read(T... args)