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
6f24e37a
Commit
6f24e37a
authored
Nov 14, 2018
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'topic/actor-registry-deadlock'
parents
7c8d47af
cb9fb971
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
83 additions
and
8 deletions
+83
-8
libcaf_core/src/actor_registry.cpp
libcaf_core/src/actor_registry.cpp
+28
-8
libcaf_core/test/actor_registry.cpp
libcaf_core/test/actor_registry.cpp
+55
-0
No files found.
libcaf_core/src/actor_registry.cpp
View file @
6f24e37a
...
...
@@ -81,8 +81,19 @@ void actor_registry::put_impl(actor_id key, strong_actor_ptr val) {
}
void
actor_registry
::
erase
(
actor_id
key
)
{
exclusive_guard
guard
{
instances_mtx_
};
entries_
.
erase
(
key
);
// Stores a reference to the actor we're going to remove. This guarantees
// that we aren't releasing the last reference to an actor while erasing it.
// Releasing the final ref can trigger the actor to call its cleanup function
// that in turn calls this function and we can end up in a deadlock.
strong_actor_ptr
ref
;
{
// Lifetime scope of guard.
exclusive_guard
guard
{
instances_mtx_
};
auto
i
=
entries_
.
find
(
key
);
if
(
i
!=
entries_
.
end
())
{
ref
.
swap
(
i
->
second
);
entries_
.
erase
(
i
);
}
}
}
void
actor_registry
::
inc_running
()
{
...
...
@@ -126,17 +137,26 @@ strong_actor_ptr actor_registry::get_impl(atom_value key) const {
}
void
actor_registry
::
put_impl
(
atom_value
key
,
strong_actor_ptr
value
)
{
if
(
value
)
value
->
get
()
->
attach_functor
([
=
]
{
system_
.
registry
().
put_impl
(
key
,
nullptr
)
;
});
if
(
value
==
nullptr
)
{
erase
(
key
);
return
;
}
exclusive_guard
guard
{
named_entries_mtx_
};
named_entries_
.
emplace
(
key
,
std
::
move
(
value
));
}
void
actor_registry
::
erase
(
atom_value
key
)
{
exclusive_guard
guard
{
named_entries_mtx_
};
named_entries_
.
erase
(
key
);
// Stores a reference to the actor we're going to remove for the same
// reasoning as in erase(actor_id).
strong_actor_ptr
ref
;
{
// Lifetime scope of guard.
exclusive_guard
guard
{
named_entries_mtx_
};
auto
i
=
named_entries_
.
find
(
key
);
if
(
i
!=
named_entries_
.
end
())
{
ref
.
swap
(
i
->
second
);
named_entries_
.
erase
(
i
);
}
}
}
auto
actor_registry
::
named_actors
()
const
->
name_map
{
...
...
libcaf_core/test/actor_registry.cpp
0 → 100644
View file @
6f24e37a
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2018 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#define CAF_SUITE actor_registry
#include "caf/actor_registry.hpp"
#include "caf/test/dsl.hpp"
using
namespace
caf
;
namespace
{
behavior
dummy
()
{
return
{
[](
int
i
)
{
return
i
;
}
};
}
using
foo_atom
=
atom_constant
<
atom
(
"foo"
)
>
;
}
// namespace <anonymous>
CAF_TEST_FIXTURE_SCOPE
(
actor_registry_tests
,
test_coordinator_fixture
<>
)
CAF_TEST
(
erase
)
{
// CAF registers a few actors by itself.
auto
baseline
=
sys
.
registry
().
named_actors
().
size
();
sys
.
registry
().
put
(
foo_atom
::
value
,
sys
.
spawn
(
dummy
));
CAF_CHECK_EQUAL
(
sys
.
registry
().
named_actors
().
size
(),
baseline
+
1u
);
self
->
send
(
sys
.
registry
().
get
<
actor
>
(
foo_atom
::
value
),
42
);
run
();
expect
((
int
),
from
(
_
).
to
(
self
).
with
(
42
));
sys
.
registry
().
erase
(
foo_atom
::
value
);
CAF_CHECK_EQUAL
(
sys
.
registry
().
named_actors
().
size
(),
baseline
);
}
CAF_TEST_FIXTURE_SCOPE_END
()
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