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
15d04e37
Commit
15d04e37
authored
Oct 17, 2017
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #610
parents
f214b791
d8dc4018
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
189 additions
and
1 deletion
+189
-1
libcaf_core/caf/actor_system.hpp
libcaf_core/caf/actor_system.hpp
+8
-0
libcaf_core/caf/actor_system_config.hpp
libcaf_core/caf/actor_system_config.hpp
+14
-0
libcaf_core/caf/all.hpp
libcaf_core/caf/all.hpp
+1
-0
libcaf_core/caf/scheduler/worker.hpp
libcaf_core/caf/scheduler/worker.hpp
+2
-0
libcaf_core/caf/thread_hook.hpp
libcaf_core/caf/thread_hook.hpp
+48
-0
libcaf_core/src/actor_system.cpp
libcaf_core/src/actor_system.cpp
+12
-0
libcaf_core/src/blocking_actor.cpp
libcaf_core/src/blocking_actor.cpp
+2
-0
libcaf_core/src/logger.cpp
libcaf_core/src/logger.cpp
+5
-1
libcaf_core/src/private_thread.cpp
libcaf_core/src/private_thread.cpp
+2
-0
libcaf_core/test/thread_hook.cpp
libcaf_core/test/thread_hook.cpp
+93
-0
libcaf_io/src/middleman.cpp
libcaf_io/src/middleman.cpp
+2
-0
No files found.
libcaf_core/caf/actor_system.hpp
View file @
15d04e37
...
...
@@ -491,6 +491,14 @@ public:
/// Blocks the caller until all detached threads are done.
void
await_detached_threads
();
/// Calls all thread started hooks
/// @warning must be called by thread which is about to start
void
thread_started
();
/// Calls all thread terminates hooks
/// @warning must be called by thread which is about to terminate
void
thread_terminates
();
/// @endcond
private:
...
...
libcaf_core/caf/actor_system_config.hpp
View file @
15d04e37
...
...
@@ -30,6 +30,7 @@
#include "caf/fwd.hpp"
#include "caf/stream.hpp"
#include "caf/thread_hook.hpp"
#include "caf/config_value.hpp"
#include "caf/config_option.hpp"
#include "caf/actor_factory.hpp"
...
...
@@ -51,6 +52,8 @@ public:
using
hook_factory_vector
=
std
::
vector
<
hook_factory
>
;
using
thread_hooks
=
std
::
vector
<
std
::
unique_ptr
<
thread_hook
>>
;
template
<
class
K
,
class
V
>
using
hash_map
=
std
::
unordered_map
<
K
,
V
>
;
...
...
@@ -224,6 +227,13 @@ public:
});
}
/// Adds a hook type to the scheduler.
template
<
class
Hook
,
class
...
Ts
>
actor_system_config
&
add_thread_hook
(
Ts
&&
...
ts
)
{
thread_hooks_
.
emplace_back
(
new
Hook
(
std
::
forward
<
Ts
>
(
ts
)...));
return
*
this
;
}
/// Stores whether the help text for this config object was
/// printed. If set to `true`, the application should not use
/// this config object to initialize an `actor_system` and
...
...
@@ -310,6 +320,10 @@ public:
hook_factory_vector
hook_factories
;
group_module_factory_vector
group_module_factories
;
// -- hooks ------------------------------------------------------------------
thread_hooks
thread_hooks_
;
// -- run-time type information ----------------------------------------------
portable_name_map
type_names_by_rtti
;
...
...
libcaf_core/caf/all.hpp
View file @
15d04e37
...
...
@@ -56,6 +56,7 @@
#include "caf/exit_reason.hpp"
#include "caf/local_actor.hpp"
#include "caf/ref_counted.hpp"
#include "caf/thread_hook.hpp"
#include "caf/typed_actor.hpp"
#include "caf/actor_system.hpp"
#include "caf/deserializer.hpp"
...
...
libcaf_core/caf/scheduler/worker.hpp
View file @
15d04e37
...
...
@@ -55,7 +55,9 @@ public:
CAF_ASSERT
(
this_thread_
.
get_id
()
==
std
::
thread
::
id
{});
auto
this_worker
=
this
;
this_thread_
=
std
::
thread
{[
this_worker
]
{
this_worker
->
system
().
thread_started
();
this_worker
->
run
();
this_worker
->
system
().
thread_terminates
();
}};
}
...
...
libcaf_core/caf/thread_hook.hpp
0 → 100644
View file @
15d04e37
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright (C) 2011 - 2017 *
* Dominik Charousset <dominik.charousset (at) haw-hamburg.de> *
* *
* 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. *
******************************************************************************/
#ifndef CAF_THREAD_HOOK_HPP
#define CAF_THREAD_HOOK_HPP
namespace
caf
{
/// Interface to define thread hooks.
class
thread_hook
{
public:
virtual
~
thread_hook
()
{
// nop
}
/// Called by the actor system once before starting any threads.
virtual
void
init
(
actor_system
&
)
=
0
;
/// Called whenever the actor system has started a new thread.
/// To access a reference to the started thread use `std::this_thread`.
/// @warning must the thread-safe
virtual
void
thread_started
()
=
0
;
/// Called whenever a thread is about to quit.
/// To access a reference to the terminating thread use `std::this_thread`.
/// @warning must the thread-safe
virtual
void
thread_terminates
()
=
0
;
};
}
// namespace caf
#endif // CAF_THREAD_HOOK_HPP
libcaf_core/src/actor_system.cpp
View file @
15d04e37
...
...
@@ -215,6 +215,8 @@ actor_system::actor_system(actor_system_config& cfg)
cfg_
(
cfg
),
logger_dtor_done_
(
false
)
{
CAF_SET_LOGGER_SYS
(
this
);
for
(
auto
&
hook
:
cfg
.
thread_hooks_
)
hook
->
init
(
*
this
);
for
(
auto
&
f
:
cfg
.
module_factories
)
{
auto
mod_ptr
=
f
(
*
this
);
modules_
[
mod_ptr
->
id
()].
reset
(
mod_ptr
);
...
...
@@ -417,6 +419,16 @@ void actor_system::await_detached_threads() {
detached_cv
.
wait
(
guard
);
}
void
actor_system
::
thread_started
()
{
for
(
auto
&
hook
:
cfg_
.
thread_hooks_
)
hook
->
thread_started
();
}
void
actor_system
::
thread_terminates
()
{
for
(
auto
&
hook
:
cfg_
.
thread_hooks_
)
hook
->
thread_terminates
();
}
expected
<
strong_actor_ptr
>
actor_system
::
dyn_spawn_impl
(
const
std
::
string
&
name
,
message
&
args
,
execution_unit
*
ctx
,
bool
check_interface
,
...
...
libcaf_core/src/blocking_actor.cpp
View file @
15d04e37
...
...
@@ -91,6 +91,7 @@ void blocking_actor::launch(execution_unit*, bool, bool hide) {
home_system
().
inc_detached_threads
();
std
::
thread
([](
strong_actor_ptr
ptr
)
{
// actor lives in its own thread
ptr
->
home_system
->
thread_started
();
auto
this_ptr
=
ptr
->
get
();
CAF_ASSERT
(
dynamic_cast
<
blocking_actor
*>
(
this_ptr
)
!=
0
);
auto
self
=
static_cast
<
blocking_actor
*>
(
this_ptr
);
...
...
@@ -119,6 +120,7 @@ void blocking_actor::launch(execution_unit*, bool, bool hide) {
# endif
self
->
cleanup
(
std
::
move
(
rsn
),
self
->
context
());
ptr
->
home_system
->
dec_detached_threads
();
ptr
->
home_system
->
thread_terminates
();
},
strong_actor_ptr
{
ctrl
()}).
detach
();
}
...
...
libcaf_core/src/logger.cpp
View file @
15d04e37
...
...
@@ -505,7 +505,11 @@ void logger::start() {
if
(
inline_output_
)
log_first_line
();
else
thread_
=
std
::
thread
{[
this
]
{
this
->
run
();
}};
thread_
=
std
::
thread
{[
this
]
{
this
->
system_
.
thread_started
();
this
->
run
();
this
->
system_
.
thread_terminates
();
}};
#endif
}
...
...
libcaf_core/src/private_thread.cpp
View file @
15d04e37
...
...
@@ -85,12 +85,14 @@ void private_thread::shutdown() {
}
void
private_thread
::
exec
(
private_thread
*
this_ptr
)
{
this_ptr
->
system_
.
thread_started
();
this_ptr
->
run
();
// make sure to not destroy the private thread object before the
// detached actor is destroyed and this object is unreachable
this_ptr
->
await_self_destroyed
();
// signalize destruction of detached thread to registry
this_ptr
->
system_
.
dec_detached_threads
();
this_ptr
->
system_
.
thread_terminates
();
// done
delete
this_ptr
;
}
...
...
libcaf_core/test/thread_hook.cpp
0 → 100644
View file @
15d04e37
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright (C) 2011 - 2017 *
* Dominik Charousset <dominik.charousset (at) haw-hamburg.de> *
* *
* 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. *
******************************************************************************/
#include "caf/config.hpp"
// this suite tests whether actors terminate as expect in several use cases
#define CAF_SUITE thread_hook
#include "caf/all.hpp"
#include "caf/test/unit_test.hpp"
using
namespace
caf
;
namespace
{
class
test_thread_hooks
:
public
thread_hook
{
using
atomic_cnt
=
std
::
atomic
<
size_t
>
;
public:
test_thread_hooks
(
size_t
assumed_init
,
size_t
assumed_thread_started
,
size_t
assumed_thread_termintes_cb
)
:
count_init_
{
0
},
count_thread_started_
{
0
},
count_thread_terminates_
{
0
},
assumed_init_
{
assumed_init
},
assumed_thread_started_
{
assumed_thread_started
},
assumed_thread_termintes_cb_
{
assumed_thread_termintes_cb
}
{
// nop
}
virtual
~
test_thread_hooks
()
{
CAF_CHECK_EQUAL
(
count_init_
,
assumed_init_
);
CAF_CHECK_EQUAL
(
count_thread_started_
,
assumed_thread_started_
);
CAF_CHECK_EQUAL
(
count_thread_terminates_
,
assumed_thread_termintes_cb_
);
}
virtual
void
init
(
actor_system
&
)
{
count_init_
.
fetch_add
(
1
,
std
::
memory_order_relaxed
);
}
virtual
void
thread_started
()
{
count_thread_started_
.
fetch_add
(
1
,
std
::
memory_order_relaxed
);
}
virtual
void
thread_terminates
()
{
count_thread_terminates_
.
fetch_add
(
1
,
std
::
memory_order_relaxed
);
}
private:
atomic_cnt
count_init_
;
atomic_cnt
count_thread_started_
;
atomic_cnt
count_thread_terminates_
;
atomic_cnt
assumed_init_
;
atomic_cnt
assumed_thread_started_
;
atomic_cnt
assumed_thread_termintes_cb_
;
};
}
// namespace <anonymous>
CAF_TEST
(
test_no_args
)
{
actor_system_config
cfg
{};
struct
a
:
public
thread_hook
{
virtual
void
init
(
actor_system
&
)
{}
virtual
void
thread_started
()
{}
virtual
void
thread_terminates
()
{}
};
cfg
.
add_thread_hook
<
a
>
();
}
CAF_TEST
(
test_no_system
)
{
actor_system_config
cfg
{};
cfg
.
add_thread_hook
<
test_thread_hooks
>
(
0
,
0
,
0
);
}
CAF_TEST
(
test_system_no_actor
)
{
actor_system_config
cfg
{};
size_t
assumed_threads
=
2
+
cfg
.
scheduler_max_threads
;
#ifdef CAF_LOG_LEVEL
assumed_threads
+=
1
;
// If logging is enabled, we have a additional thread.
#endif
cfg
.
add_thread_hook
<
test_thread_hooks
>
(
1
,
assumed_threads
,
assumed_threads
);
actor_system
system
{
cfg
};
}
libcaf_io/src/middleman.cpp
View file @
15d04e37
...
...
@@ -269,6 +269,7 @@ void middleman::start() {
std
::
condition_variable
cv
;
thread_
=
std
::
thread
{[
&
,
this
]
{
CAF_SET_LOGGER_SYS
(
&
system
());
system
().
thread_started
();
CAF_LOG_TRACE
(
""
);
{
std
::
unique_lock
<
std
::
mutex
>
guard
{
mtx
};
...
...
@@ -277,6 +278,7 @@ void middleman::start() {
cv
.
notify_one
();
}
backend
().
run
();
system
().
thread_terminates
();
}};
std
::
unique_lock
<
std
::
mutex
>
guard
{
mtx
};
while
(
init_done
==
false
)
...
...
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