Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
Actor Framework
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cpp-libs
Actor Framework
Commits
10a49baa
Commit
10a49baa
authored
Jul 26, 2014
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement DCLP for singletons
The new singleton instantiation pattern fixes #152 and closes #153.
parent
14ab6004
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
34 additions
and
38 deletions
+34
-38
libcaf_core/caf/detail/singletons.hpp
libcaf_core/caf/detail/singletons.hpp
+22
-32
libcaf_core/src/singletons.cpp
libcaf_core/src/singletons.cpp
+12
-6
No files found.
libcaf_core/caf/detail/singletons.hpp
View file @
10a49baa
...
@@ -17,9 +17,10 @@
...
@@ -17,9 +17,10 @@
* http://www.boost.org/LICENSE_1_0.txt. *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
******************************************************************************/
#ifndef CAF_
SINGLETON_MANAGER
_HPP
#ifndef CAF_
DETAIL_SINGLETONS
_HPP
#define CAF_
SINGLETON_MANAGER
_HPP
#define CAF_
DETAIL_SINGLETONS
_HPP
#include <mutex>
#include <atomic>
#include <atomic>
#include <cstddef> // size_t
#include <cstddef> // size_t
...
@@ -43,12 +44,10 @@ class abstract_singleton {
...
@@ -43,12 +44,10 @@ class abstract_singleton {
};
};
class
singletons
{
class
singletons
{
singletons
()
=
delete
;
public:
public:
singletons
()
=
delete
;
static
constexpr
size_t
max_plugin
_singleton
s
=
3
;
static
constexpr
size_t
max_plugins
=
3
;
static
constexpr
size_t
middleman_plugin_id
=
0
;
// io lib
static
constexpr
size_t
middleman_plugin_id
=
0
;
// io lib
...
@@ -82,29 +81,21 @@ class singletons {
...
@@ -82,29 +81,21 @@ class singletons {
static
void
stop_singletons
();
static
void
stop_singletons
();
private:
private:
static
std
::
mutex
&
get_mutex
();
static
std
::
atomic
<
abstract_singleton
*>&
get_plugin_singleton
(
size_t
id
);
static
std
::
atomic
<
abstract_singleton
*>&
get_plugin_singleton
(
size_t
id
);
/*
// Get instance from @p ptr or crate it on-the-fly using DCLP
* Type `T` has to provide: `static T* create_singleton()`,
template
<
class
T
,
class
Factory
>
* `void initialize()`, `void stop()`, and `dispose()`.
*/
template
<
class
T
,
typename
Factory
>
static
T
*
lazy_get
(
std
::
atomic
<
T
*>&
ptr
,
Factory
f
)
{
static
T
*
lazy_get
(
std
::
atomic
<
T
*>&
ptr
,
Factory
f
)
{
T
*
result
=
ptr
.
load
();
auto
result
=
ptr
.
load
(
std
::
memory_order_acquire
);
while
(
result
==
nullptr
)
{
if
(
result
==
nullptr
)
{
auto
tmp
=
f
();
std
::
lock_guard
<
std
::
mutex
>
guard
(
get_mutex
());
// double check if singleton is still undefined
result
=
ptr
.
load
(
std
::
memory_order_relaxed
);
if
(
ptr
.
load
()
==
nullptr
)
{
if
(
result
==
nullptr
)
{
tmp
->
initialize
();
result
=
f
();
if
(
ptr
.
compare_exchange_weak
(
result
,
tmp
))
{
result
->
initialize
();
result
=
tmp
;
ptr
.
store
(
result
,
std
::
memory_order_release
);
}
else
{
tmp
->
stop
();
tmp
->
dispose
();
}
}
else
{
tmp
->
dispose
();
}
}
}
}
return
result
;
return
result
;
...
@@ -123,21 +114,20 @@ class singletons {
...
@@ -123,21 +114,20 @@ class singletons {
template
<
class
T
>
template
<
class
T
>
static
void
dispose
(
std
::
atomic
<
T
*>&
ptr
)
{
static
void
dispose
(
std
::
atomic
<
T
*>&
ptr
)
{
for
(;;)
{
auto
p
=
ptr
.
load
();
auto
p
=
ptr
.
load
();
for
(;;)
{
if
(
p
==
nullptr
)
{
if
(
p
==
nullptr
)
{
return
;
return
;
}
else
if
(
ptr
.
compare_exchange_weak
(
p
,
nullptr
))
{
}
if
(
ptr
.
compare_exchange_weak
(
p
,
nullptr
))
{
p
->
dispose
();
p
->
dispose
();
ptr
=
nullptr
;
return
;
return
;
}
}
}
}
}
}
};
};
}
// namespace detail
}
// namespace detail
}
// namespace caf
}
// namespace caf
#endif // CAF_
SINGLETON_MANAGER
_HPP
#endif // CAF_
DETAIL_SINGLETONS
_HPP
libcaf_core/src/singletons.cpp
View file @
10a49baa
...
@@ -35,7 +35,9 @@ namespace detail {
...
@@ -35,7 +35,9 @@ namespace detail {
namespace
{
namespace
{
std
::
atomic
<
abstract_singleton
*>
s_plugins
[
singletons
::
max_plugin_singletons
];
std
::
mutex
s_singletons_mtx
;
std
::
atomic
<
abstract_singleton
*>
s_plugins
[
singletons
::
max_plugins
];
std
::
atomic
<
scheduler
::
abstract_coordinator
*>
s_scheduling_coordinator
;
std
::
atomic
<
scheduler
::
abstract_coordinator
*>
s_scheduling_coordinator
;
std
::
atomic
<
uniform_type_info_map
*>
s_uniform_type_info_map
;
std
::
atomic
<
uniform_type_info_map
*>
s_uniform_type_info_map
;
std
::
atomic
<
actor_registry
*>
s_actor_registry
;
std
::
atomic
<
actor_registry
*>
s_actor_registry
;
...
@@ -49,7 +51,12 @@ abstract_singleton::~abstract_singleton() {
...
@@ -49,7 +51,12 @@ abstract_singleton::~abstract_singleton() {
// nop
// nop
}
}
std
::
mutex
&
singletons
::
get_mutex
()
{
return
s_singletons_mtx
;
}
void
singletons
::
stop_singletons
()
{
void
singletons
::
stop_singletons
()
{
// stop singletons, i.e., make sure no background threads/actors are running
CAF_LOGF_DEBUG
(
"stop scheduler"
);
CAF_LOGF_DEBUG
(
"stop scheduler"
);
stop
(
s_scheduling_coordinator
);
stop
(
s_scheduling_coordinator
);
CAF_LOGF_DEBUG
(
"stop plugins"
);
CAF_LOGF_DEBUG
(
"stop plugins"
);
...
@@ -64,7 +71,7 @@ void singletons::stop_singletons() {
...
@@ -64,7 +71,7 @@ void singletons::stop_singletons() {
stop
(
s_uniform_type_info_map
);
stop
(
s_uniform_type_info_map
);
stop
(
s_logger
);
stop
(
s_logger
);
stop
(
s_node_id
);
stop
(
s_node_id
);
// dispose singletons
// dispose singletons
, i.e., release memory
dispose
(
s_scheduling_coordinator
);
dispose
(
s_scheduling_coordinator
);
for
(
auto
&
plugin
:
s_plugins
)
{
for
(
auto
&
plugin
:
s_plugins
)
{
dispose
(
plugin
);
dispose
(
plugin
);
...
@@ -92,9 +99,8 @@ scheduler::abstract_coordinator* singletons::get_scheduling_coordinator() {
...
@@ -92,9 +99,8 @@ scheduler::abstract_coordinator* singletons::get_scheduling_coordinator() {
return
lazy_get
(
s_scheduling_coordinator
);
return
lazy_get
(
s_scheduling_coordinator
);
}
}
bool
singletons
::
set_scheduling_coordinator
(
scheduler
::
abstract_coordinator
*
p
)
{
bool
singletons
::
set_scheduling_coordinator
(
scheduler
::
abstract_coordinator
*
p
)
{
scheduler
::
abstract_coordinator
*
expected
=
nullptr
;
return
lazy_get
(
s_scheduling_coordinator
,
[
p
]
{
return
p
;
})
==
p
;
return
s_scheduling_coordinator
.
compare_exchange_weak
(
expected
,
p
);
}
}
node_id
singletons
::
get_node_id
()
{
node_id
singletons
::
get_node_id
()
{
...
@@ -106,7 +112,7 @@ logging* singletons::get_logger() {
...
@@ -106,7 +112,7 @@ logging* singletons::get_logger() {
}
}
std
::
atomic
<
abstract_singleton
*>&
singletons
::
get_plugin_singleton
(
size_t
id
)
{
std
::
atomic
<
abstract_singleton
*>&
singletons
::
get_plugin_singleton
(
size_t
id
)
{
CAF_REQUIRE
(
id
<
max_plugin
_singleton
s
);
CAF_REQUIRE
(
id
<
max_plugins
);
return
s_plugins
[
id
];
return
s_plugins
[
id
];
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment