Skip to content

Commit

Permalink
NestedRegistrationScope is thread safe
Browse files Browse the repository at this point in the history
  • Loading branch information
ybainier committed Apr 28, 2017
1 parent cc44d9e commit 4bd138d
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 15 deletions.
40 changes: 29 additions & 11 deletions Hypodermic/NestedRegistrationScope.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,32 +27,50 @@ namespace Hypodermic

void addRegistration(const std::shared_ptr< IRegistration >& registration) override
{
if (m_scope == nullptr)
m_scope = m_parentScope->clone();

m_scope->addRegistration(registration);
writeScope().addRegistration(registration);
}

bool tryGetRegistrations(const TypeAliasKey& typeAliasKey, std::vector< std::shared_ptr< RegistrationContext > >& registrationContexts) const override
{
return scope().tryGetRegistrations(typeAliasKey, registrationContexts);
}

std::shared_ptr< IRegistrationScope > clone() override
{
std::lock_guard< decltype(m_mutex) > lock(m_mutex);

auto scopeClone = std::make_shared< NestedRegistrationScope >(PrivateTag());
scopeClone->m_parentScope = m_parentScope;
scopeClone->m_scope = m_scope;

return scopeClone;
}

private:
IRegistrationScope& scope() const
{
std::lock_guard< decltype(m_mutex) > lock(m_mutex);

if (m_scope != nullptr)
return m_scope->tryGetRegistrations(typeAliasKey, registrationContexts);
return *m_scope;

return m_parentScope->tryGetRegistrations(typeAliasKey, registrationContexts);
return *m_parentScope;
}

std::shared_ptr< IRegistrationScope > clone() override
IRegistrationScope& writeScope()
{
auto scope = std::make_shared< NestedRegistrationScope >(PrivateTag());
scope->m_parentScope = m_parentScope;
scope->m_scope = m_scope;
std::lock_guard< decltype(m_mutex) > lock(m_mutex);

if (m_scope == nullptr)
m_scope = m_parentScope->clone();

return scope;
return *m_scope;
}

private:
std::shared_ptr< IRegistrationScope > m_parentScope;
std::shared_ptr< IRegistrationScope > m_scope;
mutable std::recursive_mutex m_mutex;
};

} // namespace Hypodermic
10 changes: 6 additions & 4 deletions Hypodermic/RegistrationScope.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,13 @@ namespace Hypodermic

std::shared_ptr< IRegistrationScope > clone() override
{
auto scope = std::make_shared< RegistrationScope >();
scope->m_registrationContextsByBaseTypes = m_registrationContextsByBaseTypes;
scope->m_fallbackRegistrationContextsByBaseTypes = m_fallbackRegistrationContextsByBaseTypes;
std::lock_guard< decltype(m_mutex) > lock(m_mutex);

auto scopeClone = std::make_shared< RegistrationScope >();
scopeClone->m_registrationContextsByBaseTypes = m_registrationContextsByBaseTypes;
scopeClone->m_fallbackRegistrationContextsByBaseTypes = m_fallbackRegistrationContextsByBaseTypes;

return scope;
return scopeClone;
}

private:
Expand Down

0 comments on commit 4bd138d

Please sign in to comment.