Lumiera  0.pre.03
»edityourfreedom«
buffer-provider.cpp
Go to the documentation of this file.
1 /*
2  BufferProvider - Abstraction for Buffer management during playback/render
3 
4  Copyright (C) Lumiera.org
5  2008, 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 
29 #include "lib/error.hpp"
32 #include "lib/util.hpp"
33 
34 using util::isSameObject;
35 
36 namespace proc {
37 namespace engine {
38 
39 
40  namespace { // impl. details and definitions
41 
42  const uint DEFAULT_DESCRIPTOR = 0;
43 
44  }
45 
46  LUMIERA_ERROR_DEFINE (BUFFER_MANAGEMENT, "Problem providing working buffers");
47 
48 
55  : meta_(new BufferMetadata (implementationID))
56  { }
57 
59 
60 
65  bool
67  {
68  return meta_->isLocked (bufferID);
69  }
70 
71 
73  BufferProvider::getDescriptorFor (size_t storageSize)
74  {
75  return BufferDescriptor (*this, meta_->key (storageSize));
76  }
77 
78 
80  BufferProvider::getDescriptorFor(size_t storageSize, TypeHandler specialTreatment)
81  {
82  return BufferDescriptor (*this, meta_->key (storageSize, specialTreatment));
83  }
84 
85 
86  size_t
88  {
89  metadata::Key& typeKey = meta_->get (typeID);
90  return typeKey.storageSize();
91  }
92 
93 
100  BuffHandle
101  BufferProvider::buildHandle (HashVal typeID, void* storage, LocalKey const& implID)
102  {
103  metadata::Key& typeKey = meta_->get (typeID);
104  metadata::Entry& entry = meta_->markLocked(typeKey, storage, implID);
105 
106  return BuffHandle (BufferDescriptor(*this, entry), storage);
107  }
108 
109 
122  uint
123  BufferProvider::announce (uint count, BufferDescriptor const& type)
124  {
125  uint actually_possible = prepareBuffers (count, type);
126  if (!actually_possible)
127  throw error::State ("unable to fulfil request for buffers"
128  ,LUMIERA_ERROR_BUFFER_MANAGEMENT);
129  return actually_possible;
130  }
131 
132 
145  BuffHandle
147  {
148  REQUIRE (was_created_by_this_provider (type));
149 
150  return provideLockedBuffer (type);
151  } // is expected to call buildHandle() --> state transition
152 
153 
166  void
168  {
169  metadata::Entry& metaEntry = meta_->get (handle.entryID());
170  mark_emitted (metaEntry.parentKey(), metaEntry.localKey());
171  metaEntry.mark(EMITTED);
172  }
173 
174 
183  void
185  try {
186  metadata::Entry& metaEntry = meta_->get (handle.entryID());
187  metaEntry.mark(FREE); // might invoke embedded dtor function
188  detachBuffer (metaEntry.parentKey(), metaEntry.localKey());
189  meta_->release (metaEntry);
190  }
191  ERROR_LOG_AND_IGNORE (engine, "releasing a buffer from BufferProvider")
192 
193 
194 
195 
205  void
207  {
208  metadata::Entry& metaEntry = meta_->get (target.entryID());
209  metadata::Entry& refEntry = meta_->get (reference);
210  REQUIRE (refEntry.isTypeKey());
211  REQUIRE (!metaEntry.isTypeKey());
212  if (!metaEntry.isLocked())
213  throw error::Logic ("unable to attach an object because buffer isn't locked for use"
214  , LERR_(LIFECYCLE));
215 
216  metaEntry.useTypeHandlerFrom (refEntry); // EX_STRONG
217  }
218 
219 
227  void
228  BufferProvider::emergencyCleanup (BuffHandle const& target, bool invokeDtor)
229  try {
230  metadata::Entry& metaEntry = meta_->get (target.entryID());
231  metaEntry.invalidate (invokeDtor);
232  detachBuffer (metaEntry.parentKey(), metaEntry.localKey());
233  meta_->release (metaEntry);
234  }
235  ERROR_LOG_AND_IGNORE (engine, "cleanup of buffer metadata while handling an error")
236 
237 
238 
239  bool
241  {
242  return isSameObject (*this, *descr.provider_);
243  }
244 
245 
246 
247 
248 
249  /* === BufferDescriptor and BuffHandle === */
250 
251  bool
253  {
254  return provider_->verifyValidity(*this);
255  }
256 
257 
258  size_t
260  {
261  return provider_->getBufferSize (*this);
262  }
263 
264 
265  void
267  {
268  REQUIRE (isValid());
269  descriptor_.provider_->emitBuffer(*this);
270  }
271 
272 
273  void
275  {
276  if (pBuffer_)
277  {
278  REQUIRE (isValid());
279  descriptor_.provider_->releaseBuffer(*this);
280  pBuffer_ = 0;
281  }
282  ENSURE (!isValid());
283  }
284 
285 
286  void
288  {
289  descriptor_.provider_->emergencyCleanup(*this); // EX_FREE
290  pBuffer_ = 0;
291  }
292 
293 
306  void
308  {
309  if (!this->isValid())
310  throw error::Logic ("attaching an object requires an buffer in locked state", LERR_(LIFECYCLE));
311  if (this->size() < type.determineBufferSize())
312  throw error::Logic ("insufficient buffer size to hold an instance of that type");
313 
314  descriptor_.provider_->attachTypeHandler(*this, type); // EX_STRONG
315  }
316 
317 
318 
319 
320 }} // namespace engine
bool verifyValidity(BufferDescriptor const &) const
ChPredicate isValid(is_alnum() or is_any_of("-_.+$()@"))
characters to be retained
bool was_created_by_this_provider(BufferDescriptor const &) const
BuffHandle buildHandle(HashVal typeID, void *storage, LocalKey const &)
callback from implementation to build and enrol a BufferHandle, to be returned to the client as resul...
Description of a Buffer-"type".
HashVal entryID() const
Definition: buffhandle.hpp:162
allocated buffer, no longer in use
#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
An opaque descriptor to identify the type and further properties of a data buffer.
Definition: buffhandle.hpp:81
inline string literal This is a marker type to indicate that
Definition: symbol.hpp:75
A pair of functors to maintain a datastructure within a buffer.
allocated buffer, returned from client
void emergencyCleanup(BuffHandle const &target, bool invokeDtor=false)
BufferDescriptor getDescriptorFor(size_t storageSize=0)
describe the kind of buffer managed by this provider
Handle for a buffer for processing data, abstracting away the actual implementation.
Definition: buffhandle.hpp:111
LUMIERA_ERROR_DEFINE(BUFFER_MANAGEMENT, "Problem providing working buffers")
bool isSameObject(A const &a, B const &b)
compare plain object identity, bypassing any custom comparison operators.
Definition: util.hpp:337
Derived specific exceptions within Lumiera&#39;s exception hierarchy.
Definition: error.hpp:196
virtual void detachBuffer(HashVal typeID, LocalKey const &)=0
void releaseBuffer(BuffHandle const &)
BufferProvider API: declare done and detach.
Metadata for managing and accessing buffers.
#define LERR_(_NAME_)
Definition: error.hpp:58
Entry & mark(BufferState newState)
Buffer state machine.
Registry for managing buffer metadata.
virtual void mark_emitted(HashVal typeID, LocalKey const &)=0
LocalKey const & localKey() const
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
LumieraError< LERR_(STATE)> State
Definition: error.hpp:214
Entry & invalidate(bool invokeDtor=true)
bool isLocked() const
is this Entry currently associated to a concrete buffer? Is this buffer in use?
BufferProvider(Literal implementationID)
build a new provider instance, managing a family of buffers.
LumieraError< LERR_(LOGIC)> Logic
Definition: error.hpp:212
an opaque ID to be used by the BufferProvider implementation.
void attachTypeHandler(BuffHandle const &target, BufferDescriptor const &reference)
allow for attaching and owing an object within an already created buffer
virtual BuffHandle provideLockedBuffer(HashVal typeID)=0
Lumiera error handling (C++ interface).
uint announce(uint count, BufferDescriptor const &)
BufferProvider API: declare in advance the need for working buffers.
BuffHandle lockBuffer(BufferDescriptor const &)
BufferProvider API: retrieve a single buffer for exclusive use.
size_t HashVal
a STL compatible hash value
Definition: hash-value.h:56
virtual ~BufferProvider()
this is an ABC
virtual uint prepareBuffers(uint count, HashVal typeID)=0
unique_ptr< BufferMetadata > meta_
void emitBuffer(BuffHandle const &)
BufferProvider API: state transition to emitted state.
size_t getBufferSize(HashVal typeID) const
Proc-Layer implementation namespace root.
Definition: id-scheme.hpp:63
bool isTypeKey() const
is this Entry just an (abstract) placeholder for a type?
A complete metadata Entry, based on a Key.
ENSURE(r==&pq)
void useTypeHandlerFrom(Key const &ref)
Abstraction to represent buffer management and lifecycle within the render engine.