1
#include <cpput/resource.h>
7
// //////////////////////////////////////////////////////////////////
8
// //////////////////////////////////////////////////////////////////
9
// class ResourceHandlerRegistry
10
// //////////////////////////////////////////////////////////////////
11
// //////////////////////////////////////////////////////////////////
13
ResourceHandlerRegistry &
14
ResourceHandlerRegistry::instance()
16
static ResourceHandlerRegistry registry;
21
ResourceHandlerRegistry::addConstant( const ResourceName &name,
22
const Resource &constant )
24
ResourceHandlerPtr handler( new ConstantResourceHandler( constant ) );
30
ResourceHandlerRegistry::add( const ResourceName &name,
31
const ResourceHandlerPtr &handler )
33
CppTL::Mutex::ScopedLockGuard guard( lock_ );
38
data.handler_ = handler;
40
resourceById_[nextId_] = data;
41
idsByName_[name] = nextId_;
47
ResourceHandlerRegistry::remove( ResourceId id )
49
CppTL::Mutex::ScopedLockGuard guard( lock_ );
51
ResourceById::iterator itResource = resourceById_.find( id );
52
if ( itResource == resourceById_.end() )
57
ResourceData &data = itResource->second;
58
idsByName_.erase( data.name_ );
59
resourceById_.erase( itResource );
64
ResourceHandlerRegistry::getResource( const ResourceName &name )
66
CppTL::Mutex::ScopedLockGuard guard( lock_ );
68
IdsByName::iterator itId = idsByName_.find( name );
69
if ( itId == idsByName_.end() )
71
return ResourceLazyPtr();
74
ResourceId id = itId->second;
75
return ResourceLazyPtr( id );
79
AcquiredResourceHandlePtr
80
ResourceHandlerRegistry::obtainResource( ResourceId id )
84
return AcquiredResourceHandlePtr();
87
ResourceInstancePtr instance;
88
ResourceHandler::AccessPolicy access;
89
// Scoped lock to ensure that the retrieval/creation of a resource does
90
// prevent the retrieval/creation of another resource.
91
// Otherwise, dead-lock would occur if one thread held the lock on a resource
92
// while trying to obtain a second one, and the second one would be locked by
93
// another thread trying to obtain the first resource.
95
CppTL::Mutex::ScopedLockGuard guard( lock_ );
96
ResourceById::iterator itData = resourceById_.find( id );
97
if ( itData == resourceById_.end() )
99
return AcquiredResourceHandlePtr(); // Resource was removed
101
ResourceData &data = itData->second;
102
access = data.handler_->accessPolicy();
103
if ( !data.instance_ ) // Resource not instantiated, create it
105
data.instance_.reset( new ResourceInstance( data.name_,
108
instance = data.instance_;
110
// Now that the global lock has been required, we can safely acquire the
111
// resource (which may lock until another thread using the resource is done
112
// with it if the resource does not support concurrent access).
113
return instance->acquire( access );
118
ResourceHandlerRegistry::increaseLazyRef( ResourceId id )
125
CppTL::Mutex::ScopedLockGuard guard( lock_ );
127
ResourceById::iterator itResource = resourceById_.find( id );
128
if ( itResource != resourceById_.end() ) // checks that the resource was not removed
130
ResourceData &data = itResource->second;
137
ResourceHandlerRegistry::decreaseLazyRef( ResourceId id )
144
CppTL::Mutex::ScopedLockGuard guard( lock_ );
146
ResourceById::iterator itResource = resourceById_.find( id );
147
if ( itResource != resourceById_.end() ) // checks that the resource was not removed
149
ResourceData &data = itResource->second;
150
if ( --(data.lazyCount_) == 0 )
152
// Last lazy reference discarded, remove the ResourceInstancePtr
153
// that was stored to prevent it from being destroyed.
154
// Only other existing AcquiredResourceHandlePtr will prevent it from being
156
data.instance_.reset();
163
// //////////////////////////////////////////////////////////////////
164
// //////////////////////////////////////////////////////////////////
165
// class ResourceInstance
166
// //////////////////////////////////////////////////////////////////
167
// //////////////////////////////////////////////////////////////////
170
ResourceInstance::ResourceInstance( const ResourceName &name,
171
const ResourceHandlerPtr &handler )
172
: handler_( handler )
175
resource_ = handler_->create( name );
179
ResourceInstance::~ResourceInstance()
181
handler_->destroy( name_, resource_ );
186
ResourceInstance::setUp()
188
handler_->setUp( name_, resource_ );
193
ResourceInstance::tearDown()
195
handler_->setUp( name_, resource_ );
199
AcquiredResourceHandlePtr
200
ResourceInstance::acquire( ResourceHandler::AccessPolicy access )
202
AcquiredResourceHandlePtr handle(
203
new AcquiredResourceHandle( lock_, this, access ) );
208
// //////////////////////////////////////////////////////////////////
209
// //////////////////////////////////////////////////////////////////
210
// class AcquiredResourceHandle
211
// //////////////////////////////////////////////////////////////////
212
// //////////////////////////////////////////////////////////////////
214
AcquiredResourceHandle::AcquiredResourceHandle(
216
const ResourceInstancePtr &instance,
217
ResourceHandler::AccessPolicy access )
219
, instance_( instance )
222
if ( access_ != ResourceHandler::concurrent )
228
AcquiredResourceHandle::~AcquiredResourceHandle()
230
if ( access_ != ResourceHandler::concurrent )
238
AcquiredResourceHandle::setUp()
245
AcquiredResourceHandle::tearDown()
247
instance_->tearDown();
252
// //////////////////////////////////////////////////////////////////
253
// //////////////////////////////////////////////////////////////////
254
// class ResourceLazyPtr
255
// //////////////////////////////////////////////////////////////////
256
// //////////////////////////////////////////////////////////////////
260
ResourceLazyPtr::operator =( const ResourceLazyPtr &other )
262
ResourceId oldId = id_;
264
ResourceHandlerRegistry ®istry = ResourceHandlerRegistry::instance();
265
registry.increaseLazyRef( id_ );
266
registry.decreaseLazyRef( oldId );
272
AcquiredResourceHandlePtr
273
ResourceLazyPtr::acquire()
277
ResourceHandlerRegistry::instance().obtainResource( id_ );
279
return AcquiredResourceHandlePtr();
1
#include <cpput/resource.h>
7
// //////////////////////////////////////////////////////////////////
8
// //////////////////////////////////////////////////////////////////
9
// class ResourceHandlerRegistry
10
// //////////////////////////////////////////////////////////////////
11
// //////////////////////////////////////////////////////////////////
13
ResourceHandlerRegistry &
14
ResourceHandlerRegistry::instance()
16
static ResourceHandlerRegistry registry;
21
ResourceHandlerRegistry::addConstant( const ResourceName &name,
22
const Resource &constant )
24
ResourceHandlerPtr handler( new ConstantResourceHandler( constant ) );
30
ResourceHandlerRegistry::add( const ResourceName &name,
31
const ResourceHandlerPtr &handler )
33
CppTL::Mutex::ScopedLockGuard guard( lock_ );
38
data.handler_ = handler;
40
resourceById_[nextId_] = data;
41
idsByName_[name] = nextId_;
47
ResourceHandlerRegistry::remove( ResourceId id )
49
CppTL::Mutex::ScopedLockGuard guard( lock_ );
51
ResourceById::iterator itResource = resourceById_.find( id );
52
if ( itResource == resourceById_.end() )
57
ResourceData &data = itResource->second;
58
idsByName_.erase( data.name_ );
59
resourceById_.erase( itResource );
64
ResourceHandlerRegistry::getResource( const ResourceName &name )
66
CppTL::Mutex::ScopedLockGuard guard( lock_ );
68
IdsByName::iterator itId = idsByName_.find( name );
69
if ( itId == idsByName_.end() )
71
return ResourceLazyPtr();
74
ResourceId id = itId->second;
75
return ResourceLazyPtr( id );
79
AcquiredResourceHandlePtr
80
ResourceHandlerRegistry::obtainResource( ResourceId id )
84
return AcquiredResourceHandlePtr();
87
ResourceInstancePtr instance;
88
ResourceHandler::AccessPolicy access;
89
// Scoped lock to ensure that the retrieval/creation of a resource does
90
// prevent the retrieval/creation of another resource.
91
// Otherwise, dead-lock would occur if one thread held the lock on a resource
92
// while trying to obtain a second one, and the second one would be locked by
93
// another thread trying to obtain the first resource.
95
CppTL::Mutex::ScopedLockGuard guard( lock_ );
96
ResourceById::iterator itData = resourceById_.find( id );
97
if ( itData == resourceById_.end() )
99
return AcquiredResourceHandlePtr(); // Resource was removed
101
ResourceData &data = itData->second;
102
access = data.handler_->accessPolicy();
103
if ( !data.instance_ ) // Resource not instantiated, create it
105
data.instance_.reset( new ResourceInstance( data.name_,
108
instance = data.instance_;
110
// Now that the global lock has been required, we can safely acquire the
111
// resource (which may lock until another thread using the resource is done
112
// with it if the resource does not support concurrent access).
113
return instance->acquire( access );
118
ResourceHandlerRegistry::increaseLazyRef( ResourceId id )
125
CppTL::Mutex::ScopedLockGuard guard( lock_ );
127
ResourceById::iterator itResource = resourceById_.find( id );
128
if ( itResource != resourceById_.end() ) // checks that the resource was not removed
130
ResourceData &data = itResource->second;
137
ResourceHandlerRegistry::decreaseLazyRef( ResourceId id )
144
CppTL::Mutex::ScopedLockGuard guard( lock_ );
146
ResourceById::iterator itResource = resourceById_.find( id );
147
if ( itResource != resourceById_.end() ) // checks that the resource was not removed
149
ResourceData &data = itResource->second;
150
if ( --(data.lazyCount_) == 0 )
152
// Last lazy reference discarded, remove the ResourceInstancePtr
153
// that was stored to prevent it from being destroyed.
154
// Only other existing AcquiredResourceHandlePtr will prevent it from being
156
data.instance_.reset();
163
// //////////////////////////////////////////////////////////////////
164
// //////////////////////////////////////////////////////////////////
165
// class ResourceInstance
166
// //////////////////////////////////////////////////////////////////
167
// //////////////////////////////////////////////////////////////////
170
ResourceInstance::ResourceInstance( const ResourceName &name,
171
const ResourceHandlerPtr &handler )
172
: handler_( handler )
175
resource_ = handler_->create( name );
179
ResourceInstance::~ResourceInstance()
181
handler_->destroy( name_, resource_ );
186
ResourceInstance::setUp()
188
handler_->setUp( name_, resource_ );
193
ResourceInstance::tearDown()
195
handler_->setUp( name_, resource_ );
199
AcquiredResourceHandlePtr
200
ResourceInstance::acquire( ResourceHandler::AccessPolicy access )
202
AcquiredResourceHandlePtr handle(
203
new AcquiredResourceHandle( lock_, this, access ) );
208
// //////////////////////////////////////////////////////////////////
209
// //////////////////////////////////////////////////////////////////
210
// class AcquiredResourceHandle
211
// //////////////////////////////////////////////////////////////////
212
// //////////////////////////////////////////////////////////////////
214
AcquiredResourceHandle::AcquiredResourceHandle(
216
const ResourceInstancePtr &instance,
217
ResourceHandler::AccessPolicy access )
219
, instance_( instance )
222
if ( access_ != ResourceHandler::concurrent )
228
AcquiredResourceHandle::~AcquiredResourceHandle()
230
if ( access_ != ResourceHandler::concurrent )
238
AcquiredResourceHandle::setUp()
245
AcquiredResourceHandle::tearDown()
247
instance_->tearDown();
252
// //////////////////////////////////////////////////////////////////
253
// //////////////////////////////////////////////////////////////////
254
// class ResourceLazyPtr
255
// //////////////////////////////////////////////////////////////////
256
// //////////////////////////////////////////////////////////////////
260
ResourceLazyPtr::operator =( const ResourceLazyPtr &other )
262
ResourceId oldId = id_;
264
ResourceHandlerRegistry ®istry = ResourceHandlerRegistry::instance();
265
registry.increaseLazyRef( id_ );
266
registry.decreaseLazyRef( oldId );
272
AcquiredResourceHandlePtr
273
ResourceLazyPtr::acquire()
277
ResourceHandlerRegistry::instance().obtainResource( id_ );
279
return AcquiredResourceHandlePtr();