Lumiera  0.pre.03
»edityourfreedom«
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
advice.cpp
Go to the documentation of this file.
1 /*
2  Advice - generic loosely coupled interaction guided by symbolic pattern
3 
4  Copyright (C) Lumiera.org
5  2010, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 * *****************************************************/
22 
23 
92 #include "lib/error.hpp"
93 #include "lib/nocopy.hpp"
94 #include "lib/del-stash.hpp"
95 #include "lib/depend.hpp"
96 #include "lib/symbol.hpp"
97 #include "lib/sync.hpp"
98 #include "lib/util.hpp"
99 #include "include/logging.h"
100 #include "common/advice.hpp"
101 #include "common/advice/index.hpp"
102 
103 
104 using lib::Literal;
105 using lib::DelStash;
106 using util::unConst;
107 
108 typedef void (DeleterFunc)(void*);
109 
110 
111 namespace lumiera{
112 namespace advice {
113 
114  namespace { // ======= implementation of the AdviceSystem ============
115 
122  class AdviceSystem
123  : public lib::Sync<>
125  {
126 
127  DelStash adviceDataRegistry_;
128  Index<PointOfAdvice> index_;
129 
130  public:
131  AdviceSystem()
132  : index_()
133  {
134  INFO (library, "Initialising Advice Index tables.");
135  }
136 
137  ~AdviceSystem()
138  {
139  INFO (library, "Shutting down Advice system.");
140  }
141 
142 
143 
144  /* == Advice data storage management == */
145 
153  void*
154  allocateBuffer(size_t siz)
155  {
156  try { return new char[siz]; }
157 
158  catch(std::bad_alloc&)
159  {
160  throw error::Fatal("Unable to store Advice due to memory exhaustion");
161  }
162  ERROR_LOG_AND_IGNORE (memory, "Storing a piece of Advice")
163  throw error::Fatal("Unable to store Advice data");
164  }
165 
166  void
167  releaseBuffer (void* buff, size_t)
168  {
169  delete[] (char*)buff;
170  }
171 
172  void
173  manageAdviceData (PointOfAdvice* entry, DeleterFunc* how_to_delete)
174  {
175  Lock sync (this);
176  adviceDataRegistry_.manage (entry, how_to_delete);
177  }
178 
179  private:
180  void
181  discardEntry (PointOfAdvice* storedProvision)
182  {
183  if (storedProvision)
184  {
185  adviceDataRegistry_.kill (storedProvision);
186  } }
187 
188 
189 
190  public:
191  /* == forward additions and retractions to the index == */
192 
193  void
194  publishRequestBindingChange(PointOfAdvice & req,
195  HashVal previous_bindingKey)
196  {
197  Lock sync (this);
198  index_.modifyRequest(previous_bindingKey, req);
199  }
200 
201  void
202  registerRequest(PointOfAdvice & req)
203  {
204  Lock sync (this);
205  index_.addRequest (req);
206  }
207 
208  void
209  deregisterRequest(PointOfAdvice const& req)
210  {
211  try
212  {
213  Lock sync (this);
214  index_.removeRequest (req);
215  }
216 
217  catch(...)
218  {
219  Literal errID = lumiera_error();
220  WARN (library, "Problems on deregistration of advice request: %s", errID.c());
221  }
222  }
223 
224 
225  void
226  publishProvision (PointOfAdvice* newProvision, const PointOfAdvice* previousProvision)
227  {
228  Lock sync (this);
229 
230  if (!previousProvision && newProvision)
231  index_.addProvision (*newProvision);
232  else
233  if (previousProvision && newProvision)
234  index_.modifyProvision (*previousProvision, *newProvision);
235  else
236  if (previousProvision && !newProvision)
237  index_.removeProvision (*previousProvision);
238 
239  discardEntry (unConst(previousProvision));
240  }
241 
242  void
243  discardSolutions (const PointOfAdvice* existingProvision)
244  {
245  Lock sync (this);
246 
247  if (existingProvision)
248  index_.removeProvision (*existingProvision);
249 
250  discardEntry (unConst(existingProvision));
251  }
252  };
253 
254 
257 
258 
259  } //(End) AdviceSystem implementation
260 
261 
262 
263 
264 
265 
266  /* ====== AdviceLink : access point for Provisions and Requests ====== */
267 
268 
277  void*
279  {
280  return aSys().allocateBuffer(siz);
281  }
282 
283 
284  void
285  AdviceLink::releaseBuffer (void* buff, size_t siz)
286  {
287  aSys().releaseBuffer(buff, siz);
288  }
289 
290 
298  void
300  {
301  aSys().manageAdviceData (entry,how_to_delete);
302  }
303 
304 
305 
306 
319  void
321  {
322  const PointOfAdvice* previousProvision (getSolution());
323  this->setSolution (newProvision);
324 
325  aSys().publishProvision (newProvision, previousProvision);
326  }
327 
328 
337  void
339  {
340  const PointOfAdvice* existingProvision (getSolution());
341  this->setSolution ( NULL );
342  aSys().discardSolutions (existingProvision);
343  }
344 
345 
346  void
348  {
349  aSys().publishRequestBindingChange (*this, previous_bindingKey);
350  }
351 
352 
353  void
355  {
356  aSys().registerRequest (*this);
357  }
358 
359 
360  void
362  {
363  aSys().deregisterRequest (*this);
364  }
365 
366 
367 
368 
369 
370 }} // namespace lib::advice
Facility for monitor object based locking.
Definition: sync.hpp:425
void addProvision(POA &entry)
Definition: index.hpp:388
void addRequest(POA &entry)
Definition: index.hpp:350
void manage(TY *obj)
Definition: del-stash.hpp:146
Basic (abstracted) view of an advice collaboration partner, as used internally by the AdviceSystem to...
Definition: advice.hpp:126
#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:272
Any copy and copy construction prohibited.
Definition: nocopy.hpp:46
inline string literal This is a marker type to indicate that
Definition: symbol.hpp:75
Implementation datastructure for use by the Advice system.
This header is for including and configuring NoBug.
Access point to singletons and other kinds of dependencies designated by type.
Definition: depend.hpp:275
Collecting and finally triggering deleter functions.
void setSolution(PointOfAdvice *solution=0)
Definition: advice.hpp:156
void( DeleterFunc)(void *)
Definition: advice.cpp:108
Object Monitor based synchronisation.
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...
return NULL
Definition: llist.h:596
Marker types to indicate a literal string and a Symbol.
void removeProvision(POA const &refEntry)
Definition: index.hpp:415
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:124
void removeRequest(POA const &refEntry)
Definition: index.hpp:380
Manage a collection of deleter functions.
Definition: del-stash.hpp:64
const PointOfAdvice * getSolution() const
Definition: advice.hpp:162
Singleton services and Dependency Injection.
Lumiera error handling (C++ interface).
OBJ * unConst(const OBJ *o)
shortcut to save some typing when having to define const and non-const variants of member functions ...
Definition: util.hpp:319
size_t HashVal
a STL compatible hash value
Definition: hash-value.h:56
Lumiera public interface.
void kill(TY *obj)
Definition: del-stash.hpp:172
void modifyRequest(HashVal oKey, POA &entry)
Definition: index.hpp:364
void modifyProvision(POA const &oldRef, POA &newEntry)
Definition: index.hpp:396
const char * c() const
Definition: symbol.hpp:92
Index datastructure for organising advice solutions.
Definition: index.hpp:150
LumieraError< LERR_(FATAL), Logic > Fatal
Definition: error.hpp:213