Lumiera  0.pre.03
»edit your freedom«
advice.cpp
Go to the documentation of this file.
1 /*
2  Advice - generic loosely coupled interaction guided by symbolic pattern
3 
4  Copyright (C)
5  2010, Hermann Vosseler <Ichthyostega@web.de>
6 
7   **Lumiera** is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published by the
9   Free Software Foundation; either version 2 of the License, or (at your
10   option) any later version. See the file COPYING for further details.
11 
12 * *****************************************************************/
13 
14 
85 #include "lib/error.hpp"
86 #include "lib/nocopy.hpp"
87 #include "lib/del-stash.hpp"
88 #include "lib/depend.hpp"
89 #include "lib/symbol.hpp"
90 #include "lib/sync.hpp"
91 #include "lib/util.hpp"
92 #include "include/logging.h"
93 #include "common/advice.hpp"
94 #include "common/advice/index.hpp"
95 
96 
97 using lib::Literal;
98 using lib::DelStash;
99 using util::unConst;
100 
101 typedef void (DeleterFunc)(void*);
102 
103 
104 namespace lumiera{
105 namespace advice {
106 
107  namespace { // ======= implementation of the AdviceSystem ============
108 
116  : public lib::Sync<>
118  {
119 
120  DelStash adviceDataRegistry_;
121  Index<PointOfAdvice> index_;
122 
123  public:
124  AdviceSystem()
125  : index_()
126  {
127  TRACE (library, "Initialising Advice Index tables.");
128  }
129 
130  ~AdviceSystem()
131  {
132  TRACE (library, "Shutting down Advice system.");
133  }
134 
135 
136 
137  /* == Advice data storage management == */
138 
146  void*
147  allocateBuffer(size_t siz)
148  {
149  try { return new char[siz]; }
150 
151  catch(std::bad_alloc&)
152  {
153  throw error::Fatal("Unable to store Advice due to memory exhaustion");
154  }
155  ERROR_LOG_AND_IGNORE (memory, "Storing a piece of Advice")
156  throw error::Fatal("Unable to store Advice data");
157  }
158 
159  void
160  releaseBuffer (void* buff, size_t)
161  {
162  delete[] (char*)buff;
163  }
164 
165  void
166  manageAdviceData (PointOfAdvice* entry, DeleterFunc* how_to_delete)
167  {
168  Lock sync{this};
169  adviceDataRegistry_.manage (entry, how_to_delete);
170  }
171 
172  private:
173  void
174  discardEntry (PointOfAdvice* storedProvision)
175  {
176  if (storedProvision)
177  {
178  adviceDataRegistry_.kill (storedProvision);
179  } }
180 
181 
182 
183  public:
184  /* == forward additions and retractions to the index == */
185 
186  void
187  publishRequestBindingChange(PointOfAdvice & req,
188  HashVal previous_bindingKey)
189  {
190  Lock sync{this};
191  index_.modifyRequest(previous_bindingKey, req);
192  }
193 
194  void
195  registerRequest(PointOfAdvice & req)
196  {
197  Lock sync{this};
198  index_.addRequest (req);
199  }
200 
201  void
202  deregisterRequest(PointOfAdvice const& req)
203  {
204  try
205  {
206  Lock sync{this};
207  index_.removeRequest (req);
208  }
209 
210  catch(...)
211  {
212  Literal errID = lumiera_error();
213  WARN (library, "Problems on deregistration of advice request: %s", errID.c());
214  }
215  }
216 
217 
218  void
219  publishProvision (PointOfAdvice* newProvision, const PointOfAdvice* previousProvision)
220  {
221  Lock sync{this};
222 
223  if (!previousProvision && newProvision)
224  index_.addProvision (*newProvision);
225  else
226  if (previousProvision && newProvision)
227  index_.modifyProvision (*previousProvision, *newProvision);
228  else
229  if (previousProvision && !newProvision)
230  index_.removeProvision (*previousProvision);
231 
232  discardEntry (unConst(previousProvision));
233  }
234 
235  void
236  discardSolutions (const PointOfAdvice* existingProvision)
237  {
238  Lock sync{this};
239 
240  if (existingProvision)
241  index_.removeProvision (*existingProvision);
242 
243  discardEntry (unConst(existingProvision));
244  }
245  };
246 
247 
250 
251 
252  } //(End) AdviceSystem implementation
253 
254 
255 
256 
257 
258 
259  /* ====== AdviceLink : access point for Provisions and Requests ====== */
260 
261 
270  void*
272  {
273  return aSys().allocateBuffer(siz);
274  }
275 
276 
277  void
278  AdviceLink::releaseBuffer (void* buff, size_t siz)
279  {
280  aSys().releaseBuffer(buff, siz);
281  }
282 
283 
291  void
292  AdviceLink::manageAdviceData (PointOfAdvice* entry, DeleterFunc* how_to_delete)
293  {
294  aSys().manageAdviceData (entry,how_to_delete);
295  }
296 
297 
298 
299 
312  void
314  {
315  const PointOfAdvice* previousProvision (getSolution());
316  this->setSolution (newProvision);
317 
318  aSys().publishProvision (newProvision, previousProvision);
319  }
320 
321 
330  void
332  {
333  const PointOfAdvice* existingProvision (getSolution());
334  this->setSolution ( NULL );
335  aSys().discardSolutions (existingProvision);
336  }
337 
338 
339  void
340  AdviceLink::publishRequestBindingChange(HashVal previous_bindingKey)
341  {
342  aSys().publishRequestBindingChange (*this, previous_bindingKey);
343  }
344 
345 
346  void
347  AdviceLink::registerRequest()
348  {
349  aSys().registerRequest (*this);
350  }
351 
352 
353  void
354  AdviceLink::deregisterRequest()
355  {
356  aSys().deregisterRequest (*this);
357  }
358 
359 
360 
361 
362 
363 }} // namespace lib::advice
Facility for monitor object based locking.
Definition: sync.hpp:209
the system-wide service to support the implementation of advice collaborations.
Definition: advice.cpp:115
void * allocateBuffer(size_t siz)
low-level allocation of storage to hold advice data
Definition: advice.cpp:147
Basic (abstracted) view of an advice collaboration partner, as used internally by the AdviceSystem to...
Definition: advice.hpp:122
#define ERROR_LOG_AND_IGNORE(_FLAG_, _OP_DESCR_)
convenience shortcut for a sequence of catch blocks just logging and consuming an error...
Definition: error.hpp:266
AnyPair entry(Query< TY > const &query, typename WrapReturn< TY >::Wrapper &obj)
helper to simplify creating mock table entries, wrapped correctly
Any copy and copy construction prohibited.
Definition: nocopy.hpp:37
inline string literal This is a marker type to indicate that
Definition: symbol.hpp:76
Implementation datastructure for use by the Advice system.
lib::Depend< AdviceSystem > aSys
hidden implementation-level access to the AdviceSystem
Definition: advice.cpp:249
This header is for including and configuring NoBug.
Access point to singletons and other kinds of dependencies designated by type.
Definition: depend.hpp:280
Collecting and finally triggering deleter functions.
Object Monitor based synchronisation.
Derived specific exceptions within Lumiera&#39;s exception hierarchy.
Definition: error.hpp:190
Mix-Ins to allow or prohibit various degrees of copying and cloning.
Expecting Advice and giving Advice: a cross-cutting collaboration of loosely coupled participants...
Marker types to indicate a literal string and a Symbol.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
lumiera_err lumiera_error(void)
Get and clear current error state.
Definition: error-state.c:115
Manage a collection of deleter functions.
Definition: del-stash.hpp:56
Singleton services and Dependency Injection.
Lumiera error handling (C++ interface).
size_t HashVal
a STL compatible hash value
Definition: hash-value.h:52
Lumiera public interface.
Definition: advice.cpp:104
void modifyRequest(HashVal oKey, POA &entry)
Definition: index.hpp:355
Index datastructure for organising advice solutions.
Definition: index.hpp:141
void discardEntry(PointOfAdvice *storedProvision)
Definition: advice.cpp:174