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
d90fc078
Commit
d90fc078
authored
Jun 25, 2012
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
event-based actor factory
parent
85a4fc8d
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
393 additions
and
200 deletions
+393
-200
CMakeLists.txt
CMakeLists.txt
+1
-0
cppa.files
cppa.files
+3
-0
cppa/cppa.hpp
cppa/cppa.hpp
+37
-42
cppa/detail/event_based_actor_factory.hpp
cppa/detail/event_based_actor_factory.hpp
+142
-0
cppa/detail/scheduled_actor_dummy.hpp
cppa/detail/scheduled_actor_dummy.hpp
+1
-0
cppa/detail/stacked_actor_mixin.hpp
cppa/detail/stacked_actor_mixin.hpp
+6
-0
cppa/detail/thread_pool_scheduler.hpp
cppa/detail/thread_pool_scheduler.hpp
+1
-2
cppa/event_based_actor.hpp
cppa/event_based_actor.hpp
+4
-0
cppa/exit_reason.hpp
cppa/exit_reason.hpp
+0
-5
cppa/factory.hpp
cppa/factory.hpp
+91
-0
cppa/guard_expr.hpp
cppa/guard_expr.hpp
+12
-2
cppa/scheduled_actor.hpp
cppa/scheduled_actor.hpp
+4
-0
src/factory.cpp
src/factory.cpp
+37
-0
src/scheduled_actor_dummy.cpp
src/scheduled_actor_dummy.cpp
+1
-1
src/thread_pool_scheduler.cpp
src/thread_pool_scheduler.cpp
+19
-13
unit_testing/test__spawn.cpp
unit_testing/test__spawn.cpp
+34
-135
No files found.
CMakeLists.txt
View file @
d90fc078
...
...
@@ -27,6 +27,7 @@ set(LIBCPPA_SRC
src/empty_tuple.cpp
src/event_based_actor.cpp
src/exception.cpp
src/factory.cpp
src/fiber.cpp
src/group.cpp
src/group_manager.cpp
...
...
cppa.files
View file @
d90fc078
...
...
@@ -262,3 +262,6 @@ cppa/detail/receive_policy.hpp
cppa/detail/behavior_stack.hpp
src/behavior_stack.cpp
cppa/detail/stacked_actor_mixin.hpp
cppa/detail/event_based_actor_factory.hpp
cppa/factory.hpp
src/factory.cpp
cppa/cppa.hpp
View file @
d90fc078
...
...
@@ -40,18 +40,19 @@
#include "cppa/on.hpp"
#include "cppa/atom.hpp"
#include "cppa/self.hpp"
#include "cppa/cow_tuple.hpp"
#include "cppa/actor.hpp"
#include "cppa/channel.hpp"
#include "cppa/receive.hpp"
#include "cppa/factory.hpp"
#include "cppa/behavior.hpp"
#include "cppa/announce.hpp"
#include "cppa/scheduler.hpp"
#include "cppa/to_string.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/fsm_actor.hpp"
#include "cppa/
local_actor
.hpp"
#include "cppa/
cow_tuple
.hpp"
#include "cppa/exit_reason.hpp"
#include "cppa/local_actor.hpp"
#include "cppa/scheduled_actor.hpp"
#include "cppa/scheduling_hint.hpp"
#include "cppa/event_based_actor.hpp"
...
...
@@ -123,17 +124,24 @@
* features.
*
* @namespace cppa
* @brief This is the root namespace of libcppa.
*
* Thie @b cppa namespace contains all functions and classes to
* implement Actor based applications.
* @brief Root namespace of libcppa.
*
* @namespace cppa::util
* @brief
This namespace c
ontains utility classes and metaprogramming
* @brief
C
ontains utility classes and metaprogramming
* utilities used by the libcppa implementation.
*
* @namespace cppa::intrusive
* @brief This namespace contains intrusive container implementations.
* @brief Contains intrusive container implementations.
*
* @namespace cppa::factory
* @brief Contains factory functions to create actors from lambdas or
* other functors.
*
* @namespace cppa::exit_reason
* @brief Contains all predefined exit reasons.
*
* @namespace cppa::placeholders
* @brief Contains the guard placeholders @p _x1 to @p _x9.
*
* @defgroup CopyOnWrite Copy-on-write optimization.
* @p libcppa uses a copy-on-write optimization for its message
...
...
@@ -246,16 +254,13 @@
* to define patterns:
*
* @code
* receive
* (
* on(atom("hello"), val<std::string>()) >> [](const std::string& msg)
* {
* receive (
* on(atom("hello"), val<std::string>()) >> [](const std::string& msg) {
* cout << "received hello message: " << msg << endl;
* },
* on(atom("compute"), val<int>(), val<int>(), val<int>()>() >> [](int i0, int i1, int i2)
* {
* on(atom("compute"), val<int>(), val<int>()>() >> [](int i0, int i1) {
* // send our result back to the sender of this messages
* reply(atom("result"), i0 + i1
+ i2
);
* reply(atom("result"), i0 + i1);
* }
* );
* @endcode
...
...
@@ -270,16 +275,12 @@
*
* Example actor:
* @code
* void math_actor()
* {
* receive_loop
* (
* on<atom("plus"), int, int>() >> [](int a, int b)
* {
* void math_actor() {
* receive_loop (
* on<atom("plus"), int, int>() >> [](int a, int b) {
* reply(atom("result"), a + b);
* },
* on<atom("minus"), int, int>() >> [](int a, int b)
* {
* on<atom("minus"), int, int>() >> [](int a, int b) {
* reply(atom("result"), a - b);
* }
* );
...
...
@@ -307,10 +308,8 @@
* @code
* // receive two integers
* vector<int> received_values;
* receive_while([&]() { return received_values.size() < 2; })
* (
* on<int>() >> [](int value)
* {
* receive_while([&]() { return received_values.size() < 2; }) (
* on<int>() >> [](int value) {
* received_values.push_back(value);
* }
* );
...
...
@@ -322,8 +321,7 @@
* @code
* std::vector<int> vec {1, 2, 3, 4};
* auto i = vec.begin();
* receive_for(i, vec.end())
* (
* receive_for(i, vec.end()) (
* on(atom("get")) >> [&]() { reply(atom("result"), *i); }
* );
* @endcode
...
...
@@ -335,10 +333,8 @@
* @code
* // receive ints until zero was received
* vector<int> received_values;
* do_receive
* (
* on<int>() >> [](int value)
* {
* do_receive (
* on<int>() >> [](int value) {
* received_values.push_back(value);
* }
* )
...
...
@@ -354,11 +350,9 @@
*
* @code
* delayed_send(self, std::chrono::seconds(1), atom("poll"));
* receive_loop
* (
* receive_loop (
* // ...
* on<atom("poll")>() >> []()
* {
* on<atom("poll")>() >> []() {
* // ... poll something ...
* // and do it again after 1sec
* delayed_send(self, std::chrono::seconds(1), atom("poll"));
...
...
@@ -392,8 +386,7 @@
* // x has the type cppa::tuple<std::string, std::string>
* auto x = make_cow_tuple("hello", "tuple");
*
* receive
* (
* receive (
* // equal to: on(std::string("hello actor!"))
* on("hello actor!") >> []() { }
* );
...
...
@@ -486,9 +479,11 @@ struct spawn_fwd_<self_type> {
*/
template
<
scheduling_hint
Hint
,
typename
F
,
typename
Arg0
,
typename
...
Args
>
inline
actor_ptr
spawn
(
F
bhvr
,
Arg0
&&
arg0
,
Args
&&
...
args
)
{
return
spawn
<
Hint
>
(
std
::
bind
(
std
::
move
(
bhvr
),
spawn_fwd_
<
typename
util
::
rm_ref
<
Arg0
>::
type
>::
_
(
arg0
),
spawn_fwd_
<
typename
util
::
rm_ref
<
Args
>::
type
>::
_
(
args
)...));
return
spawn
<
Hint
>
(
std
::
bind
(
std
::
move
(
bhvr
),
spawn_fwd_
<
typename
util
::
rm_ref
<
Arg0
>::
type
>::
_
(
arg0
),
spawn_fwd_
<
typename
util
::
rm_ref
<
Args
>::
type
>::
_
(
args
)...));
}
/**
...
...
cppa/detail/event_based_actor_factory.hpp
0 → 100644
View file @
d90fc078
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011, 2012 *
* Dominik Charousset <dominik.charousset@haw-hamburg.de> *
* *
* This file is part of libcppa. *
* libcppa is free software: you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation, either version 3 of the License *
* or (at your option) any later version. *
* *
* libcppa is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
\******************************************************************************/
#ifndef CPPA_EVENT_BASED_ACTOR_FACTORY_HPP
#define CPPA_EVENT_BASED_ACTOR_FACTORY_HPP
#include <type_traits>
#include "cppa/scheduler.hpp"
#include "cppa/event_based_actor.hpp"
#include "cppa/detail/tdata.hpp"
#include "cppa/util/type_list.hpp"
namespace
cppa
{
namespace
detail
{
template
<
typename
InitFun
,
typename
CleanupFun
,
typename
...
Members
>
class
event_based_actor_impl
:
public
event_based_actor
{
public:
template
<
typename
...
Args
>
event_based_actor_impl
(
InitFun
fun
,
CleanupFun
cfun
,
Args
&&
...
args
)
:
m_init
(
std
::
move
(
fun
)),
m_on_exit
(
std
::
move
(
cfun
))
,
m_members
(
std
::
forward
<
Args
>
(
args
)...)
{
}
void
init
()
{
apply
(
m_init
);
}
void
on_exit
()
{
typedef
typename
util
::
get_arg_types
<
CleanupFun
>::
types
arg_types
;
std
::
integral_constant
<
size_t
,
arg_types
::
size
>
token
;
on_exit_impl
(
m_on_exit
,
token
);
}
private:
InitFun
m_init
;
CleanupFun
m_on_exit
;
tdata
<
Members
...
>
m_members
;
template
<
typename
F
>
void
apply
(
F
&
f
,
typename
std
::
add_pointer
<
Members
>::
type
...
args
)
{
f
(
args
...);
}
template
<
typename
F
,
typename
...
Args
>
void
apply
(
F
&
f
,
Args
...
args
)
{
apply
(
f
,
args
...,
&
get_ref
<
sizeof
...(
Args
)
>
(
m_members
));
}
typedef
std
::
integral_constant
<
size_t
,
0
>
zero_t
;
template
<
typename
OnExit
,
typename
Token
>
typename
std
::
enable_if
<
std
::
is_same
<
Token
,
zero_t
>::
value
>::
type
on_exit_impl
(
OnExit
&
fun
,
Token
)
{
fun
();
}
template
<
typename
OnExit
,
typename
Token
>
typename
std
::
enable_if
<
std
::
is_same
<
Token
,
zero_t
>::
value
==
false
>::
type
on_exit_impl
(
OnExit
&
fun
,
Token
)
{
apply
(
fun
);
}
};
template
<
typename
InitFun
,
typename
CleanupFun
,
typename
...
Members
>
class
event_based_actor_factory
{
public:
typedef
event_based_actor_impl
<
InitFun
,
CleanupFun
,
Members
...
>
impl
;
event_based_actor_factory
(
InitFun
fun
,
CleanupFun
cfun
)
:
m_init
(
std
::
move
(
fun
)),
m_on_exit
(
std
::
move
(
cfun
))
{
}
template
<
typename
...
Args
>
actor_ptr
spawn
(
Args
&&
...
args
)
{
return
get_scheduler
()
->
spawn
(
new
impl
(
m_init
,
m_on_exit
,
std
::
forward
<
Args
>
(
args
)...));
}
private:
InitFun
m_init
;
CleanupFun
m_on_exit
;
};
// event-based actor factory from type list
template
<
typename
InitFun
,
typename
CleanupFun
,
class
TypeList
>
struct
ebaf_from_type_list
;
template
<
typename
InitFun
,
typename
CleanupFun
,
typename
...
Ts
>
struct
ebaf_from_type_list
<
InitFun
,
CleanupFun
,
util
::
type_list
<
Ts
...
>
>
{
typedef
event_based_actor_factory
<
InitFun
,
CleanupFun
,
Ts
...
>
type
;
};
template
<
typename
Init
,
typename
Cleanup
>
struct
ebaf_from_functor
{
typedef
typename
util
::
get_arg_types
<
Init
>::
types
arg_types
;
typedef
typename
util
::
get_arg_types
<
Cleanup
>::
types
arg_types2
;
static_assert
(
util
::
tl_forall
<
arg_types
,
std
::
is_pointer
>::
value
,
"First functor takes non-pointer arguments"
);
static_assert
(
std
::
is_same
<
arg_types
,
arg_types2
>::
value
||
std
::
is_same
<
util
::
type_list
<>
,
arg_types2
>::
value
,
"Second functor must provide either the same signature "
" as the first one or must take zero arguments"
);
typedef
typename
util
::
tl_map
<
arg_types
,
std
::
remove_pointer
>::
type
mems
;
typedef
typename
ebaf_from_type_list
<
Init
,
Cleanup
,
mems
>::
type
type
;
};
}
}
// namespace cppa::detail
#endif // CPPA_EVENT_BASED_ACTOR_FACTORY_HPP
cppa/detail/scheduled_actor_dummy.hpp
View file @
d90fc078
...
...
@@ -48,6 +48,7 @@ struct scheduled_actor_dummy : abstract_scheduled_actor {
bool
attach
(
attachable
*
);
void
unbecome
();
void
do_become
(
behavior
*
,
bool
,
bool
);
bool
has_behavior
();
};
}
}
// namespace cppa::detail
...
...
cppa/detail/stacked_actor_mixin.hpp
View file @
d90fc078
...
...
@@ -92,6 +92,12 @@ class stacked_actor_mixin : public Base {
}
}
virtual
bool
has_behavior
()
{
return
static_cast
<
bool
>
(
m_behavior
)
||
(
static_cast
<
bool
>
(
m_bhvr_stack_ptr
)
&&
m_bhvr_stack_ptr
->
empty
()
==
false
);
}
private:
std
::
function
<
void
()
>
m_behavior
;
...
...
cppa/detail/thread_pool_scheduler.hpp
View file @
d90fc078
...
...
@@ -67,8 +67,7 @@ class thread_pool_scheduler : public scheduler {
scheduled_actor_dummy
m_dummy
;
std
::
thread
m_supervisor
;
actor_ptr
spawn_impl
(
scheduled_actor
*
what
,
bool
push_to_queue
=
true
);
actor_ptr
spawn_impl
(
scheduled_actor_ptr
what
,
bool
push_to_queue
=
true
);
static
void
worker_loop
(
worker
*
);
static
void
supervisor_loop
(
job_queue
*
,
scheduled_actor
*
);
...
...
cppa/event_based_actor.hpp
View file @
d90fc078
...
...
@@ -86,6 +86,10 @@ class event_based_actor : public detail::abstract_scheduled_actor {
event_based_actor
();
bool
has_behavior
()
{
return
m_bhvr_stack
.
empty
()
==
false
;
}
// provoke compiler errors for usage of receive() and related functions
/**
...
...
cppa/exit_reason.hpp
View file @
d90fc078
...
...
@@ -33,11 +33,6 @@
#include <cstdint>
/**
* @namespace cppa::exit_reason
* @brief This naemspace contains all predefined exit reasons.
*/
namespace
cppa
{
namespace
exit_reason
{
/**
...
...
cppa/factory.hpp
0 → 100644
View file @
d90fc078
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011, 2012 *
* Dominik Charousset <dominik.charousset@haw-hamburg.de> *
* *
* This file is part of libcppa. *
* libcppa is free software: you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation, either version 3 of the License *
* or (at your option) any later version. *
* *
* libcppa is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
\******************************************************************************/
#ifndef CPPA_FACTORY_HPP
#define CPPA_FACTORY_HPP
#include "cppa/detail/event_based_actor_factory.hpp"
namespace
cppa
{
namespace
factory
{
#ifdef CPPA_DOCUMENTATION
/**
* @brief Returns a factory for event-based actors using @p fun as
* implementation for {@link cppa::event_based_actor::init() init()}.
*
* @p fun must take pointer arguments only. The factory creates an event-based
* actor implementation with member variables according to the functor's
* signature, as shown in the example below.
*
* @code
* auto f = factory::event_based([](int* a, int* b) { ... });
* auto actor1 = f.spawn();
* auto actor2 = f.spawn(1);
* auto actor3 = f.spawn(1, 2);
* @endcode
*
* The arguments @p a and @p b will point to @p int member variables of the
* actor. All member variables are initialized using the default constructor
* unless an initial value is passed to @p spawn.
*/
template
<
typename
InitFun
>
auto
event_based
(
InitFun
fun
);
/**
* @brief Returns a factory for event-based actors using @p fun0 as
* implementation for {@link cppa::event_based_actor::init() init()}
* and @p fun1 as implementation for
* {@link cppa::event_based_actor::on_exit() on_exit()}.
*/
template
<
typename
InitFun
,
OnExitFun
>
auto
event_based
(
InitFun
fun0
,
OnExitFun
fun1
);
#else // CPPA_DOCUMENTATION
void
default_cleanup
();
template
<
typename
InitFun
>
inline
typename
detail
::
ebaf_from_functor
<
InitFun
,
void
(
*
)()
>::
type
event_based
(
InitFun
init
)
{
return
{
std
::
move
(
init
),
default_cleanup
};
}
template
<
typename
InitFun
,
typename
OnExitFun
>
inline
typename
detail
::
ebaf_from_functor
<
InitFun
,
OnExitFun
>::
type
event_based
(
InitFun
init
,
OnExitFun
on_exit
)
{
return
{
std
::
move
(
init
),
on_exit
};
}
#endif // CPPA_DOCUMENTATION
}
}
// namespace cppa::factory
#endif // CPPA_FACTORY_HPP
cppa/guard_expr.hpp
View file @
d90fc078
...
...
@@ -726,7 +726,12 @@ struct mutable_gref_wrapped<T&> {
// finally ...
namespace
placeholders
{
namespace
{
namespace
placeholders
{
// doxygen cannot handle anonymous namespaces
#ifndef CPPA_DOCUMENTATION
namespace
{
#endif // CPPA_DOCUMENTATION
constexpr
guard_placeholder
<
0
>
_x1
;
constexpr
guard_placeholder
<
1
>
_x2
;
...
...
@@ -738,7 +743,12 @@ constexpr guard_placeholder<6> _x7;
constexpr
guard_placeholder
<
7
>
_x8
;
constexpr
guard_placeholder
<
8
>
_x9
;
}
}
// namespace placeholders::<anonymous>
// doxygen cannot handle anonymous namespaces
#ifndef CPPA_DOCUMENTATION
}
// namespace <anonymous>
#endif // CPPA_DOCUMENTATION
}
// namespace placeholders
}
// namespace cppa
...
...
cppa/scheduled_actor.hpp
View file @
d90fc078
...
...
@@ -63,6 +63,8 @@ class scheduled_actor : public local_actor {
scheduled_actor
*
attach_to_scheduler
(
scheduler
*
sched
);
virtual
bool
has_behavior
()
=
0
;
protected:
scheduler
*
m_scheduler
;
...
...
@@ -71,6 +73,8 @@ class scheduled_actor : public local_actor {
};
typedef
intrusive_ptr
<
scheduled_actor
>
scheduled_actor_ptr
;
}
// namespace cppa
#endif // CPPA_ACTOR_BEHAVIOR_HPP
src/factory.cpp
0 → 100644
View file @
d90fc078
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011, 2012 *
* Dominik Charousset <dominik.charousset@haw-hamburg.de> *
* *
* This file is part of libcppa. *
* libcppa is free software: you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation, either version 3 of the License *
* or (at your option) any later version. *
* *
* libcppa is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
\******************************************************************************/
#include "cppa/factory.hpp"
namespace
cppa
{
namespace
factory
{
void
default_cleanup
()
{
}
}
}
// namespace cppa::factory
src/scheduled_actor_dummy.cpp
View file @
d90fc078
...
...
@@ -54,6 +54,6 @@ void scheduled_actor_dummy::detach(const attachable::token&) { }
bool
scheduled_actor_dummy
::
attach
(
attachable
*
)
{
return
false
;
}
void
scheduled_actor_dummy
::
unbecome
()
{
}
void
scheduled_actor_dummy
::
do_become
(
behavior
*
,
bool
,
bool
)
{
}
bool
scheduled_actor_dummy
::
has_behavior
()
{
return
false
;
}
}
}
// namespace cppa::detail
src/thread_pool_scheduler.cpp
View file @
d90fc078
...
...
@@ -195,30 +195,36 @@ void thread_pool_scheduler::enqueue(scheduled_actor* what) {
m_queue
.
push_back
(
what
);
}
actor_ptr
thread_pool_scheduler
::
spawn_impl
(
scheduled_actor
*
what
,
actor_ptr
thread_pool_scheduler
::
spawn_impl
(
scheduled_actor
_ptr
what
,
bool
push_to_queue
)
{
inc_actor_count
();
std
::
atomic_thread_fence
(
std
::
memory_order_seq_cst
);
intrusive_ptr
<
scheduled_actor
>
ctx
(
what
);
ctx
->
ref
();
if
(
push_to_queue
)
m_queue
.
push_back
(
ctx
.
get
());
return
std
::
move
(
ctx
);
if
(
what
->
has_behavior
())
{
inc_actor_count
();
what
->
ref
();
if
(
push_to_queue
)
m_queue
.
push_back
(
what
.
get
());
}
else
{
what
->
on_exit
();
}
return
std
::
move
(
what
);
}
actor_ptr
thread_pool_scheduler
::
spawn
(
scheduled_actor
*
what
)
{
actor_ptr
thread_pool_scheduler
::
spawn
(
scheduled_actor
*
ptr
)
{
// do NOT push event-based actors to the queue on startup
return
spawn_impl
(
what
->
attach_to_scheduler
(
this
),
false
);
scheduled_actor_ptr
what
{
ptr
};
what
->
attach_to_scheduler
(
this
);
return
spawn_impl
(
std
::
move
(
what
),
false
);
}
#ifndef CPPA_DISABLE_CONTEXT_SWITCHING
actor_ptr
thread_pool_scheduler
::
spawn
(
std
::
function
<
void
()
>
what
,
actor_ptr
thread_pool_scheduler
::
spawn
(
std
::
function
<
void
()
>
bhvr
,
scheduling_hint
hint
)
{
if
(
hint
==
scheduled
)
{
auto
new_actor
=
new
context_switching_actor
(
std
::
move
(
what
));
return
spawn_impl
(
new_actor
->
attach_to_scheduler
(
this
));
scheduled_actor_ptr
ptr
{
new
context_switching_actor
(
std
::
move
(
bhvr
))};
ptr
->
attach_to_scheduler
(
this
);
return
spawn_impl
(
std
::
move
(
ptr
));
}
else
{
return
mock_scheduler
::
spawn_impl
(
std
::
move
(
what
));
return
mock_scheduler
::
spawn_impl
(
std
::
move
(
bhvr
));
}
}
#else
...
...
unit_testing/test__spawn.cpp
View file @
d90fc078
...
...
@@ -11,6 +11,7 @@
#include "cppa/on.hpp"
#include "cppa/cppa.hpp"
#include "cppa/actor.hpp"
#include "cppa/factory.hpp"
#include "cppa/scheduler.hpp"
#include "cppa/fsm_actor.hpp"
#include "cppa/to_string.hpp"
...
...
@@ -301,118 +302,6 @@ std::string behavior_test(actor_ptr et) {
return
result
;
}
template
<
class
MatchExpr
>
class
actor_template
{
MatchExpr
m_expr
;
public:
actor_template
(
MatchExpr
me
)
:
m_expr
(
std
::
move
(
me
))
{
}
actor_ptr
spawn
()
const
{
struct
impl
:
fsm_actor
<
impl
>
{
behavior
init_state
;
impl
(
const
MatchExpr
&
mx
)
:
init_state
(
mx
.
as_partial_function
())
{
}
};
return
cppa
::
spawn
(
new
impl
{
m_expr
});
}
};
template
<
typename
...
Args
>
auto
actor_prototype
(
const
Args
&
...
args
)
->
actor_template
<
decltype
(
mexpr_concat
(
args
...))
>
{
return
{
mexpr_concat
(
args
...)};
}
template
<
typename
InitFun
,
typename
CleanupFun
,
typename
...
Members
>
class
simple_event_based_actor_impl
:
public
event_based_actor
{
public:
template
<
typename
...
Args
>
simple_event_based_actor_impl
(
InitFun
fun
,
CleanupFun
cfun
,
Args
&&
...
args
)
:
m_init
(
std
::
move
(
fun
)),
m_cleanup
(
std
::
move
(
cfun
))
,
m_members
(
std
::
forward
<
Args
>
(
args
)...)
{
}
void
init
()
{
apply
(
m_init
);
}
void
on_exit
()
{
m_cleanup
();
}
private:
InitFun
m_init
;
CleanupFun
m_cleanup
;
detail
::
tdata
<
Members
...
>
m_members
;
template
<
typename
F
>
void
apply
(
F
&
f
,
typename
std
::
add_pointer
<
Members
>::
type
...
args
)
{
f
(
args
...);
}
template
<
typename
F
,
typename
...
Args
>
void
apply
(
F
&
f
,
Args
...
args
)
{
apply
(
f
,
args
...,
&
get_ref
<
sizeof
...(
Args
)
>
(
m_members
));
}
};
template
<
typename
InitFun
,
typename
CleanupFun
,
typename
...
Members
>
class
simple_event_based_actor_factory
{
public:
typedef
simple_event_based_actor_impl
<
InitFun
,
CleanupFun
,
Members
...
>
impl
;
simple_event_based_actor_factory
(
InitFun
fun
,
CleanupFun
cfun
)
:
m_init
(
std
::
move
(
fun
)),
m_cleanup
(
std
::
move
(
cfun
))
{
}
template
<
typename
...
Args
>
actor_ptr
spawn
(
Args
&&
...
args
)
{
return
cppa
::
spawn
(
new
impl
(
m_init
,
m_cleanup
,
std
::
forward
<
Args
>
(
args
)...));
}
private:
InitFun
m_init
;
CleanupFun
m_cleanup
;
};
template
<
typename
InitFun
,
typename
CleanupFun
,
class
TypeList
>
struct
actor_tpl_from_type_list
;
template
<
typename
InitFun
,
typename
CleanupFun
,
typename
...
Ts
>
struct
actor_tpl_from_type_list
<
InitFun
,
CleanupFun
,
util
::
type_list
<
Ts
...
>
>
{
typedef
simple_event_based_actor_factory
<
InitFun
,
CleanupFun
,
Ts
...
>
type
;
};
template
<
typename
Init
,
typename
Cleanup
>
struct
actor_tpl_from_fun
{
typedef
typename
util
::
get_arg_types
<
Init
>::
types
arg_types
;
typedef
typename
util
::
get_arg_types
<
Cleanup
>::
types
arg_types2
;
static_assert
(
util
::
tl_forall
<
arg_types
,
std
::
is_pointer
>::
value
,
"First functor takes non-pointer arguments"
);
static_assert
(
std
::
is_same
<
arg_types
,
arg_types2
>::
value
||
std
::
is_same
<
util
::
type_list
<>
,
arg_types2
>::
value
,
"Second functor must provide either the same signature "
" as the first one or take zero arguments"
);
typedef
typename
util
::
tl_map
<
arg_types
,
std
::
remove_pointer
>::
type
mems
;
typedef
typename
actor_tpl_from_type_list
<
Init
,
Cleanup
,
mems
>::
type
type
;
};
void
dummy_function
()
{
}
struct
factory
{
template
<
typename
Fun
>
static
inline
typename
actor_tpl_from_fun
<
Fun
,
void
(
*
)()
>::
type
event_based
(
Fun
fun
)
{
return
{
std
::
move
(
fun
),
dummy_function
};
}
};
size_t
test__spawn
()
{
using
std
::
string
;
CPPA_TEST
(
test__spawn
);
...
...
@@ -449,29 +338,6 @@ size_t test__spawn() {
send
(
mirror
,
atom
(
"EXIT"
),
exit_reason
::
user_defined
);
CPPA_IF_VERBOSE
(
cout
<<
"ok"
<<
endl
);
auto
svec
=
std
::
make_shared
<
std
::
vector
<
string
>
>
();
auto
avec
=
actor_prototype
(
on
(
atom
(
"push_back"
),
arg_match
)
>>
[
svec
](
const
string
&
str
)
{
svec
->
push_back
(
str
);
},
on
(
atom
(
"get"
))
>>
[
svec
]()
{
reply
(
*
svec
);
}
).
spawn
();
send
(
avec
,
atom
(
"push_back"
),
"hello"
);
send
(
avec
,
atom
(
"push_back"
),
" world"
);
send
(
avec
,
atom
(
"get"
));
send
(
avec
,
atom
(
"EXIT"
),
exit_reason
::
user_defined
);
receive
(
on_arg_match
>>
[
&
](
const
std
::
vector
<
string
>&
vec
)
{
if
(
vec
.
size
()
==
2
)
{
CPPA_CHECK_EQUAL
(
"hello world"
,
vec
.
front
()
+
vec
.
back
());
}
}
);
CPPA_IF_VERBOSE
(
cout
<<
"test delayed_send() ... "
<<
std
::
flush
);
delayed_send
(
self
,
std
::
chrono
::
seconds
(
1
),
1
,
2
,
3
);
receive
(
on
(
1
,
2
,
3
)
>>
[]()
{
});
...
...
@@ -535,6 +401,39 @@ size_t test__spawn() {
await_all_others_done
();
CPPA_IF_VERBOSE
(
cout
<<
"ok"
<<
endl
);
int
zombie_init_called
=
0
;
int
zombie_on_exit_called
=
0
;
factory
::
event_based
([
&
]()
{
++
zombie_init_called
;
},
[
&
]()
{
++
zombie_on_exit_called
;
})
.
spawn
();
CPPA_CHECK_EQUAL
(
1
,
zombie_init_called
);
CPPA_CHECK_EQUAL
(
1
,
zombie_on_exit_called
);
factory
::
event_based
([
&
](
int
*
i
)
{
CPPA_CHECK_EQUAL
(
42
,
*
i
);
++
zombie_init_called
;
},
[
&
](
int
*
i
)
{
CPPA_CHECK_EQUAL
(
42
,
*
i
);
++
zombie_on_exit_called
;
})
.
spawn
(
42
);
CPPA_CHECK_EQUAL
(
2
,
zombie_init_called
);
CPPA_CHECK_EQUAL
(
2
,
zombie_on_exit_called
);
factory
::
event_based
([
&
](
int
*
i
)
{
CPPA_CHECK_EQUAL
(
23
,
*
i
);
++
zombie_init_called
;
},
[
&
]()
{
++
zombie_on_exit_called
;
})
.
spawn
(
23
);
CPPA_CHECK_EQUAL
(
3
,
zombie_init_called
);
CPPA_CHECK_EQUAL
(
3
,
zombie_on_exit_called
);
CPPA_CHECK_EQUAL
(
behavior_test
<
testee_actor
>
(
spawn
(
testee_actor
{})),
"wait4int"
);
CPPA_CHECK_EQUAL
(
behavior_test
<
event_testee
>
(
spawn
(
new
event_testee
)),
"wait4int"
);
...
...
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