Skip to content

Commit 7caec7d

Browse files
committed
add thread safe concept implementation
1 parent 4a8c3a2 commit 7caec7d

File tree

7 files changed

+24
-9
lines changed

7 files changed

+24
-9
lines changed

Include/SevenBit/DI/Details/Core/IServiceInstanceProviderRoot.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#pragma once
22

3+
#include <mutex>
4+
35
#include "SevenBit/DI/LibraryConfig.hpp"
46

57
#include "SevenBit/DI/Details/Containers/ServiceDescriptorsMap.hpp"
@@ -16,6 +18,8 @@ namespace sb::di::details
1618

1719
virtual ServiceInstancesCreator &getRootCreator() = 0;
1820

21+
virtual std::recursive_mutex *tryGetSyncMutex() = 0;
22+
1923
virtual ~IServiceInstanceProviderRoot() = default;
2024
};
2125
} // namespace sb::di::details

Include/SevenBit/DI/Details/Core/ServiceInstanceProvider.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ namespace sb::di::details
3939

4040
[[nodiscard]] IServiceInstanceProvider::Ptr createScope() const override;
4141

42+
std::recursive_mutex *tryGetSyncMutex() override { return _root.tryGetSyncMutex(); }
43+
4244
const ServiceInstance &getInstance(const TypeId serviceTypeId) override
4345
{
4446
return getInstance(ServiceId{serviceTypeId});

Include/SevenBit/DI/Details/Core/ServiceInstanceProviderRoot.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ namespace sb::di::details
1313
{
1414
ServiceDescriptorsMap _descriptorsMap;
1515
ServiceInstancesMap _singletons;
16+
std::unique_ptr<std::recursive_mutex> _mutex;
1617

1718
public:
1819
using Ptr = std::unique_ptr<ServiceInstanceProviderRoot>;
@@ -26,6 +27,10 @@ namespace sb::di::details
2627
_descriptorsMap(begin, end, options.checkServiceGlobalUniqueness),
2728
_singletons(options.strongDestructionOrder)
2829
{
30+
if (options.threadSafe)
31+
{
32+
_mutex = std::make_unique<std::recursive_mutex>();
33+
}
2934
_descriptorsMap.seal();
3035
}
3136

@@ -37,6 +42,8 @@ namespace sb::di::details
3742

3843
ServiceInstancesCreator &getRootCreator() override { return getCreator(); }
3944

45+
std::recursive_mutex *tryGetSyncMutex() override { return _mutex.get(); }
46+
4047
private:
4148
void prebuildSingletons();
4249
};

Include/SevenBit/DI/IServiceInstanceProvider.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22

33
#include <memory>
4+
#include <mutex>
45
#include <optional>
56
#include <string_view>
67

@@ -29,6 +30,8 @@ namespace sb::di
2930
*/
3031
[[nodiscard]] virtual Ptr createScope() const = 0;
3132

33+
virtual std::recursive_mutex *tryGetSyncMutex() = 0;
34+
3235
/**
3336
* @brief Returns service instance reference, might throw exception
3437
* @details If service was not registered or was registered as transient, method throws exception

Include/SevenBit/DI/Impl/ServiceCollection.hpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ namespace sb::di
1111
{
1212
INLINE ServiceProvider ServiceCollection::buildServiceProvider(ServiceProviderOptions options)
1313
{
14-
return ServiceProvider{std::make_unique<details::ServiceInstanceProviderRoot>(begin(), end(), options),
15-
options.threadSafe};
14+
return ServiceProvider{std::make_unique<details::ServiceInstanceProviderRoot>(begin(), end(), options)};
1615
}
1716

1817
INLINE ServiceProvider::Ptr ServiceCollection::buildServiceProviderAsPtr(ServiceProviderOptions options)

Include/SevenBit/DI/ServiceProvider.hpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,16 @@ namespace sb::di
1616
class ServiceProvider
1717
{
1818
IServiceInstanceProvider::Ptr _instanceProvider;
19-
std::unique_ptr<std::recursive_mutex> _mutex;
2019

2120
public:
2221
using Ptr = std::unique_ptr<ServiceProvider>;
2322

2423
/**
2524
* @brief Constructs service provider with specified instance provider
2625
*/
27-
explicit ServiceProvider(IServiceInstanceProvider::Ptr instanceProvider, const bool threadSafe = false)
26+
explicit ServiceProvider(IServiceInstanceProvider::Ptr instanceProvider)
2827
: _instanceProvider(std::move(instanceProvider))
2928
{
30-
if (threadSafe)
31-
{
32-
_mutex = std::make_unique<std::recursive_mutex>();
33-
}
3429
details::Require::notNull(_instanceProvider);
3530
getInstanceProvider().init(*this);
3631
}
@@ -422,7 +417,11 @@ namespace sb::di
422417
private:
423418
std::optional<std::unique_lock<std::recursive_mutex>> tryUniqueLock()
424419
{
425-
return _mutex ? std::make_optional(std::unique_lock{*_mutex}) : std::nullopt;
420+
if (const auto mutex = getInstanceProvider().tryGetSyncMutex())
421+
{
422+
return std::unique_lock{*mutex};
423+
}
424+
return std::nullopt;
426425
}
427426
};
428427
} // namespace sb::di

Tests/Helpers/Mocks/ServiceInstanceProviderMock.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
struct ServiceInstanceProviderMock : public sb::di::IServiceInstanceProvider
88
{
99
MOCK_METHOD((std::unique_ptr<sb::di::IServiceInstanceProvider>), createScope, (), (const override));
10+
MOCK_METHOD((std::recursive_mutex *), tryGetSyncMutex, (), (override));
1011
MOCK_METHOD((void), init, (sb::di::ServiceProvider &), (override));
1112
MOCK_METHOD((const sb::di::ServiceInstance *), tryGetInstance, (sb::di::TypeId serviceTypeId), (override));
1213
MOCK_METHOD((const sb::di::ServiceInstance &), getInstance, (sb::di::TypeId serviceTypeId), (override));

0 commit comments

Comments
 (0)