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
4126af45
Commit
4126af45
authored
Mar 14, 2014
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
properly spawn new actors in same worker as parent
parent
1ad4a179
Changes
11
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
189 additions
and
116 deletions
+189
-116
cppa/detail/proper_actor.hpp
cppa/detail/proper_actor.hpp
+4
-4
cppa/local_actor.hpp
cppa/local_actor.hpp
+27
-22
cppa/logging.hpp
cppa/logging.hpp
+5
-1
cppa/policy/context_switching_resume.hpp
cppa/policy/context_switching_resume.hpp
+2
-2
cppa/policy/cooperative_scheduling.hpp
cppa/policy/cooperative_scheduling.hpp
+3
-2
cppa/policy/event_based_resume.hpp
cppa/policy/event_based_resume.hpp
+2
-1
cppa/policy/no_scheduling.hpp
cppa/policy/no_scheduling.hpp
+1
-1
cppa/spawn.hpp
cppa/spawn.hpp
+90
-55
cppa/spawn_fwd.hpp
cppa/spawn_fwd.hpp
+35
-19
src/logging.cpp
src/logging.cpp
+6
-6
src/scheduler.cpp
src/scheduler.cpp
+14
-3
No files found.
cppa/detail/proper_actor.hpp
View file @
4126af45
...
@@ -188,7 +188,7 @@ class proper_actor : public proper_actor_base<Base,
...
@@ -188,7 +188,7 @@ class proper_actor : public proper_actor_base<Base,
template
<
typename
...
Ts
>
template
<
typename
...
Ts
>
proper_actor
(
Ts
&&
...
args
)
:
super
(
std
::
forward
<
Ts
>
(
args
)...)
{
}
proper_actor
(
Ts
&&
...
args
)
:
super
(
std
::
forward
<
Ts
>
(
args
)...)
{
}
inline
void
launch
(
bool
is_hidden
)
{
inline
void
launch
(
bool
is_hidden
,
execution_unit
*
host
)
{
CPPA_LOG_TRACE
(
""
);
CPPA_LOG_TRACE
(
""
);
this
->
hidden
(
is_hidden
);
this
->
hidden
(
is_hidden
);
auto
bhvr
=
this
->
make_behavior
();
auto
bhvr
=
this
->
make_behavior
();
...
@@ -196,7 +196,7 @@ class proper_actor : public proper_actor_base<Base,
...
@@ -196,7 +196,7 @@ class proper_actor : public proper_actor_base<Base,
CPPA_LOG_WARNING_IF
(
this
->
bhvr_stack
().
empty
(),
CPPA_LOG_WARNING_IF
(
this
->
bhvr_stack
().
empty
(),
"actor did not set a behavior"
);
"actor did not set a behavior"
);
if
(
!
this
->
bhvr_stack
().
empty
())
{
if
(
!
this
->
bhvr_stack
().
empty
())
{
this
->
scheduling_policy
().
launch
(
this
);
this
->
scheduling_policy
().
launch
(
this
,
host
);
}
}
}
}
...
@@ -256,9 +256,9 @@ class proper_actor<Base, Policies,true> : public proper_actor_base<Base,
...
@@ -256,9 +256,9 @@ class proper_actor<Base, Policies,true> : public proper_actor_base<Base,
this
->
resume_policy
().
await_ready
(
this
);
this
->
resume_policy
().
await_ready
(
this
);
}
}
inline
void
launch
(
bool
is_hidden
)
{
inline
void
launch
(
bool
is_hidden
,
execution_unit
*
host
)
{
this
->
hidden
(
is_hidden
);
this
->
hidden
(
is_hidden
);
this
->
scheduling_policy
().
launch
(
this
);
this
->
scheduling_policy
().
launch
(
this
,
host
);
}
}
// implement blocking_actor::dequeue_response
// implement blocking_actor::dequeue_response
...
...
cppa/local_actor.hpp
View file @
4126af45
...
@@ -52,7 +52,6 @@
...
@@ -52,7 +52,6 @@
#include "cppa/message_header.hpp"
#include "cppa/message_header.hpp"
#include "cppa/abstract_actor.hpp"
#include "cppa/abstract_actor.hpp"
#include "cppa/abstract_group.hpp"
#include "cppa/abstract_group.hpp"
#include "cppa/execution_unit.hpp"
#include "cppa/mailbox_element.hpp"
#include "cppa/mailbox_element.hpp"
#include "cppa/response_promise.hpp"
#include "cppa/response_promise.hpp"
#include "cppa/message_priority.hpp"
#include "cppa/message_priority.hpp"
...
@@ -68,7 +67,6 @@
...
@@ -68,7 +67,6 @@
namespace
cppa
{
namespace
cppa
{
// forward declarations
// forward declarations
class
execution_unit
;
class
sync_handle_helper
;
class
sync_handle_helper
;
/**
/**
...
@@ -94,28 +92,32 @@ class local_actor : public extend<abstract_actor>::with<memory_cached> {
...
@@ -94,28 +92,32 @@ class local_actor : public extend<abstract_actor>::with<memory_cached> {
template
<
class
C
,
spawn_options
Os
=
no_spawn_options
,
typename
...
Ts
>
template
<
class
C
,
spawn_options
Os
=
no_spawn_options
,
typename
...
Ts
>
actor
spawn
(
Ts
&&
...
args
)
{
actor
spawn
(
Ts
&&
...
args
)
{
constexpr
auto
os
=
make_unbound
(
Os
);
constexpr
auto
os
=
make_unbound
(
Os
);
auto
res
=
cppa
::
spawn
<
C
,
os
>
(
std
::
forward
<
Ts
>
(
args
)...);
auto
res
=
spawn_class
<
C
,
os
>
(
m_host
,
empty_before_launch_callback
{},
std
::
forward
<
Ts
>
(
args
)...);
return
eval_opts
(
Os
,
std
::
move
(
res
));
return
eval_opts
(
Os
,
std
::
move
(
res
));
}
}
template
<
spawn_options
Os
=
no_spawn_options
,
typename
...
Ts
>
template
<
spawn_options
Os
=
no_spawn_options
,
typename
...
Ts
>
actor
spawn
(
Ts
&&
...
args
)
{
actor
spawn
(
Ts
&&
...
args
)
{
constexpr
auto
os
=
make_unbound
(
Os
);
constexpr
auto
os
=
make_unbound
(
Os
);
auto
res
=
cppa
::
spawn
<
os
>
(
std
::
forward
<
Ts
>
(
args
)...);
auto
res
=
spawn_functor
<
os
>
(
m_host
,
empty_before_launch_callback
{},
std
::
forward
<
Ts
>
(
args
)...);
return
eval_opts
(
Os
,
std
::
move
(
res
));
return
eval_opts
(
Os
,
std
::
move
(
res
));
}
}
template
<
spawn_options
Os
=
no_spawn_option
s
,
typename
...
Ts
>
template
<
class
C
,
spawn_options
O
s
,
typename
...
Ts
>
actor
spawn_in_group
(
const
group
&
grp
,
Ts
&&
...
args
)
{
actor
spawn_in_group
(
const
group
&
grp
,
Ts
&&
...
args
)
{
constexpr
auto
os
=
make_unbound
(
Os
);
constexpr
auto
os
=
make_unbound
(
Os
);
auto
res
=
cppa
::
spawn_in_group
<
os
>
(
grp
,
std
::
forward
<
Ts
>
(
args
)...);
auto
res
=
spawn_class
<
C
,
os
>
(
m_host
,
group_subscriber
{
grp
},
std
::
forward
<
Ts
>
(
args
)...);
return
eval_opts
(
Os
,
std
::
move
(
res
));
return
eval_opts
(
Os
,
std
::
move
(
res
));
}
}
template
<
class
C
,
spawn_options
O
s
,
typename
...
Ts
>
template
<
spawn_options
Os
=
no_spawn_option
s
,
typename
...
Ts
>
actor
spawn_in_group
(
const
group
&
grp
,
Ts
&&
...
args
)
{
actor
spawn_in_group
(
const
group
&
grp
,
Ts
&&
...
args
)
{
constexpr
auto
os
=
make_unbound
(
Os
);
constexpr
auto
os
=
make_unbound
(
Os
);
auto
res
=
cppa
::
spawn_in_group
<
C
,
os
>
(
grp
,
std
::
forward
<
Ts
>
(
args
)...);
auto
res
=
spawn_functor
<
os
>
(
m_host
,
group_subscriber
{
grp
},
std
::
forward
<
Ts
>
(
args
)...);
return
eval_opts
(
Os
,
std
::
move
(
res
));
return
eval_opts
(
Os
,
std
::
move
(
res
));
}
}
...
@@ -123,6 +125,17 @@ class local_actor : public extend<abstract_actor>::with<memory_cached> {
...
@@ -123,6 +125,17 @@ class local_actor : public extend<abstract_actor>::with<memory_cached> {
* spawn typed actors *
* spawn typed actors *
**************************************************************************/
**************************************************************************/
template
<
class
C
,
spawn_options
Os
=
no_spawn_options
,
typename
...
Ts
>
typename
detail
::
actor_handle_from_signature_list
<
typename
C
::
signatures
>::
type
spawn_typed
(
Ts
&&
...
args
)
{
constexpr
auto
os
=
make_unbound
(
Os
);
auto
res
=
spawn_class
<
C
,
os
>
(
m_host
,
empty_before_launch_callback
{},
std
::
forward
<
Ts
>
(
args
)...);
return
eval_opts
(
Os
,
std
::
move
(
res
));
}
template
<
spawn_options
Os
=
no_spawn_options
,
typename
F
,
typename
...
Ts
>
template
<
spawn_options
Os
=
no_spawn_options
,
typename
F
,
typename
...
Ts
>
typename
detail
::
infer_typed_actor_handle
<
typename
detail
::
infer_typed_actor_handle
<
typename
util
::
get_callable_trait
<
F
>::
result_type
,
typename
util
::
get_callable_trait
<
F
>::
result_type
,
...
@@ -132,21 +145,13 @@ class local_actor : public extend<abstract_actor>::with<memory_cached> {
...
@@ -132,21 +145,13 @@ class local_actor : public extend<abstract_actor>::with<memory_cached> {
>::
type
>::
type
spawn_typed
(
F
fun
,
Ts
&&
...
args
)
{
spawn_typed
(
F
fun
,
Ts
&&
...
args
)
{
constexpr
auto
os
=
make_unbound
(
Os
);
constexpr
auto
os
=
make_unbound
(
Os
);
auto
res
=
cppa
::
spawn_typed
<
os
>
(
std
::
move
(
fun
),
auto
res
=
cppa
::
spawn_typed_functor
<
os
>
(
m_host
,
empty_before_launch_callback
{},
std
::
move
(
fun
),
std
::
forward
<
Ts
>
(
args
)...);
std
::
forward
<
Ts
>
(
args
)...);
return
eval_opts
(
Os
,
std
::
move
(
res
));
return
eval_opts
(
Os
,
std
::
move
(
res
));
}
}
template
<
class
C
,
spawn_options
Os
=
no_spawn_options
,
typename
...
Ts
>
typename
detail
::
actor_handle_from_signature_list
<
typename
C
::
signatures
>::
type
spawn_typed
(
Ts
&&
...
args
)
{
constexpr
auto
os
=
make_unbound
(
Os
);
auto
res
=
cppa
::
spawn_typed
<
C
,
os
>
(
std
::
forward
<
Ts
>
(
args
)...);
return
eval_opts
(
Os
,
std
::
move
(
res
));
}
/**************************************************************************
/**************************************************************************
* send asynchronous messages *
* send asynchronous messages *
**************************************************************************/
**************************************************************************/
...
@@ -472,10 +477,10 @@ class local_actor : public extend<abstract_actor>::with<memory_cached> {
...
@@ -472,10 +477,10 @@ class local_actor : public extend<abstract_actor>::with<memory_cached> {
template
<
class
ActorHandle
>
template
<
class
ActorHandle
>
inline
ActorHandle
eval_opts
(
spawn_options
opts
,
ActorHandle
res
)
{
inline
ActorHandle
eval_opts
(
spawn_options
opts
,
ActorHandle
res
)
{
if
(
has_monitor_flag
(
opts
))
{
if
(
has_monitor_flag
(
opts
))
{
monitor
(
res
.
address
());
monitor
(
res
->
address
());
}
}
if
(
has_link_flag
(
opts
))
{
if
(
has_link_flag
(
opts
))
{
link_to
(
res
.
address
());
link_to
(
res
->
address
());
}
}
return
res
;
return
res
;
}
}
...
...
cppa/logging.hpp
View file @
4126af45
...
@@ -70,7 +70,7 @@ class logging {
...
@@ -70,7 +70,7 @@ class logging {
// associates given actor id with this thread,
// associates given actor id with this thread,
// returns the previously set actor id
// returns the previously set actor id
virtual
actor_id
set_aid
(
actor_id
aid
)
=
0
;
actor_id
set_aid
(
actor_id
aid
)
;
virtual
void
log
(
const
char
*
level
,
virtual
void
log
(
const
char
*
level
,
const
char
*
class_name
,
const
char
*
class_name
,
...
@@ -176,6 +176,7 @@ oss_wr operator<<(oss_wr&& lhs, T rhs) {
...
@@ -176,6 +176,7 @@ oss_wr operator<<(oss_wr&& lhs, T rhs) {
# define CPPA_LOG_IMPL(lvlname, classname, funname, message) \
# define CPPA_LOG_IMPL(lvlname, classname, funname, message) \
CPPA_PRINT_ERROR_IMPL(lvlname, classname, funname, message)
CPPA_PRINT_ERROR_IMPL(lvlname, classname, funname, message)
# define CPPA_PUSH_AID(unused) static_cast<void>(0)
# define CPPA_PUSH_AID(unused) static_cast<void>(0)
# define CPPA_PUSH_AID_FROM_PTR(unused) static_cast<void>(0)
# define CPPA_SET_AID(unused) cppa_set_aid_dummy()
# define CPPA_SET_AID(unused) cppa_set_aid_dummy()
# define CPPA_LOG_LEVEL 1
# define CPPA_LOG_LEVEL 1
#else
#else
...
@@ -190,6 +191,9 @@ oss_wr operator<<(oss_wr&& lhs, T rhs) {
...
@@ -190,6 +191,9 @@ oss_wr operator<<(oss_wr&& lhs, T rhs) {
auto aid_pop_guard = ::cppa::util::make_scope_guard([=] { \
auto aid_pop_guard = ::cppa::util::make_scope_guard([=] { \
::cppa::get_logger()->set_aid(prev_aid_in_scope); \
::cppa::get_logger()->set_aid(prev_aid_in_scope); \
})
})
# define CPPA_PUSH_AID_FROM_PTR(some_ptr) \
auto aid_ptr_argument = some_ptr; \
CPPA_PUSH_AID(aid_ptr_argument ? aid_ptr_argument->id() : 0)
# define CPPA_SET_AID(aid_arg) \
# define CPPA_SET_AID(aid_arg) \
::cppa::get_logger()->set_aid(aid_arg)
::cppa::get_logger()->set_aid(aid_arg)
#endif
#endif
...
...
cppa/policy/context_switching_resume.hpp
View file @
4126af45
...
@@ -80,8 +80,8 @@ class context_switching_resume {
...
@@ -80,8 +80,8 @@ class context_switching_resume {
resumable
::
resume_result
resume
(
detail
::
cs_thread
*
from
,
resumable
::
resume_result
resume
(
detail
::
cs_thread
*
from
,
execution_unit
*
host
)
override
{
execution_unit
*
host
)
override
{
CPPA_REQUIRE
(
from
!=
nullptr
);
CPPA_REQUIRE
(
from
!=
nullptr
&&
host
!=
nullptr
);
CPPA_
PUSH_AID
(
this
->
id
()
);
CPPA_
LOG_TRACE
(
""
);
this
->
m_host
=
host
;
this
->
m_host
=
host
;
using
namespace
detail
;
using
namespace
detail
;
for
(;;)
{
for
(;;)
{
...
...
cppa/policy/cooperative_scheduling.hpp
View file @
4126af45
...
@@ -82,10 +82,11 @@ class cooperative_scheduling {
...
@@ -82,10 +82,11 @@ class cooperative_scheduling {
}
}
template
<
class
Actor
>
template
<
class
Actor
>
inline
void
launch
(
Actor
*
self
)
{
inline
void
launch
(
Actor
*
self
,
execution_unit
*
host
)
{
// detached in scheduler::worker::run
// detached in scheduler::worker::run
self
->
attach_to_scheduler
();
self
->
attach_to_scheduler
();
get_scheduling_coordinator
()
->
enqueue
(
self
);
if
(
host
)
host
->
exec_later
(
self
);
else
get_scheduling_coordinator
()
->
enqueue
(
self
);
}
}
template
<
class
Actor
>
template
<
class
Actor
>
...
...
cppa/policy/event_based_resume.hpp
View file @
4126af45
...
@@ -39,6 +39,7 @@
...
@@ -39,6 +39,7 @@
#include "cppa/config.hpp"
#include "cppa/config.hpp"
#include "cppa/extend.hpp"
#include "cppa/extend.hpp"
#include "cppa/logging.hpp"
#include "cppa/behavior.hpp"
#include "cppa/behavior.hpp"
#include "cppa/scheduler.hpp"
#include "cppa/scheduler.hpp"
#include "cppa/actor_state.hpp"
#include "cppa/actor_state.hpp"
...
@@ -74,13 +75,13 @@ class event_based_resume {
...
@@ -74,13 +75,13 @@ class event_based_resume {
resumable
::
resume_result
resume
(
detail
::
cs_thread
*
,
resumable
::
resume_result
resume
(
detail
::
cs_thread
*
,
execution_unit
*
host
)
override
{
execution_unit
*
host
)
override
{
CPPA_REQUIRE
(
host
!=
nullptr
);
auto
d
=
dptr
();
auto
d
=
dptr
();
d
->
m_host
=
host
;
d
->
m_host
=
host
;
CPPA_LOG_TRACE
(
"id = "
<<
d
->
id
()
CPPA_LOG_TRACE
(
"id = "
<<
d
->
id
()
<<
", state = "
<<
static_cast
<
int
>
(
d
->
state
()));
<<
", state = "
<<
static_cast
<
int
>
(
d
->
state
()));
CPPA_REQUIRE
(
d
->
state
()
==
actor_state
::
ready
CPPA_REQUIRE
(
d
->
state
()
==
actor_state
::
ready
||
d
->
state
()
==
actor_state
::
pending
);
||
d
->
state
()
==
actor_state
::
pending
);
CPPA_PUSH_AID
(
d
->
id
());
auto
done_cb
=
[
&
]()
->
bool
{
auto
done_cb
=
[
&
]()
->
bool
{
CPPA_LOG_TRACE
(
""
);
CPPA_LOG_TRACE
(
""
);
d
->
bhvr_stack
().
clear
();
d
->
bhvr_stack
().
clear
();
...
...
cppa/policy/no_scheduling.hpp
View file @
4126af45
...
@@ -105,7 +105,7 @@ class no_scheduling {
...
@@ -105,7 +105,7 @@ class no_scheduling {
}
}
template
<
class
Actor
>
template
<
class
Actor
>
void
launch
(
Actor
*
self
)
{
void
launch
(
Actor
*
self
,
execution_unit
*
)
{
CPPA_PUSH_AID
(
self
->
id
());
CPPA_PUSH_AID
(
self
->
id
());
CPPA_LOG_TRACE
(
CPPA_ARG
(
self
));
CPPA_LOG_TRACE
(
CPPA_ARG
(
self
));
CPPA_REQUIRE
(
self
!=
nullptr
);
CPPA_REQUIRE
(
self
!=
nullptr
);
...
...
cppa/spawn.hpp
View file @
4126af45
...
@@ -52,10 +52,14 @@
...
@@ -52,10 +52,14 @@
namespace
cppa
{
namespace
cppa
{
class
execution_unit
;
namespace
detail
{
namespace
detail
{
template
<
class
C
,
spawn_options
Os
,
typename
BeforeLaunch
,
typename
...
Ts
>
template
<
class
C
,
spawn_options
Os
,
typename
BeforeLaunch
,
typename
...
Ts
>
intrusive_ptr
<
C
>
spawn_impl
(
BeforeLaunch
before_launch_fun
,
Ts
&&
...
args
)
{
intrusive_ptr
<
C
>
spawn_impl
(
execution_unit
*
host
,
BeforeLaunch
before_launch_fun
,
Ts
&&
...
args
)
{
static_assert
(
!
std
::
is_base_of
<
blocking_actor
,
C
>::
value
||
static_assert
(
!
std
::
is_base_of
<
blocking_actor
,
C
>::
value
||
has_blocking_api_flag
(
Os
),
has_blocking_api_flag
(
Os
),
"C is derived type of blocking_actor but "
"C is derived type of blocking_actor but "
...
@@ -69,7 +73,7 @@ intrusive_ptr<C> spawn_impl(BeforeLaunch before_launch_fun, Ts&&... args) {
...
@@ -69,7 +73,7 @@ intrusive_ptr<C> spawn_impl(BeforeLaunch before_launch_fun, Ts&&... args) {
if
(
has_blocking_api_flag
(
Os
)
if
(
has_blocking_api_flag
(
Os
)
&&
!
has_detach_flag
(
Os
)
&&
!
has_detach_flag
(
Os
)
&&
detail
::
cs_thread
::
is_disabled_feature
)
{
&&
detail
::
cs_thread
::
is_disabled_feature
)
{
return
spawn_impl
<
C
,
Os
+
detached
>
(
before_launch_fun
,
return
spawn_impl
<
C
,
Os
+
detached
>
(
host
,
before_launch_fun
,
std
::
forward
<
Ts
>
(
args
)...);
std
::
forward
<
Ts
>
(
args
)...);
}
}
using
scheduling_policy
=
typename
std
::
conditional
<
using
scheduling_policy
=
typename
std
::
conditional
<
...
@@ -102,9 +106,10 @@ intrusive_ptr<C> spawn_impl(BeforeLaunch before_launch_fun, Ts&&... args) {
...
@@ -102,9 +106,10 @@ intrusive_ptr<C> spawn_impl(BeforeLaunch before_launch_fun, Ts&&... args) {
invoke_policy
>
;
invoke_policy
>
;
using
proper_impl
=
detail
::
proper_actor
<
C
,
policies
>
;
using
proper_impl
=
detail
::
proper_actor
<
C
,
policies
>
;
auto
ptr
=
make_counted
<
proper_impl
>
(
std
::
forward
<
Ts
>
(
args
)...);
auto
ptr
=
make_counted
<
proper_impl
>
(
std
::
forward
<
Ts
>
(
args
)...);
CPPA_LOGF_DEBUG
(
"spawned actor with ID "
<<
ptr
->
id
());
CPPA_PUSH_AID
(
ptr
->
id
());
CPPA_PUSH_AID
(
ptr
->
id
());
before_launch_fun
(
ptr
.
get
());
before_launch_fun
(
ptr
.
get
());
ptr
->
launch
(
has_hide_flag
(
Os
));
ptr
->
launch
(
has_hide_flag
(
Os
)
,
host
);
return
ptr
;
return
ptr
;
}
}
...
@@ -127,17 +132,51 @@ struct spawn_fwd<scoped_actor> {
...
@@ -127,17 +132,51 @@ struct spawn_fwd<scoped_actor> {
static
inline
actor
fwd
(
T
&
arg
)
{
return
arg
;
}
static
inline
actor
fwd
(
T
&
arg
)
{
return
arg
;
}
};
};
}
// namespace detail
// forwards the arguments to spawn_impl, replacing pointers
// forwards the arguments to spawn_impl, replacing pointers
// to actors with instances of 'actor'
// to actors with instances of 'actor'
template
<
class
C
,
spawn_options
Os
,
typename
BeforeLaunch
,
typename
...
Ts
>
template
<
class
C
,
spawn_options
Os
,
typename
BeforeLaunch
,
typename
...
Ts
>
intrusive_ptr
<
C
>
spawn_fwd_args
(
BeforeLaunch
before_launch_fun
,
Ts
&&
...
args
)
{
intrusive_ptr
<
C
>
spawn_class
(
execution_unit
*
host
,
return
spawn_impl
<
C
,
Os
>
(
BeforeLaunch
before_launch_fun
,
Ts
&&
...
args
)
{
return
detail
::
spawn_impl
<
C
,
Os
>
(
host
,
before_launch_fun
,
before_launch_fun
,
spawn_fwd
<
typename
util
::
rm_const_and_ref
<
Ts
>::
type
>::
fwd
(
detail
::
spawn_fwd
<
typename
util
::
rm_const_and_ref
<
Ts
>::
type
>::
fwd
(
std
::
forward
<
Ts
>
(
args
))...);
std
::
forward
<
Ts
>
(
args
))...);
}
}
}
// namespace detail
template
<
spawn_options
Os
,
typename
BeforeLaunch
,
typename
F
,
typename
...
Ts
>
actor
spawn_functor
(
execution_unit
*
eu
,
BeforeLaunch
cb
,
F
fun
,
Ts
&&
...
args
)
{
typedef
typename
util
::
get_callable_trait
<
F
>::
type
trait
;
typedef
typename
trait
::
arg_types
arg_types
;
typedef
typename
util
::
tl_head
<
arg_types
>::
type
first_arg
;
constexpr
bool
is_blocking
=
has_blocking_api_flag
(
Os
);
constexpr
bool
has_ptr_arg
=
std
::
is_pointer
<
first_arg
>::
value
;
constexpr
bool
has_blocking_self
=
std
::
is_same
<
first_arg
,
blocking_actor
*
>::
value
;
constexpr
bool
has_nonblocking_self
=
std
::
is_same
<
first_arg
,
event_based_actor
*
>::
value
;
static_assert
(
!
is_blocking
||
has_blocking_self
||
!
has_ptr_arg
,
"functor-based actors with blocking_actor* as first "
"argument need to be spawned using the blocking_api flag"
);
static_assert
(
is_blocking
||
has_nonblocking_self
||
!
has_ptr_arg
,
"functor-based actors with event_based_actor* as first "
"argument cannot be spawned using the blocking_api flag"
);
using
base_class
=
typename
std
::
conditional
<
is_blocking
,
detail
::
functor_based_blocking_actor
,
detail
::
functor_based_actor
>::
type
;
return
spawn_class
<
base_class
,
Os
>
(
eu
,
cb
,
fun
,
std
::
forward
<
Ts
>
(
args
)...);
}
/**
/**
* @ingroup ActorCreation
* @ingroup ActorCreation
...
@@ -151,10 +190,9 @@ intrusive_ptr<C> spawn_fwd_args(BeforeLaunch before_launch_fun, Ts&&... args) {
...
@@ -151,10 +190,9 @@ intrusive_ptr<C> spawn_fwd_args(BeforeLaunch before_launch_fun, Ts&&... args) {
* @tparam Os Optional flags to modify <tt>spawn</tt>'s behavior.
* @tparam Os Optional flags to modify <tt>spawn</tt>'s behavior.
* @returns An {@link actor} to the spawned {@link actor}.
* @returns An {@link actor} to the spawned {@link actor}.
*/
*/
template
<
class
C
,
spawn_options
O
s
,
typename
...
Ts
>
template
<
class
Impl
,
spawn_options
Os
=
no_spawn_option
s
,
typename
...
Ts
>
actor
spawn
(
Ts
&&
...
args
)
{
actor
spawn
(
Ts
&&
...
args
)
{
return
detail
::
spawn_fwd_args
<
C
,
Os
>
(
return
spawn_class
<
Impl
,
Os
>
(
nullptr
,
empty_before_launch_callback
{},
[](
C
*
)
{
/* no-op as BeforeLaunch callback */
},
std
::
forward
<
Ts
>
(
args
)...);
std
::
forward
<
Ts
>
(
args
)...);
}
}
...
@@ -164,51 +202,39 @@ actor spawn(Ts&&... args) {
...
@@ -164,51 +202,39 @@ actor spawn(Ts&&... args) {
* @tparam Os Optional flags to modify <tt>spawn</tt>'s behavior.
* @tparam Os Optional flags to modify <tt>spawn</tt>'s behavior.
* @returns An {@link actor} to the spawned {@link actor}.
* @returns An {@link actor} to the spawned {@link actor}.
*/
*/
//template<spawn_options Os = no_spawn_options, typename... Ts>
template
<
spawn_options
Os
=
no_spawn_options
,
typename
...
Ts
>
template
<
spawn_options
Os
,
typename
...
Ts
>
actor
spawn
(
Ts
&&
...
args
)
{
actor
spawn
(
Ts
&&
...
args
)
{
static_assert
(
sizeof
...(
Ts
)
>
0
,
"too few arguments provided"
);
static_assert
(
sizeof
...(
Ts
)
>
0
,
"too few arguments provided"
);
using
base_class
=
typename
std
::
conditional
<
return
spawn_functor
<
Os
>
(
nullptr
,
empty_before_launch_callback
{},
has_blocking_api_flag
(
Os
),
std
::
forward
<
Ts
>
(
args
)...);
detail
::
functor_based_blocking_actor
,
detail
::
functor_based_actor
>::
type
;
return
spawn
<
base_class
,
Os
>
(
std
::
forward
<
Ts
>
(
args
)...);
}
}
/**
/**
* @brief Spawns a
new actor that evaluates given arguments and
* @brief Spawns a
n actor of type @p C that immediately joins @p grp.
*
immediately joins @p grp
.
*
@param args Constructor arguments
.
* @
param args A functor followed by its arguments
.
* @
tparam C Subtype of {@link event_based_actor} or {@link sb_actor}
.
* @tparam Os Optional flags to modify <tt>spawn</tt>'s behavior.
* @tparam Os Optional flags to modify <tt>spawn</tt>'s behavior.
* @returns An {@link actor} to the spawned {@link actor}.
* @returns An {@link actor} to the spawned {@link actor}.
* @note The spawned has joined the group before this function returns.
* @note The spawned has joined the group before this function returns.
*/
*/
template
<
spawn_options
O
s
,
typename
...
Ts
>
template
<
class
Impl
,
spawn_options
Os
=
no_spawn_option
s
,
typename
...
Ts
>
actor
spawn_in_group
(
const
group
&
grp
,
Ts
&&
...
args
)
{
actor
spawn_in_group
(
const
group
&
grp
,
Ts
&&
...
args
)
{
static_assert
(
sizeof
...(
Ts
)
>
0
,
"too few arguments provided"
);
return
spawn_class
<
Impl
,
Os
>
(
nullptr
,
group_subscriber
{
grp
},
using
base_class
=
typename
std
::
conditional
<
has_blocking_api_flag
(
Os
),
detail
::
functor_based_blocking_actor
,
detail
::
functor_based_actor
>::
type
;
return
detail
::
spawn_fwd_args
<
base_class
,
Os
>
(
[
&
](
base_class
*
ptr
)
{
ptr
->
join
(
grp
);
},
std
::
forward
<
Ts
>
(
args
)...);
std
::
forward
<
Ts
>
(
args
)...);
}
}
/**
/**
* @brief Spawns a
n actor of type @p C that immediately joins @p grp.
* @brief Spawns a
new actor that evaluates given arguments and
*
@param args Constructor arguments
.
*
immediately joins @p grp
.
* @
tparam C Subtype of {@link event_based_actor} or {@link sb_actor}
.
* @
param args A functor followed by its arguments
.
* @tparam Os Optional flags to modify <tt>spawn</tt>'s behavior.
* @tparam Os Optional flags to modify <tt>spawn</tt>'s behavior.
* @returns An {@link actor} to the spawned {@link actor}.
* @returns An {@link actor} to the spawned {@link actor}.
* @note The spawned has joined the group before this function returns.
* @note The spawned has joined the group before this function returns.
*/
*/
template
<
class
C
,
spawn_options
O
s
,
typename
...
Ts
>
template
<
spawn_options
Os
=
no_spawn_option
s
,
typename
...
Ts
>
actor
spawn_in_group
(
const
group
&
grp
,
Ts
&&
...
args
)
{
actor
spawn_in_group
(
const
group
&
grp
,
Ts
&&
...
args
)
{
return
detail
::
spawn_fwd_args
<
C
,
Os
>
(
static_assert
(
sizeof
...(
Ts
)
>
0
,
"too few arguments provided"
);
[
&
](
C
*
ptr
)
{
ptr
->
join
(
grp
);
},
return
spawn_functor
<
Os
>
(
nullptr
,
group_subscriber
{
grp
},
std
::
forward
<
Ts
>
(
args
)...);
std
::
forward
<
Ts
>
(
args
)...);
}
}
...
@@ -318,30 +344,23 @@ struct infer_typed_actor_base<void, typed_event_based_actor<Rs...>*> {
...
@@ -318,30 +344,23 @@ struct infer_typed_actor_base<void, typed_event_based_actor<Rs...>*> {
* @tparam Os Optional flags to modify <tt>spawn</tt>'s behavior.
* @tparam Os Optional flags to modify <tt>spawn</tt>'s behavior.
* @returns A {@link typed_actor} handle to the spawned actor.
* @returns A {@link typed_actor} handle to the spawned actor.
*/
*/
template
<
class
C
,
spawn_options
Os
,
typename
...
Ts
>
template
<
class
C
,
spawn_options
Os
=
no_spawn_options
,
typename
...
Ts
>
typename
detail
::
actor_handle_from_signature_list
<
typename
detail
::
actor_handle_from_signature_list
<
typename
C
::
signatures
typename
C
::
signatures
>::
type
>::
type
spawn_typed
(
Ts
&&
...
args
)
{
spawn_typed
(
Ts
&&
...
args
)
{
return
detail
::
spawn_fwd_args
<
C
,
Os
>
(
return
spawn_class
<
C
,
Os
>
(
nullptr
,
empty_before_launch_callback
{},
[
&
](
C
*
)
{
},
std
::
forward
<
Ts
>
(
args
)...);
std
::
forward
<
Ts
>
(
args
)...);
}
}
/**
template
<
spawn_options
Os
,
typename
BeforeLaunch
,
typename
F
,
typename
...
Ts
>
* @brief Spawns a typed actor from a functor.
* @param args A functor followed by its arguments.
* @tparam Os Optional flags to modify <tt>spawn</tt>'s behavior.
* @returns An {@link actor} to the spawned {@link actor}.
*/
template
<
spawn_options
Os
,
typename
F
,
typename
...
Ts
>
typename
detail
::
infer_typed_actor_handle
<
typename
detail
::
infer_typed_actor_handle
<
typename
util
::
get_callable_trait
<
F
>::
result_type
,
typename
util
::
get_callable_trait
<
F
>::
result_type
,
typename
util
::
tl_head
<
typename
util
::
tl_head
<
typename
util
::
get_callable_trait
<
F
>::
arg_types
typename
util
::
get_callable_trait
<
F
>::
arg_types
>::
type
>::
type
>::
type
>::
type
spawn_typed
(
F
fun
,
Ts
&&
...
args
)
{
spawn_typed
_functor
(
execution_unit
*
eu
,
BeforeLaunch
bl
,
F
fun
,
Ts
&&
...
args
)
{
typedef
typename
detail
::
infer_typed_actor_base
<
typedef
typename
detail
::
infer_typed_actor_base
<
typename
util
::
get_callable_trait
<
F
>::
result_type
,
typename
util
::
get_callable_trait
<
F
>::
result_type
,
typename
util
::
tl_head
<
typename
util
::
tl_head
<
...
@@ -349,8 +368,24 @@ spawn_typed(F fun, Ts&&... args) {
...
@@ -349,8 +368,24 @@ spawn_typed(F fun, Ts&&... args) {
>::
type
>::
type
>::
type
>::
type
impl
;
impl
;
return
detail
::
spawn_fwd_args
<
impl
,
Os
>
(
return
spawn_class
<
impl
,
Os
>
(
eu
,
bl
,
fun
,
std
::
forward
<
Ts
>
(
args
)...);
[
&
](
impl
*
)
{
},
}
/**
* @brief Spawns a typed actor from a functor.
* @param args A functor followed by its arguments.
* @tparam Os Optional flags to modify <tt>spawn</tt>'s behavior.
* @returns An {@link actor} to the spawned {@link actor}.
*/
template
<
spawn_options
Os
=
no_spawn_options
,
typename
F
,
typename
...
Ts
>
typename
detail
::
infer_typed_actor_handle
<
typename
util
::
get_callable_trait
<
F
>::
result_type
,
typename
util
::
tl_head
<
typename
util
::
get_callable_trait
<
F
>::
arg_types
>::
type
>::
type
spawn_typed
(
F
fun
,
Ts
&&
...
args
)
{
return
spawn_typed_functor
<
Os
>
(
nullptr
,
empty_before_launch_callback
{},
std
::
move
(
fun
),
std
::
forward
<
Ts
>
(
args
)...);
std
::
move
(
fun
),
std
::
forward
<
Ts
>
(
args
)...);
}
}
...
...
cppa/spawn_fwd.hpp
View file @
4126af45
...
@@ -34,6 +34,7 @@
...
@@ -34,6 +34,7 @@
#ifndef CPPA_SPAWN_FWD_HPP
#ifndef CPPA_SPAWN_FWD_HPP
#define CPPA_SPAWN_FWD_HPP
#define CPPA_SPAWN_FWD_HPP
#include "cppa/group.hpp"
#include "cppa/typed_actor.hpp"
#include "cppa/typed_actor.hpp"
#include "cppa/spawn_options.hpp"
#include "cppa/spawn_options.hpp"
...
@@ -41,21 +42,42 @@
...
@@ -41,21 +42,42 @@
namespace
cppa
{
namespace
cppa
{
/******************************************************************************
template
<
class
C
,
spawn_options
Os
,
typename
BeforeLaunch
,
typename
...
Ts
>
* untyped actors *
intrusive_ptr
<
C
>
spawn_class
(
execution_unit
*
host
,
******************************************************************************/
BeforeLaunch
before_launch_fun
,
Ts
&&
...
args
);
template
<
spawn_options
Os
,
typename
BeforeLaunch
,
typename
F
,
typename
...
Ts
>
actor
spawn_functor
(
execution_unit
*
host
,
BeforeLaunch
before_launch_fun
,
F
fun
,
Ts
&&
...
args
);
class
group_subscriber
{
public:
inline
group_subscriber
(
const
group
&
grp
)
:
m_grp
(
grp
)
{
}
template
<
typename
T
>
inline
void
operator
()(
T
*
ptr
)
const
{
ptr
->
join
(
m_grp
);
}
template
<
class
Impl
,
spawn_options
Os
=
no_spawn_options
,
typename
...
Ts
>
private:
actor
spawn
(
Ts
&&
...
args
);
template
<
spawn_options
Os
=
no_spawn_options
,
typename
...
Ts
>
group
m_grp
;
actor
spawn
(
Ts
&&
...
args
);
template
<
class
Impl
,
spawn_options
Os
=
no_spawn_options
,
typename
...
Ts
>
};
actor
spawn_in_group
(
const
group
&
,
Ts
&&
...
args
);
class
empty_before_launch_callback
{
template
<
spawn_options
Os
=
no_spawn_options
,
typename
...
Ts
>
public:
actor
spawn_in_group
(
const
group
&
,
Ts
&&
...
args
);
template
<
typename
T
>
inline
void
operator
()(
T
*
)
const
{
}
};
/******************************************************************************
/******************************************************************************
* typed actors *
* typed actors *
...
@@ -88,20 +110,14 @@ struct actor_handle_from_signature_list<util::type_list<Rs...>> {
...
@@ -88,20 +110,14 @@ struct actor_handle_from_signature_list<util::type_list<Rs...>> {
}
// namespace detail
}
// namespace detail
template
<
class
Impl
,
spawn_options
Os
=
no_spawn_options
,
typename
...
Ts
>
template
<
spawn_options
Os
,
typename
BeforeLaunch
,
typename
F
,
typename
...
Ts
>
typename
detail
::
actor_handle_from_signature_list
<
typename
Impl
::
signatures
>::
type
spawn_typed
(
Ts
&&
...
args
);
template
<
spawn_options
Os
=
no_spawn_options
,
typename
F
,
typename
...
Ts
>
typename
detail
::
infer_typed_actor_handle
<
typename
detail
::
infer_typed_actor_handle
<
typename
util
::
get_callable_trait
<
F
>::
result_type
,
typename
util
::
get_callable_trait
<
F
>::
result_type
,
typename
util
::
tl_head
<
typename
util
::
tl_head
<
typename
util
::
get_callable_trait
<
F
>::
arg_types
typename
util
::
get_callable_trait
<
F
>::
arg_types
>::
type
>::
type
>::
type
>::
type
spawn_typed
(
F
fun
,
Ts
&&
...
args
);
spawn_typed
_functor
(
execution_unit
*
,
BeforeLaunch
bl
,
F
fun
,
Ts
&&
...
args
);
}
// namespace cppa
}
// namespace cppa
...
...
src/logging.cpp
View file @
4126af45
...
@@ -104,12 +104,6 @@ class logging_impl : public logging {
...
@@ -104,12 +104,6 @@ class logging_impl : public logging {
}
}
}
}
actor_id
set_aid
(
actor_id
aid
)
override
{
actor_id
prev
=
t_self_id
;
t_self_id
=
aid
;
return
prev
;
}
void
log
(
const
char
*
level
,
void
log
(
const
char
*
level
,
const
char
*
c_class_name
,
const
char
*
c_class_name
,
const
char
*
function_name
,
const
char
*
function_name
,
...
@@ -170,4 +164,10 @@ logging::~logging() { }
...
@@ -170,4 +164,10 @@ logging::~logging() { }
logging
*
logging
::
create_singleton
()
{
return
new
logging_impl
;
}
logging
*
logging
::
create_singleton
()
{
return
new
logging_impl
;
}
actor_id
logging
::
set_aid
(
actor_id
aid
)
{
actor_id
prev
=
t_self_id
;
t_self_id
=
aid
;
return
prev
;
}
}
// namespace cppa
}
// namespace cppa
src/scheduler.cpp
View file @
4126af45
...
@@ -242,6 +242,7 @@ class coordinator::shutdown_helper : public resumable {
...
@@ -242,6 +242,7 @@ class coordinator::shutdown_helper : public resumable {
resumable
::
resume_result
resume
(
detail
::
cs_thread
*
,
execution_unit
*
ptr
)
{
resumable
::
resume_result
resume
(
detail
::
cs_thread
*
,
execution_unit
*
ptr
)
{
auto
w
=
dynamic_cast
<
worker
*>
(
ptr
);
auto
w
=
dynamic_cast
<
worker
*>
(
ptr
);
CPPA_REQUIRE
(
w
!=
nullptr
);
CPPA_REQUIRE
(
w
!=
nullptr
);
CPPA_LOG_DEBUG
(
"shutdown_helper::resume => shutdown worker"
);
w
->
m_running
=
false
;
w
->
m_running
=
false
;
std
::
unique_lock
<
std
::
mutex
>
guard
(
mtx
);
std
::
unique_lock
<
std
::
mutex
>
guard
(
mtx
);
last_worker
=
w
;
last_worker
=
w
;
...
@@ -328,7 +329,7 @@ void coordinator::enqueue(resumable* what) {
...
@@ -328,7 +329,7 @@ void coordinator::enqueue(resumable* what) {
******************************************************************************/
******************************************************************************/
worker
::
worker
(
size_t
id
,
coordinator
*
parent
)
worker
::
worker
(
size_t
id
,
coordinator
*
parent
)
:
m_running
(
fals
e
),
m_id
(
id
),
m_last_victim
(
id
),
m_parent
(
parent
)
{
}
:
m_running
(
tru
e
),
m_id
(
id
),
m_last_victim
(
id
),
m_parent
(
parent
)
{
}
void
worker
::
start
()
{
void
worker
::
start
()
{
...
@@ -389,15 +390,20 @@ void worker::run() {
...
@@ -389,15 +390,20 @@ void worker::run() {
}
}
};
};
// scheduling loop
// scheduling loop
m_running
=
true
;
while
(
m_running
)
{
while
(
m_running
)
{
local_poll
()
||
aggressive_poll
()
||
moderate_poll
()
||
relaxed_poll
();
local_poll
()
||
aggressive_poll
()
||
moderate_poll
()
||
relaxed_poll
();
CPPA_LOG_DEBUG
(
"dequeued new job"
);
CPPA_LOG_DEBUG
(
"dequeued new job"
);
CPPA_PUSH_AID_FROM_PTR
(
dynamic_cast
<
abstract_actor
*>
(
job
));
if
(
job
->
resume
(
&
fself
,
this
)
==
resumable
::
done
)
{
if
(
job
->
resume
(
&
fself
,
this
)
==
resumable
::
done
)
{
// was attached in policy::cooperative_scheduling::launch
// was attached in policy::cooperative_scheduling::launch
job
->
detach_from_scheduler
();
job
->
detach_from_scheduler
();
}
}
job
=
nullptr
;
job
=
nullptr
;
// give others the opportunity to steal from us
if
(
m_job_list
.
size
()
>
1
&&
m_exposed_queue
.
empty
())
{
m_exposed_queue
.
push_back
(
m_job_list
.
front
());
m_job_list
.
erase
(
m_job_list
.
begin
());
}
}
}
}
}
...
@@ -412,7 +418,12 @@ worker::job_ptr worker::raid() {
...
@@ -412,7 +418,12 @@ worker::job_ptr worker::raid() {
m_last_victim
=
(
m_last_victim
+
1
)
%
n
;
m_last_victim
=
(
m_last_victim
+
1
)
%
n
;
if
(
m_last_victim
!=
m_id
)
{
if
(
m_last_victim
!=
m_id
)
{
auto
job
=
m_parent
->
worker_by_id
(
m_last_victim
)
->
try_steal
();
auto
job
=
m_parent
->
worker_by_id
(
m_last_victim
)
->
try_steal
();
if
(
job
)
return
job
;
if
(
job
)
{
CPPA_LOG_DEBUG
(
"worker "
<<
m_id
<<
" has successfully stolen a job from "
<<
m_last_victim
);
return
job
;
}
}
}
}
}
return
nullptr
;
return
nullptr
;
...
...
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