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
f9b9aade
Commit
f9b9aade
authored
Apr 04, 2013
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'unstable' into topic/opencl
Conflicts: cppa.files
parents
d71658df
b1c6e28a
Changes
26
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
26 changed files
with
608 additions
and
299 deletions
+608
-299
cppa.files
cppa.files
+33
-33
cppa/cppa.hpp
cppa/cppa.hpp
+7
-4
cppa/guard_expr.hpp
cppa/guard_expr.hpp
+21
-0
cppa/local_actor.hpp
cppa/local_actor.hpp
+7
-0
cppa/option.hpp
cppa/option.hpp
+7
-0
cppa/partial_function.hpp
cppa/partial_function.hpp
+5
-5
cppa/self.hpp
cppa/self.hpp
+6
-0
cppa/util/callable_trait.hpp
cppa/util/callable_trait.hpp
+5
-0
examples/CMakeLists.txt
examples/CMakeLists.txt
+3
-3
examples/hello_world.cpp
examples/hello_world.cpp
+7
-11
examples/message_passing/calculator.cpp
examples/message_passing/calculator.cpp
+23
-29
examples/message_passing/dancing_kirby.cpp
examples/message_passing/dancing_kirby.cpp
+33
-15
examples/message_passing/dining_philosophers.cpp
examples/message_passing/dining_philosophers.cpp
+14
-16
examples/remote_actors/distributed_calculator.cpp
examples/remote_actors/distributed_calculator.cpp
+223
-0
examples/remote_actors/group_chat.cpp
examples/remote_actors/group_chat.cpp
+28
-42
examples/remote_actors/group_server.cpp
examples/remote_actors/group_server.cpp
+2
-1
examples/type_system/announce_1.cpp
examples/type_system/announce_1.cpp
+40
-31
examples/type_system/announce_2.cpp
examples/type_system/announce_2.cpp
+15
-12
examples/type_system/announce_3.cpp
examples/type_system/announce_3.cpp
+15
-11
examples/type_system/announce_4.cpp
examples/type_system/announce_4.cpp
+28
-20
examples/type_system/announce_5.cpp
examples/type_system/announce_5.cpp
+58
-46
src/scheduled_actor.cpp
src/scheduled_actor.cpp
+2
-2
src/self.cpp
src/self.cpp
+16
-8
unit_testing/ping_pong.cpp
unit_testing/ping_pong.cpp
+1
-1
unit_testing/test_spawn.cpp
unit_testing/test_spawn.cpp
+7
-7
unit_testing/test_sync_send.cpp
unit_testing/test_sync_send.cpp
+2
-2
No files found.
cppa.files
View file @
f9b9aade
...
...
@@ -47,14 +47,12 @@ cppa/detail/pseudo_tuple.hpp
cppa/detail/ptype_to_type.hpp
cppa/detail/receive_loop_helper.hpp
cppa/detail/receive_policy.hpp
cppa/mailbox_element.hpp
cppa/mailbox_based.hpp
cppa/detail/scheduled_actor_dummy.hpp
cppa/detail/serialize_tuple.hpp
cppa/detail/singleton_manager.hpp
cppa/detail/singleton_mixin.hpp
cppa/stacked.hpp
cppa/detail/swap_bytes.hpp
cppa/detail/sync_request_bouncer.hpp
cppa/detail/tdata.hpp
cppa/detail/thread_pool_scheduler.hpp
cppa/detail/to_uniform_name.hpp
...
...
@@ -72,6 +70,7 @@ cppa/enable_weak_ptr.hpp
cppa/event_based_actor.hpp
cppa/exception.hpp
cppa/exit_reason.hpp
cppa/extend.hpp
cppa/factory.hpp
cppa/from_string.hpp
cppa/get.hpp
...
...
@@ -82,8 +81,11 @@ cppa/intrusive/single_reader_queue.hpp
cppa/intrusive_ptr.hpp
cppa/local_actor.hpp
cppa/logging.hpp
cppa/mailbox_based.hpp
cppa/mailbox_element.hpp
cppa/match.hpp
cppa/match_expr.hpp
cppa/memory_cached.hpp
cppa/memory_managed.hpp
cppa/message_future.hpp
cppa/message_id.hpp
...
...
@@ -107,6 +109,13 @@ cppa/network/output_stream.hpp
cppa/network/protocol.hpp
cppa/object.hpp
cppa/on.hpp
cppa/opencl.hpp
cppa/opencl/actor_facade.hpp
cppa/opencl/command.hpp
cppa/opencl/command_dispatcher.hpp
cppa/opencl/global.hpp
cppa/opencl/program.hpp
cppa/opencl/smart_ptr.hpp
cppa/opt.hpp
cppa/option.hpp
cppa/partial_function.hpp
...
...
@@ -122,7 +131,11 @@ cppa/scheduled_actor.hpp
cppa/scheduler.hpp
cppa/self.hpp
cppa/serializer.hpp
cppa/singletons.hpp
cppa/spawn_options.hpp
cppa/stacked.hpp
cppa/thread_mapped_actor.hpp
cppa/threaded.hpp
cppa/timeout_definition.hpp
cppa/to_string.hpp
cppa/tpartial_function.hpp
...
...
@@ -139,13 +152,16 @@ cppa/util/compare_tuples.hpp
cppa/util/conjunction.hpp
cppa/util/deduce_ref_type.hpp
cppa/util/disjunction.hpp
cppa/util/dptr.hpp
cppa/util/duration.hpp
cppa/util/element_at.hpp
cppa/util/fiber.hpp
cppa/util/fixed_vector.hpp
cppa/util/get_result_type.hpp
cppa/util/int_list.hpp
cppa/util/is_array_of.hpp
cppa/util/is_builtin.hpp
cppa/util/is_callable.hpp
cppa/util/is_comparable.hpp
cppa/util/is_forward_iterator.hpp
cppa/util/is_iterable.hpp
...
...
@@ -158,6 +174,7 @@ cppa/util/producer_consumer_list.hpp
cppa/util/pt_dispatch.hpp
cppa/util/pt_token.hpp
cppa/util/purge_refs.hpp
cppa/util/rebindable_reference.hpp
cppa/util/replace_type.hpp
cppa/util/ripemd_160.hpp
cppa/util/rm_option.hpp
...
...
@@ -174,15 +191,15 @@ cppa/util/wrapped.hpp
cppa/weak_intrusive_ptr.hpp
cppa/weak_ptr_anchor.hpp
cppa/wildcard_position.hpp
examples/event_based_api/dining_philosophers.cpp
examples/hello_world.cpp
examples/message_passing/calculator.cpp
examples/message_passing/dancing_kirby.cpp
examples/message_passing/
math_actor
.cpp
examples/message_passing/
dining_philosophers
.cpp
examples/qtsupport/chatwidget.cpp
examples/qtsupport/chatwidget.hpp
examples/qtsupport/chatwindow.ui
examples/qtsupport/qt_group_chat.cpp
examples/remote_actors/distributed_
math_ac
tor.cpp
examples/remote_actors/distributed_
calcula
tor.cpp
examples/remote_actors/group_chat.cpp
examples/remote_actors/group_server.cpp
examples/type_system/announce_1.cpp
...
...
@@ -219,6 +236,7 @@ src/duration.cpp
src/empty_tuple.cpp
src/event_based_actor.cpp
src/exception.cpp
src/exit_reason.cpp
src/factory.cpp
src/fd_util.cpp
src/fiber.cpp
...
...
@@ -228,6 +246,7 @@ src/ipv4_acceptor.cpp
src/ipv4_io_stream.cpp
src/local_actor.cpp
src/logging.cpp
src/mailbox_element.cpp
src/match.cpp
src/memory.cpp
src/memory_managed.cpp
...
...
@@ -235,12 +254,16 @@ src/message_header.cpp
src/middleman.cpp
src/object.cpp
src/object_array.cpp
src/on.cpp
src/opencl/actor_facade.cpp
src/opencl/command_dispatcher.cpp
src/opencl/global.cpp
src/opencl/program.cpp
src/opt.cpp
src/partial_function.cpp
src/primitive_variant.cpp
src/process_information.cpp
src/protocol.cpp
src/mailbox_element.cpp
src/ref_counted.cpp
src/response_handle.cpp
src/ripemd_160.cpp
...
...
@@ -261,6 +284,7 @@ src/weak_ptr_anchor.cpp
src/yield_interface.cpp
unit_testing/ping_pong.cpp
unit_testing/ping_pong.hpp
unit_testing/test.cpp
unit_testing/test.hpp
unit_testing/test_atom.cpp
unit_testing/test_fixed_vector.cpp
...
...
@@ -268,6 +292,8 @@ unit_testing/test_intrusive_containers.cpp
unit_testing/test_intrusive_ptr.cpp
unit_testing/test_local_group.cpp
unit_testing/test_match.cpp
unit_testing/test_metaprogramming.cpp
unit_testing/test_opencl.cpp
unit_testing/test_primitive_variant.cpp
unit_testing/test_remote_actor.cpp
unit_testing/test_ripemd_160.cpp
...
...
@@ -275,31 +301,5 @@ unit_testing/test_serialization.cpp
unit_testing/test_spawn.cpp
unit_testing/test_sync_send.cpp
unit_testing/test_tuple.cpp
unit_testing/test_metaprogramming.cpp
unit_testing/test_uniform_type.cpp
unit_testing/test_yield_interface.cpp
unit_testing/test.cpp
cppa/opencl/program.hpp
cppa/opencl/actor_facade.hpp
cppa/opencl/command.hpp
cppa/opencl/command_dispatcher.hpp
src/opencl/command_dispatcher.cpp
unit_testing/test_opencl.cpp
cppa/opencl/global.hpp
src/opencl/global.cpp
src/opencl/program.cpp
src/opencl/actor_facade.cpp
cppa/opencl/smart_ptr.hpp
src/exit_reason.cpp
src/on.cpp
cppa/spawn_options.hpp
cppa/extend.hpp
cppa/detail/sync_request_bouncer.hpp
cppa/memory_cached.hpp
cppa/singletons.hpp
cppa/threaded.hpp
cppa/util/dptr.hpp
cppa/util/is_callable.hpp
cppa/util/get_result_type.hpp
cppa/util/rebindable_reference.hpp
cppa/opencl.hpp
cppa/cppa.hpp
View file @
f9b9aade
...
...
@@ -856,12 +856,15 @@ actor_ptr remote_actor(network::io_stream_ptr_pair connection);
void
shutdown
();
// note: implemented in singleton_manager.cpp
/**
* @brief Causes @p whom to quit with @p reason.
* @note Does nothing if <tt>reason == exit_reason::normal</tt>.
* @brief Sends an exit message to @p whom with @p reason.
*
* This function is syntactic sugar for
* <tt>send(whom, atom("EXIT"), reason)</tt>.
* @pre <tt>reason != exit_reason::normal</tt>
*/
inline
void
quit_actor
(
const
actor_ptr
&
whom
,
std
::
uint32_t
reason
)
{
inline
void
send_exit
(
const
actor_ptr
&
whom
,
std
::
uint32_t
reason
)
{
CPPA_REQUIRE
(
reason
!=
exit_reason
::
normal
);
send
(
whom
.
get
()
,
atom
(
"EXIT"
),
reason
);
send
(
whom
,
atom
(
"EXIT"
),
reason
);
}
/**
...
...
cppa/guard_expr.hpp
View file @
f9b9aade
...
...
@@ -338,6 +338,14 @@ struct guard_placeholder {
};
template
<
typename
T
>
struct
ge_value
{
T
value
;
};
template
<
typename
T
>
ge_value
<
T
>
gval
(
T
val
)
{
return
{
std
::
move
(
val
)};
}
// result type computation
template
<
typename
T
,
class
Tuple
>
...
...
@@ -352,6 +360,9 @@ struct ge_unbound<std::reference_wrapper<T>, Tuple> { typedef T type; };
template
<
typename
T
,
class
Tuple
>
struct
ge_unbound
<
std
::
reference_wrapper
<
const
T
>
,
Tuple
>
{
typedef
T
type
;
};
template
<
typename
T
,
class
Tuple
>
struct
ge_unbound
<
ge_value
<
T
>
,
Tuple
>
{
typedef
T
type
;
};
// unbound type of placeholder
template
<
int
X
,
typename
...
Ts
>
struct
ge_unbound
<
guard_placeholder
<
X
>
,
detail
::
tdata
<
Ts
...
>
>
{
...
...
@@ -386,6 +397,11 @@ struct is_ge_type<guard_expr<OP, First, Second> > {
static
constexpr
bool
value
=
true
;
};
template
<
typename
T
>
struct
is_ge_type
<
ge_value
<
T
>>
{
static
constexpr
bool
value
=
true
;
};
template
<
operator_id
OP
,
typename
T1
,
typename
T2
>
guard_expr
<
OP
,
typename
detail
::
strip_and_convert
<
T1
>::
type
,
typename
detail
::
strip_and_convert
<
T2
>::
type
>
...
...
@@ -516,6 +532,11 @@ inline const T& ge_resolve(const Tuple&, const util::rebindable_reference<const
return
value
.
get
();
}
template
<
class
Tuple
,
typename
T
>
inline
const
T
&
ge_resolve
(
const
Tuple
&
,
const
ge_value
<
T
>&
wrapped_value
)
{
return
wrapped_value
.
value
;
}
template
<
class
Tuple
,
int
X
>
inline
auto
ge_resolve
(
const
Tuple
&
tup
,
guard_placeholder
<
X
>
)
->
decltype
(
get
<
X
>
(
tup
).
get
())
{
...
...
cppa/local_actor.hpp
View file @
f9b9aade
...
...
@@ -221,6 +221,13 @@ class local_actor : public extend<actor>::with<memory_cached> {
m_sync_failure_handler
=
std
::
move
(
fun
);
}
/**
* @brief Checks wheter this actor has a user-defined sync failure handler.
*/
inline
bool
has_sync_failure_handler
()
{
return
static_cast
<
bool
>
(
m_sync_failure_handler
);
}
/**
* @brief Calls <tt>on_sync_timeout(fun); on_sync_failure(fun);</tt>.
*/
...
...
cppa/option.hpp
View file @
f9b9aade
...
...
@@ -62,6 +62,13 @@ class option {
*/
option
(
T
value
)
:
m_valid
(
false
)
{
cr
(
std
::
move
(
value
));
}
template
<
typename
T0
,
typename
T1
,
typename
...
Ts
>
option
(
T0
&&
arg0
,
T1
&&
arg1
,
Ts
&&
...
args
)
{
cr
(
T
(
std
::
forward
<
T0
>
(
arg0
),
std
::
forward
<
T1
>
(
arg1
),
std
::
forward
<
Ts
>
(
args
)...));
}
option
(
const
option
&
other
)
:
m_valid
(
false
)
{
if
(
other
.
m_valid
)
cr
(
other
.
m_value
);
}
...
...
cppa/partial_function.hpp
View file @
f9b9aade
...
...
@@ -79,8 +79,8 @@ class partial_function {
partial_function
&
operator
=
(
partial_function
&&
)
=
default
;
partial_function
&
operator
=
(
const
partial_function
&
)
=
default
;
template
<
typename
...
Cs
>
partial_function
(
const
match_expr
<
Cs
...
>&
mexpr
);
template
<
typename
...
Cs
,
typename
...
Ts
>
partial_function
(
const
match_expr
<
Cs
...
>&
mexpr
,
const
Ts
&
...
args
);
/**
* @brief Returns @p true if this partial function is defined for the
...
...
@@ -141,9 +141,9 @@ match_expr_convert(const T0& arg0, const T1& arg1, const Ts&... args) {
* inline and template member function implementations *
******************************************************************************/
template
<
typename
...
Cs
>
partial_function
::
partial_function
(
const
match_expr
<
Cs
...
>&
mexpr
)
:
m_impl
(
mexpr
.
as_behavior_impl
(
))
{
}
template
<
typename
...
Cs
,
typename
...
Ts
>
partial_function
::
partial_function
(
const
match_expr
<
Cs
...
>&
arg
,
const
Ts
&
...
args
)
:
m_impl
(
detail
::
match_expr_concat
(
arg
,
args
...
))
{
}
inline
bool
partial_function
::
defined_at
(
const
any_tuple
&
value
)
{
return
(
m_impl
)
&&
m_impl
->
defined_at
(
value
);
...
...
cppa/self.hpp
View file @
f9b9aade
...
...
@@ -146,6 +146,12 @@ class scoped_self_setter {
};
// disambiguation (compiler gets confused with cast operator otherwise)
bool
operator
==
(
const
actor_ptr
&
lhs
,
const
self_type
&
rhs
);
bool
operator
==
(
const
self_type
&
lhs
,
const
actor_ptr
&
rhs
);
bool
operator
!=
(
const
actor_ptr
&
lhs
,
const
self_type
&
rhs
);
bool
operator
!=
(
const
self_type
&
lhs
,
const
actor_ptr
&
rhs
);
#endif // CPPA_DOCUMENTATION
}
// namespace cppa
...
...
cppa/util/callable_trait.hpp
View file @
f9b9aade
...
...
@@ -31,6 +31,7 @@
#ifndef CPPA_UTIL_CALLABLE_TRAIT
#define CPPA_UTIL_CALLABLE_TRAIT
#include <functional>
#include <type_traits>
#include "cppa/util/rm_ref.hpp"
...
...
@@ -46,6 +47,7 @@ template<class C, typename Result, typename... Ts>
struct
callable_trait
<
Result
(
C
::*
)(
Ts
...)
const
>
{
typedef
Result
result_type
;
typedef
type_list
<
Ts
...
>
arg_types
;
typedef
std
::
function
<
Result
(
Ts
...)
>
fun_type
;
};
// member function pointer
...
...
@@ -53,6 +55,7 @@ template<class C, typename Result, typename... Ts>
struct
callable_trait
<
Result
(
C
::*
)(
Ts
...)
>
{
typedef
Result
result_type
;
typedef
type_list
<
Ts
...
>
arg_types
;
typedef
std
::
function
<
Result
(
Ts
...)
>
fun_type
;
};
// good ol' function
...
...
@@ -60,6 +63,7 @@ template<typename Result, typename... Ts>
struct
callable_trait
<
Result
(
Ts
...)
>
{
typedef
Result
result_type
;
typedef
type_list
<
Ts
...
>
arg_types
;
typedef
std
::
function
<
Result
(
Ts
...)
>
fun_type
;
};
// good ol' function pointer
...
...
@@ -67,6 +71,7 @@ template<typename Result, typename... Ts>
struct
callable_trait
<
Result
(
*
)(
Ts
...)
>
{
typedef
Result
result_type
;
typedef
type_list
<
Ts
...
>
arg_types
;
typedef
std
::
function
<
Result
(
Ts
...)
>
fun_type
;
};
// matches (IsFun || IsMemberFun)
...
...
examples/CMakeLists.txt
View file @
f9b9aade
...
...
@@ -15,10 +15,10 @@ add(announce_3 type_system)
add
(
announce_4 type_system
)
add
(
announce_5 type_system
)
add
(
dancing_kirby message_passing
)
add
(
dining_philosophers
event_based_api
)
add
(
dining_philosophers
message_passing
)
add
(
hello_world .
)
add
(
math_ac
tor message_passing
)
add
(
distributed_
math_ac
tor remote_actors
)
add
(
calcula
tor message_passing
)
add
(
distributed_
calcula
tor remote_actors
)
add
(
group_server remote_actors
)
add
(
group_chat remote_actors
)
...
...
examples/hello_world.cpp
View file @
f9b9aade
...
...
@@ -9,26 +9,23 @@ void mirror() {
become
(
// invoke this lambda expression if we receive a string
on_arg_match
>>
[](
const
std
::
string
&
what
)
{
// prints "Hello World!"
std
::
c
out
<<
what
<<
std
::
endl
;
// prints "Hello World!"
via aout (thread-safe cout wrapper)
a
out
<<
what
<<
std
::
endl
;
// replies "!dlroW olleH"
reply
(
std
::
string
(
what
.
rbegin
(),
what
.
rend
()));
// terminates this actor
// terminates this actor
(become otherwise 'loops' forever)
self
->
quit
();
}
);
}
void
hello_world
(
const
actor_ptr
&
buddy
)
{
// send "Hello World!" to the mirror
send
(
buddy
,
"Hello World!"
);
// wait for messages
become
(
// send "Hello World!" to our buddy ...
sync_send
(
buddy
,
"Hello World!"
).
then
(
// ... and wait for a response
on_arg_match
>>
[](
const
std
::
string
&
what
)
{
// prints "!dlroW olleH"
std
::
cout
<<
what
<<
std
::
endl
;
// terminate this actor
self
->
quit
();
aout
<<
what
<<
std
::
endl
;
}
);
}
...
...
@@ -42,5 +39,4 @@ int main() {
await_all_others_done
();
// run cleanup code before exiting main
shutdown
();
return
0
;
}
examples/message_passing/
math_ac
tor.cpp
→
examples/message_passing/
calcula
tor.cpp
View file @
f9b9aade
...
...
@@ -34,8 +34,7 @@ void blocking_math_fun() {
).
until
(
gref
(
done
));
}
// implementation using the event-based API
void
math_fun
()
{
void
calculator
()
{
// execute this behavior until actor terminates
become
(
on
(
atom
(
"plus"
),
arg_match
)
>>
[](
int
a
,
int
b
)
{
...
...
@@ -44,43 +43,38 @@ void math_fun() {
on
(
atom
(
"minus"
),
arg_match
)
>>
[](
int
a
,
int
b
)
{
reply
(
atom
(
"result"
),
a
-
b
);
},
// the [=] capture copies the 'this' pointer into the lambda
// thus, it has access to all members and member functions
on
(
atom
(
"quit"
))
>>
[
=
]
{
on
(
atom
(
"quit"
))
>>
[]
{
// terminate actor with normal exit reason
self
->
quit
();
}
);
}
// utility function
int
fetch_result
(
actor_ptr
&
calculator
,
atom_value
operation
,
int
a
,
int
b
)
{
// send request
send
(
calculator
,
operation
,
a
,
b
);
// wait for result
int
result
;
receive
(
on
<
atom
(
"result"
),
int
>
()
>>
[
&
](
int
r
)
{
result
=
r
;
});
// print and return result
cout
<<
a
<<
" "
<<
to_string
(
operation
)
<<
" "
<<
b
<<
" = "
<<
result
<<
endl
;
return
result
;
void
tester
(
const
actor_ptr
&
testee
)
{
self
->
link_to
(
testee
);
// will be invoked if we receive an unexpected response message
self
->
on_sync_failure
([]
{
aout
<<
"AUT (actor under test) failed"
<<
endl
;
self
->
quit
(
exit_reason
::
user_defined
);
});
// first test: 2 + 1 = 3
sync_send
(
testee
,
atom
(
"plus"
),
2
,
1
).
then
(
on
(
atom
(
"result"
),
3
)
>>
[
=
]
{
// second test: 2 - 1 = 1
sync_send
(
testee
,
atom
(
"minus"
),
2
,
1
).
then
(
on
(
atom
(
"result"
),
1
)
>>
[
=
]
{
// both tests succeeded
aout
<<
"AUT (actor under test) seems to be ok"
<<
endl
;
send
(
testee
,
atom
(
"quit"
));
}
);
}
);
}
int
main
()
{
// spawn a context-switching actor that invokes math_fun
auto
a1
=
spawn
<
blocking_api
>
(
blocking_math_fun
);
// spawn an event-based math actor
auto
a2
=
spawn
(
math_fun
);
// do some testing on both implementations
assert
((
fetch_result
(
a1
,
atom
(
"plus"
),
1
,
2
)
==
3
));
assert
((
fetch_result
(
a2
,
atom
(
"plus"
),
1
,
2
)
==
3
));
assert
((
fetch_result
(
a1
,
atom
(
"minus"
),
2
,
1
)
==
1
));
assert
((
fetch_result
(
a2
,
atom
(
"minus"
),
2
,
1
)
==
1
));
// tell both actors to terminate
send
(
a1
,
atom
(
"quit"
));
send
(
a2
,
atom
(
"quit"
));
// wait until all spawned actors are terminated
spawn
(
tester
,
spawn
(
calculator
));
await_all_others_done
();
// done
shutdown
();
return
0
;
}
...
...
examples/message_passing/dancing_kirby.cpp
View file @
f9b9aade
...
...
@@ -9,6 +9,8 @@
using
std
::
cout
;
using
std
::
endl
;
using
std
::
pair
;
using
namespace
cppa
;
// ASCII art figures
...
...
@@ -18,44 +20,60 @@ constexpr const char* figures[] = {
"(>^.^)>"
};
struct
animation_step
{
size_t
figure_idx
;
size_t
offset
;
};
// array of {figure, offset} pairs
constexpr
size_t
animation_steps
[][
2
]
=
{
constexpr
animation_step
animation_steps
[
]
=
{
{
1
,
7
},
{
0
,
7
},
{
0
,
6
},
{
0
,
5
},
{
1
,
5
},
{
2
,
5
},
{
2
,
6
},
{
2
,
7
},
{
2
,
8
},
{
2
,
9
},
{
2
,
10
},
{
1
,
10
},
{
0
,
10
},
{
0
,
9
},
{
1
,
9
},
{
2
,
10
},
{
2
,
11
},
{
2
,
12
},
{
2
,
13
},
{
1
,
13
},
{
0
,
13
},
{
0
,
12
},
{
0
,
11
},
{
0
,
10
},
{
0
,
9
},
{
0
,
8
},
{
0
,
7
},
{
1
,
7
}
};
template
<
typename
T
,
size_t
S
>
constexpr
size_t
array_size
(
const
T
(
&
)
[
S
])
{
return
S
;
}
constexpr
size_t
animation_width
=
20
;
// "draws" an animation step
: {offset_whitespaces}{figure}{padding}
void
draw_kirby
(
size_t
const
(
&
animation
)[
2
]
)
{
// "draws" an animation step
by printing "{offset_whitespaces}{figure}{padding}"
void
draw_kirby
(
const
animation_step
&
animation
)
{
cout
.
width
(
animation_width
);
// override last figure
cout
<<
'\r'
;
std
::
fill_n
(
std
::
ostream_iterator
<
char
>
{
cout
},
animation
[
1
],
' '
);
cout
<<
figures
[
animation
[
0
]];
// print offset
std
::
fill_n
(
std
::
ostream_iterator
<
char
>
{
cout
},
animation
.
offset
,
' '
);
// print figure
cout
<<
figures
[
animation
.
figure_idx
];
// print padding
cout
.
fill
(
' '
);
// make sure figure is printed
cout
.
flush
();
}
// uses a message-based loop to iterate over all animation steps
void
dancing_kirby
()
{
// let's get it started
send
(
self
,
atom
(
"Step"
));
// iterate over animation_steps
auto
i
=
std
::
begin
(
animation_steps
);
receive_for
(
i
,
std
::
end
(
animation_steps
))
(
on
<
atom
(
"Step"
)
>
()
>>
[
&
]()
{
draw_kirby
(
*
i
);
send
(
self
,
atom
(
"Step"
),
size_t
{
0
});
become
(
on
(
atom
(
"Step"
),
array_size
(
animation_steps
))
>>
[]
{
// we've printed all animation steps (done)
cout
<<
endl
;
self
->
quit
();
},
on
(
atom
(
"Step"
),
arg_match
)
>>
[](
size_t
step
)
{
// print given step
draw_kirby
(
animation_steps
[
step
]);
// animate next step in 150ms
delayed_send
(
self
,
std
::
chrono
::
milliseconds
(
150
),
atom
(
"Step"
));
delayed_send
(
self
,
std
::
chrono
::
milliseconds
(
150
),
atom
(
"Step"
)
,
step
+
1
);
}
);
}
int
main
()
{
cout
<<
endl
;
dancing_kirby
();
cout
<<
endl
;
spawn
(
dancing_kirby
);
await_all_others_done
();
shutdown
();
return
0
;
}
examples/
event_based_api
/dining_philosophers.cpp
→
examples/
message_passing
/dining_philosophers.cpp
View file @
f9b9aade
...
...
@@ -24,7 +24,8 @@ void chopstick() {
send
(
philos
,
atom
(
"taken"
),
self
);
// await 'put' message and reject other 'take' messages
become
(
keep_behavior
,
// "enables" unbecome()
// allows us to return to the previous behavior
keep_behavior
,
on
(
atom
(
"take"
),
arg_match
)
>>
[
=
](
const
actor_ptr
&
other
)
{
send
(
other
,
atom
(
"busy"
),
self
);
},
...
...
@@ -70,7 +71,7 @@ void chopstick() {
* [ X = right => Y = left ]
*/
struct
philosopher
:
sb_actor
<
philosopher
>
{
struct
philosopher
:
event_based_actor
{
std
::
string
name
;
// the name of this philosopher
actor_ptr
left
;
// left chopstick
...
...
@@ -82,7 +83,6 @@ struct philosopher : sb_actor<philosopher> {
behavior
hungry
;
behavior
denied
;
behavior
eating
;
behavior
init_state
;
// wait for second chopstick
behavior
waiting_for
(
const
actor_ptr
&
what
)
{
...
...
@@ -107,7 +107,7 @@ struct philosopher : sb_actor<philosopher> {
}
philosopher
(
const
std
::
string
&
n
,
const
actor_ptr
&
l
,
const
actor_ptr
&
r
)
:
name
(
n
),
left
(
l
),
right
(
r
)
{
:
name
(
n
),
left
(
l
),
right
(
r
)
{
// a philosopher that receives {eat} stops thinking and becomes hungry
thinking
=
(
on
(
atom
(
"eat"
))
>>
[
=
]
{
...
...
@@ -151,14 +151,19 @@ struct philosopher : sb_actor<philosopher> {
become
(
thinking
);
}
);
}
void
init
()
{
// philosophers start to think after receiving {think}
init_state
=
(
become
(
on
(
atom
(
"think"
))
>>
[
=
]
{
aout
<<
name
<<
" starts to think
\n
"
;
delayed_send
(
this
,
seconds
(
5
),
atom
(
"eat"
));
become
(
thinking
);
}
);
// start thinking
send
(
this
,
atom
(
"think"
));
}
};
...
...
@@ -172,19 +177,12 @@ int main(int, char**) {
aout
<<
" "
<<
chopsticks
.
back
()
->
id
();
}
aout
<<
endl
;
// a group to address all philosophers
auto
dinner_club
=
group
::
anonymous
();
// spawn five philosopher, each joining the Dinner Club
std
::
vector
<
std
::
string
>
names
=
{
"Plato"
,
"Hume"
,
"Kant"
,
"Nietzsche"
,
"Descartes"
};
// spawn five philosophers
std
::
vector
<
std
::
string
>
names
{
"Plato"
,
"Hume"
,
"Kant"
,
"Nietzsche"
,
"Descartes"
};
for
(
size_t
i
=
0
;
i
<
5
;
++
i
)
{
spawn_in_group
<
philosopher
>
(
dinner_club
,
names
[
i
],
chopsticks
[
i
],
chopsticks
[(
i
+
1
)
%
chopsticks
.
size
()]);
spawn
<
philosopher
>
(
names
[
i
],
chopsticks
[
i
],
chopsticks
[(
i
+
1
)
%
5
]);
}
// tell all philosophers to start thinking
send
(
dinner_club
,
atom
(
"think"
));
// real philosophers are never done
await_all_others_done
();
shutdown
();
...
...
examples/remote_actors/distributed_
math_ac
tor.cpp
→
examples/remote_actors/distributed_
calcula
tor.cpp
View file @
f9b9aade
This diff is collapsed.
Click to expand it.
examples/remote_actors/group_chat.cpp
View file @
f9b9aade
...
...
@@ -29,7 +29,7 @@ istream& operator>>(istream& is, line& l) {
return
is
;
}
string
s_last_line
;
namespace
{
string
s_last_line
;
}
any_tuple
split_line
(
const
line
&
l
)
{
istringstream
strs
(
l
.
str
);
...
...
@@ -42,46 +42,32 @@ any_tuple split_line(const line& l) {
return
any_tuple
::
view
(
std
::
move
(
result
));
}
class
client
:
public
event_based_actor
{
public:
client
(
string
name
)
:
m_name
(
move
(
name
))
{
}
protected:
void
init
()
{
become
(
on
(
atom
(
"broadcast"
),
arg_match
)
>>
[
=
](
const
string
&
message
)
{
for
(
auto
&
dest
:
joined_groups
())
{
send
(
dest
,
m_name
+
": "
+
message
);
}
},
on
(
atom
(
"join"
),
arg_match
)
>>
[
=
](
const
group_ptr
&
what
)
{
for
(
auto
g
:
joined_groups
())
{
cout
<<
"*** leave "
<<
to_string
(
g
)
<<
endl
;
send
(
g
,
m_name
+
" has left the chatroom"
);
leave
(
g
);
}
cout
<<
"*** join "
<<
to_string
(
what
)
<<
endl
;
join
(
what
);
send
(
what
,
m_name
+
" has entered the chatroom"
);
},
on
<
string
>
()
>>
[
=
](
const
string
&
txt
)
{
// don't print own messages
if
(
last_sender
()
!=
this
)
cout
<<
txt
<<
endl
;
},
others
()
>>
[
=
]()
{
cout
<<
"unexpected: "
<<
to_string
(
last_dequeued
())
<<
endl
;
void
client
(
const
string
&
name
)
{
become
(
on
(
atom
(
"broadcast"
),
arg_match
)
>>
[
=
](
const
string
&
message
)
{
for
(
auto
&
dest
:
self
->
joined_groups
())
{
send
(
dest
,
name
+
": "
+
message
);
}
);
}
private:
string
m_name
;
};
},
on
(
atom
(
"join"
),
arg_match
)
>>
[
=
](
const
group_ptr
&
what
)
{
for
(
auto
g
:
self
->
joined_groups
())
{
cout
<<
"*** leave "
<<
to_string
(
g
)
<<
endl
;
send
(
g
,
name
+
" has left the chatroom"
);
self
->
leave
(
g
);
}
cout
<<
"*** join "
<<
to_string
(
what
)
<<
endl
;
self
->
join
(
what
);
send
(
what
,
name
+
" has entered the chatroom"
);
},
on
<
string
>
()
>>
[
=
](
const
string
&
txt
)
{
// don't print own messages
if
(
self
->
last_sender
()
!=
self
)
cout
<<
txt
<<
endl
;
},
others
()
>>
[
=
]()
{
cout
<<
"unexpected: "
<<
to_string
(
self
->
last_dequeued
())
<<
endl
;
}
);
}
int
main
(
int
argc
,
char
**
argv
)
{
...
...
@@ -105,7 +91,7 @@ int main(int argc, char** argv) {
}
cout
<<
"*** starting client, type '/help' for a list of commands"
<<
endl
;
auto
client_actor
=
spawn
<
client
>
(
name
);
auto
client_actor
=
spawn
(
client
,
name
);
// evaluate group parameters
if
(
!
group_id
.
empty
())
{
...
...
@@ -156,7 +142,7 @@ int main(int argc, char** argv) {
}
);
// force actor to quit
quit_actor
(
client_actor
,
exit_reason
::
user_defined
);
send_exit
(
client_actor
,
exit_reason
::
user_defined
);
await_all_others_done
();
shutdown
();
return
0
;
...
...
examples/remote_actors/group_server.cpp
View file @
f9b9aade
...
...
@@ -30,7 +30,8 @@ int main(int argc, char** argv) {
}
if
(
!
args_valid
)
{
// print_desc(&desc) returns a function printing the stored help text
print_desc
(
&
desc
)();
auto
desc_printer
=
print_desc
(
&
desc
);
desc_printer
();
return
1
;
}
try
{
...
...
examples/type_system/announce_1.cpp
View file @
f9b9aade
...
...
@@ -41,6 +41,38 @@ bool operator==( const foo2& lhs, const foo2& rhs ) {
return
lhs
.
a
==
rhs
.
a
&&
lhs
.
b
==
rhs
.
b
;
}
// receives `remaining` messages
void
testee
(
size_t
remaining
)
{
auto
set_next_behavior
=
[
=
]
{
if
(
remaining
>
1
)
testee
(
remaining
-
1
);
else
self
->
quit
();
};
become
(
// note: we sent a foo_pair2, but match on foo_pair
// that's safe because both are aliases for std::pair<int,int>
on
<
foo_pair
>
()
>>
[
=
](
const
foo_pair
&
val
)
{
cout
<<
"foo_pair("
<<
val
.
first
<<
","
<<
val
.
second
<<
")"
<<
endl
;
set_next_behavior
();
},
on
<
foo
>
()
>>
[
=
](
const
foo
&
val
)
{
cout
<<
"foo({"
;
auto
i
=
val
.
a
.
begin
();
auto
end
=
val
.
a
.
end
();
if
(
i
!=
end
)
{
cout
<<
*
i
;
while
(
++
i
!=
end
)
{
cout
<<
","
<<
*
i
;
}
}
cout
<<
"},"
<<
val
.
b
<<
")"
<<
endl
;
set_next_behavior
();
}
);
}
int
main
(
int
,
char
**
)
{
// announces foo to the libcppa type system;
...
...
@@ -75,41 +107,18 @@ int main(int, char**) {
// std::pair<int,int> is already announced
assert
(
announce
<
foo_pair2
>
(
&
foo_pair2
::
first
,
&
foo_pair2
::
second
)
==
false
);
// send a foo to ourselves
send
(
self
,
foo
{
std
::
vector
<
int
>
{
1
,
2
,
3
,
4
},
5
});
// send a foo_pair2 to ourselves
send
(
self
,
foo_pair2
{
3
,
4
});
// quits the program
send
(
self
,
atom
(
"done"
));
// libcppa returns the same uniform_type_info
// instance for foo_pair and foo_pair2
assert
(
uniform_typeid
<
foo_pair
>
()
==
uniform_typeid
<
foo_pair2
>
());
// receive two messages
int
i
=
0
;
receive_for
(
i
,
2
)
(
// note: we sent a foo_pair2, but match on foo_pair
// that's safe because both are aliases for std::pair<int,int>
on
<
foo_pair
>
()
>>
[](
const
foo_pair
&
val
)
{
cout
<<
"foo_pair("
<<
val
.
first
<<
","
<<
val
.
second
<<
")"
<<
endl
;
},
on
<
foo
>
()
>>
[](
const
foo
&
val
)
{
cout
<<
"foo({"
;
auto
i
=
val
.
a
.
begin
();
auto
end
=
val
.
a
.
end
();
if
(
i
!=
end
)
{
cout
<<
*
i
;
while
(
++
i
!=
end
)
{
cout
<<
","
<<
*
i
;
}
}
cout
<<
"},"
<<
val
.
b
<<
")"
<<
endl
;
}
);
// spawn a testee that receives two messages
auto
t
=
spawn
(
testee
,
2
);
// send t a foo
send
(
t
,
foo
{
std
::
vector
<
int
>
{
1
,
2
,
3
,
4
},
5
});
// send t a foo_pair2
send
(
t
,
foo_pair2
{
3
,
4
});
await_all_others_done
();
shutdown
();
return
0
;
}
...
...
examples/type_system/announce_2.cpp
View file @
f9b9aade
...
...
@@ -35,29 +35,32 @@ class foo {
};
// announce requires foo to
have the equal operator implemented
// announce requires foo to
be comparable
bool
operator
==
(
const
foo
&
lhs
,
const
foo
&
rhs
)
{
return
lhs
.
a
()
==
rhs
.
a
()
&&
lhs
.
b
()
==
rhs
.
b
();
}
int
main
(
int
,
char
**
)
{
// if a class uses getter and setter member functions,
// we pass those to the announce function as { getter, setter } pairs.
announce
<
foo
>
(
make_pair
(
&
foo
::
a
,
&
foo
::
set_a
),
make_pair
(
&
foo
::
b
,
&
foo
::
set_b
));
// send a foo to ourselves ...
send
(
self
,
foo
{
1
,
2
});
receive
(
// ... and receive it
void
testee
()
{
become
(
on
<
foo
>
()
>>
[](
const
foo
&
val
)
{
c
out
<<
"foo("
a
out
<<
"foo("
<<
val
.
a
()
<<
","
<<
val
.
b
()
<<
")"
<<
endl
;
self
->
quit
();
}
);
}
int
main
(
int
,
char
**
)
{
// if a class uses getter and setter member functions,
// we pass those to the announce function as { getter, setter } pairs.
announce
<
foo
>
(
make_pair
(
&
foo
::
a
,
&
foo
::
set_a
),
make_pair
(
&
foo
::
b
,
&
foo
::
set_b
));
auto
t
=
spawn
(
testee
);
send
(
t
,
foo
{
1
,
2
});
await_all_others_done
();
shutdown
();
return
0
;
}
...
...
examples/type_system/announce_3.cpp
View file @
f9b9aade
...
...
@@ -46,6 +46,18 @@ typedef int (foo::*foo_getter)() const;
// a member function pointer to set an attribute of foo
typedef
void
(
foo
::*
foo_setter
)(
int
);
void
testee
()
{
become
(
on
<
foo
>
()
>>
[](
const
foo
&
val
)
{
aout
<<
"foo("
<<
val
.
a
()
<<
","
<<
val
.
b
()
<<
")"
<<
endl
;
self
->
quit
();
}
);
}
int
main
(
int
,
char
**
)
{
// since the member function "a" is ambiguous, the compiler
// also needs a type to select the correct overload
...
...
@@ -65,17 +77,9 @@ int main(int, char**) {
make_pair
(
static_cast
<
foo_getter
>
(
&
foo
::
b
),
static_cast
<
foo_setter
>
(
&
foo
::
b
)));
// send a foo to ourselves ...
send
(
self
,
foo
{
1
,
2
});
receive
(
// ... and receive it
on
<
foo
>
()
>>
[](
const
foo
&
val
)
{
cout
<<
"foo("
<<
val
.
a
()
<<
","
<<
val
.
b
()
<<
")"
<<
endl
;
}
);
// spawn a new testee and send it a foo
send
(
spawn
(
testee
),
foo
{
1
,
2
});
await_all_others_done
();
shutdown
();
return
0
;
}
...
...
examples/type_system/announce_4.cpp
View file @
f9b9aade
...
...
@@ -78,6 +78,29 @@ bool operator==(const baz& lhs, const baz& rhs) {
&&
lhs
.
b
==
rhs
.
b
;
}
// receives `remaining` messages
void
testee
(
size_t
remaining
)
{
auto
set_next_behavior
=
[
=
]
{
if
(
remaining
>
1
)
testee
(
remaining
-
1
);
else
self
->
quit
();
};
become
(
on
<
bar
>
()
>>
[
=
](
const
bar
&
val
)
{
aout
<<
"bar(foo("
<<
val
.
f
.
a
()
<<
","
<<
val
.
f
.
b
()
<<
"),"
<<
val
.
i
<<
")"
<<
endl
;
set_next_behavior
();
},
on
<
baz
>
()
>>
[
=
](
const
baz
&
val
)
{
// prints: baz ( foo ( 1, 2 ), bar ( foo ( 3, 4 ), 5 ) )
aout
<<
to_string
(
object
::
from
(
val
))
<<
endl
;
set_next_behavior
();
}
);
}
int
main
(
int
,
char
**
)
{
// bar has a non-trivial data member f, thus, we have to told
// announce how to serialize/deserialize this member;
...
...
@@ -102,26 +125,11 @@ int main(int, char**) {
make_pair
(
&
foo
::
b
,
&
foo
::
set_b
)),
&
bar
::
i
));
// send a bar to ourselves
send
(
self
,
bar
{
foo
{
1
,
2
},
3
});
// send a baz to ourselves
send
(
self
,
baz
{
foo
{
1
,
2
},
bar
{
foo
{
3
,
4
},
5
}});
// receive two messages
int
i
=
0
;
receive_for
(
i
,
2
)
(
on
<
bar
>
()
>>
[](
const
bar
&
val
)
{
cout
<<
"bar(foo("
<<
val
.
f
.
a
()
<<
","
<<
val
.
f
.
b
()
<<
"),"
<<
val
.
i
<<
")"
<<
endl
;
},
on
<
baz
>
()
>>
[](
const
baz
&
val
)
{
// prints: baz ( foo ( 1, 2 ), bar ( foo ( 3, 4 ), 5 ) )
cout
<<
to_string
(
object
::
from
(
val
))
<<
endl
;
}
);
// spawn a testee that receives two messages
auto
t
=
spawn
(
testee
,
2
);
send
(
t
,
bar
{
foo
{
1
,
2
},
3
});
send
(
t
,
baz
{
foo
{
1
,
2
},
bar
{
foo
{
3
,
4
},
5
}});
await_all_others_done
();
shutdown
();
return
0
;
}
...
...
examples/type_system/announce_5.cpp
View file @
f9b9aade
...
...
@@ -39,18 +39,18 @@ struct tree_node {
void
print
()
const
{
// format is: value { children0, children1, ..., childrenN }
// e.g., 10 { 20 { 21, 22 }, 30 }
c
out
<<
value
;
a
out
<<
value
;
if
(
children
.
empty
()
==
false
)
{
c
out
<<
" { "
;
a
out
<<
" { "
;
auto
begin
=
children
.
begin
();
auto
end
=
children
.
end
();
for
(
auto
i
=
begin
;
i
!=
end
;
++
i
)
{
if
(
i
!=
begin
)
{
c
out
<<
", "
;
a
out
<<
", "
;
}
i
->
print
();
}
c
out
<<
" } "
;
a
out
<<
" } "
;
}
}
...
...
@@ -62,9 +62,9 @@ struct tree {
// print tree to stdout
void
print
()
const
{
c
out
<<
"tree::print: "
;
a
out
<<
"tree::print: "
;
root
.
print
();
c
out
<<
endl
;
a
out
<<
endl
;
}
};
...
...
@@ -138,17 +138,53 @@ class tree_type_info : public util::abstract_uniform_type_info<tree> {
};
typedef
std
::
vector
<
tree
>
tree_vector
;
// receives `remaining` messages
void
testee
(
size_t
remaining
)
{
auto
set_next_behavior
=
[
=
]
{
if
(
remaining
>
1
)
testee
(
remaining
-
1
);
else
self
->
quit
();
};
become
(
on_arg_match
>>
[
=
](
const
tree
&
tmsg
)
{
// prints the tree in its serialized format:
// @<> ( { tree ( 0, { 10, { 11, { }, 12, { }, 13, { } }, 20, { 21, { }, 22, { } } } ) } )
aout
<<
"to_string(self->last_dequeued()): "
<<
to_string
(
self
->
last_dequeued
())
<<
endl
;
// prints the tree using the print member function:
// 0 { 10 { 11, 12, 13 } , 20 { 21, 22 } }
tmsg
.
print
();
set_next_behavior
();
},
on_arg_match
>>
[
=
](
const
tree_vector
&
trees
)
{
// prints "received 2 trees"
aout
<<
"received "
<<
trees
.
size
()
<<
" trees"
<<
endl
;
// prints:
// @<> ( {
// std::vector<tree,std::allocator<tree>> ( {
// tree ( 0, { 10, { 11, { }, 12, { }, 13, { } }, 20, { 21, { }, 22, { } } } ),
// tree ( 0, { 10, { 11, { }, 12, { }, 13, { } }, 20, { 21, { }, 22, { } } } )
// )
// } )
aout
<<
"to_string: "
<<
to_string
(
self
->
last_dequeued
())
<<
endl
;
set_next_behavior
();
}
);
}
int
main
()
{
// the tree_type_info is owned by libcppa after this function call
announce
(
typeid
(
tree
),
new
tree_type_info
);
tree
t
;
// create a tree and fill it with some data
tree
t
0
;
// create a tree and fill it with some data
t
.
root
.
add_child
(
10
);
t
.
root
.
children
.
back
().
add_child
(
11
).
add_child
(
12
).
add_child
(
13
);
t
0
.
root
.
add_child
(
10
);
t
0
.
root
.
children
.
back
().
add_child
(
11
).
add_child
(
12
).
add_child
(
13
);
t
.
root
.
add_child
(
20
);
t
.
root
.
children
.
back
().
add_child
(
21
).
add_child
(
22
);
t
0
.
root
.
add_child
(
20
);
t
0
.
root
.
children
.
back
().
add_child
(
21
).
add_child
(
22
);
/*
tree t is now:
...
...
@@ -162,44 +198,20 @@ int main() {
11 12 13 21 22
*/
// s
end a tree to ourselves ...
send
(
self
,
t
);
// s
pawn a testee that receives two messages
auto
t
=
spawn
(
testee
,
2
);
// send a vector of trees to ourselves
typedef
std
::
vector
<
tree
>
tree_vector
;
// send a tree
send
(
t
,
t0
);
// send a vector of trees
announce
<
tree_vector
>
();
tree_vector
tvec
;
tvec
.
push_back
(
t
);
tvec
.
push_back
(
t
);
send
(
self
,
tvec
);
// receive both messages
int
i
=
0
;
receive_for
(
i
,
2
)
(
// ... and receive it
on
<
tree
>
()
>>
[](
const
tree
&
tmsg
)
{
// prints the tree in its serialized format:
// @<> ( { tree ( 0, { 10, { 11, { }, 12, { }, 13, { } }, 20, { 21, { }, 22, { } } } ) } )
cout
<<
"to_string(self->last_dequeued()): "
<<
to_string
(
self
->
last_dequeued
())
<<
endl
;
// prints the tree using the print member function:
// 0 { 10 { 11, 12, 13 } , 20 { 21, 22 } }
tmsg
.
print
();
},
on
<
tree_vector
>
()
>>
[](
const
tree_vector
&
trees
)
{
// prints "received 2 trees"
cout
<<
"received "
<<
trees
.
size
()
<<
" trees"
<<
endl
;
// prints:
// @<> ( {
// std::vector<tree,std::allocator<tree>> ( {
// tree ( 0, { 10, { 11, { }, 12, { }, 13, { } }, 20, { 21, { }, 22, { } } } ),
// tree ( 0, { 10, { 11, { }, 12, { }, 13, { } }, 20, { 21, { }, 22, { } } } )
// )
// } )
cout
<<
"to_string: "
<<
to_string
(
self
->
last_dequeued
())
<<
endl
;
}
);
tvec
.
push_back
(
t0
);
tvec
.
push_back
(
t0
);
send
(
t
,
tvec
);
await_all_others_done
();
shutdown
();
return
0
;
}
src/scheduled_actor.cpp
View file @
f9b9aade
...
...
@@ -43,6 +43,7 @@ scheduled_actor::scheduled_actor(actor_state init_state, bool chained_send)
void
scheduled_actor
::
attach_to_scheduler
(
scheduler
*
sched
,
bool
hidden
)
{
CPPA_REQUIRE
(
sched
!=
nullptr
);
m_scheduler
=
sched
;
m_hidden
=
hidden
;
// init is called by the spawning actor, manipulate self to
// point to this actor
...
...
@@ -52,7 +53,6 @@ void scheduled_actor::attach_to_scheduler(scheduler* sched, bool hidden) {
catch
(...)
{
}
// make sure scheduler is not set until init() is done
std
::
atomic_thread_fence
(
std
::
memory_order_seq_cst
);
m_scheduler
=
sched
;
}
bool
scheduled_actor
::
initialized
()
const
{
...
...
@@ -95,7 +95,7 @@ bool scheduled_actor::enqueue(actor_state next_state,
mailbox_element
*
e
)
{
CPPA_REQUIRE
(
next_state
==
actor_state
::
ready
||
next_state
==
actor_state
::
pending
);
CPPA_REQUIRE
(
e
->
marked
==
false
);
CPPA_REQUIRE
(
e
!=
nullptr
&&
e
->
marked
==
false
);
switch
(
m_mailbox
.
enqueue
(
e
))
{
case
intrusive
:
:
first_enqueued
:
{
auto
state
=
m_state
.
load
();
...
...
src/self.cpp
View file @
f9b9aade
...
...
@@ -96,14 +96,6 @@ void tss_reset(local_actor* ptr, bool inc_ref_count = true) {
}
// namespace <anonymous>
bool
operator
==
(
const
actor_ptr
&
lhs
,
const
self_type
&
rhs
)
{
return
lhs
.
get
()
==
rhs
.
get
();
}
bool
operator
!=
(
const
self_type
&
lhs
,
const
actor_ptr
&
rhs
)
{
return
lhs
.
get
()
!=
rhs
.
get
();
}
void
self_type
::
cleanup_fun
(
cppa
::
local_actor
*
what
)
{
if
(
what
)
{
auto
ptr
=
dynamic_cast
<
thread_mapped_actor
*>
(
what
);
...
...
@@ -139,4 +131,20 @@ self_type::pointer self_type::release_impl() {
return
tss_release
();
}
bool
operator
==
(
const
actor_ptr
&
lhs
,
const
self_type
&
rhs
)
{
return
lhs
.
get
()
==
rhs
.
get
();
}
bool
operator
==
(
const
self_type
&
lhs
,
const
actor_ptr
&
rhs
)
{
return
rhs
==
lhs
;
}
bool
operator
!=
(
const
actor_ptr
&
lhs
,
const
self_type
&
rhs
)
{
return
!
(
lhs
==
rhs
);
}
bool
operator
!=
(
const
self_type
&
lhs
,
const
actor_ptr
&
rhs
)
{
return
!
(
rhs
==
lhs
);
}
}
// namespace cppa
unit_testing/ping_pong.cpp
View file @
f9b9aade
...
...
@@ -22,7 +22,7 @@ behavior ping_behavior(size_t num_pings) {
CPPA_LOGF_ERROR_IF
(
!
self
->
last_sender
(),
"last_sender() == nullptr"
);
//cout << to_string(self->last_dequeued()) << endl;
if
(
++
s_pongs
>=
num_pings
)
{
quit_actor
(
self
->
last_sender
(),
exit_reason
::
user_defined
);
send_exit
(
self
->
last_sender
(),
exit_reason
::
user_defined
);
self
->
quit
();
}
else
reply
(
atom
(
"ping"
),
value
);
...
...
unit_testing/test_spawn.cpp
View file @
f9b9aade
...
...
@@ -202,7 +202,7 @@ string behavior_test(actor_ptr et) {
throw
runtime_error
(
testee_name
+
" does not reply"
);
}
);
quit_actor
(
et
,
exit_reason
::
user_defined
);
send_exit
(
et
,
exit_reason
::
user_defined
);
await_all_others_done
();
return
result
;
}
...
...
@@ -309,7 +309,7 @@ int main() {
on
(
"hello mirror"
)
>>
CPPA_CHECKPOINT_CB
(),
others
()
>>
CPPA_UNEXPECTED_MSG_CB
()
);
quit_actor
(
mirror
,
exit_reason
::
user_defined
);
send_exit
(
mirror
,
exit_reason
::
user_defined
);
receive
(
on
(
atom
(
"DOWN"
),
exit_reason
::
user_defined
)
>>
CPPA_CHECKPOINT_CB
(),
others
()
>>
CPPA_UNEXPECTED_MSG_CB
()
...
...
@@ -325,7 +325,7 @@ int main() {
on
(
"hello mirror"
)
>>
CPPA_CHECKPOINT_CB
(),
others
()
>>
CPPA_UNEXPECTED_MSG_CB
()
);
quit_actor
(
mirror
,
exit_reason
::
user_defined
);
send_exit
(
mirror
,
exit_reason
::
user_defined
);
receive
(
on
(
atom
(
"DOWN"
),
exit_reason
::
user_defined
)
>>
CPPA_CHECKPOINT_CB
(),
others
()
>>
CPPA_UNEXPECTED_MSG_CB
()
...
...
@@ -429,7 +429,7 @@ int main() {
CPPA_CHECK
(
values
==
expected
);
}
// terminate st
quit_actor
(
st
,
exit_reason
::
user_defined
);
send_exit
(
st
,
exit_reason
::
user_defined
);
await_all_others_done
();
CPPA_CHECKPOINT
();
...
...
@@ -625,8 +625,8 @@ int main() {
CPPA_CHECK_EQUAL
(
name
,
"bob"
);
}
);
quit_actor
(
a1
,
exit_reason
::
user_defined
);
quit_actor
(
a2
,
exit_reason
::
user_defined
);
send_exit
(
a1
,
exit_reason
::
user_defined
);
send_exit
(
a2
,
exit_reason
::
user_defined
);
await_all_others_done
();
factory
::
event_based
([](
int
*
i
)
{
...
...
@@ -652,7 +652,7 @@ int main() {
}
become
(
others
()
>>
CPPA_UNEXPECTED_MSG_CB
());
});
quit_actor
(
legion
,
exit_reason
::
user_defined
);
send_exit
(
legion
,
exit_reason
::
user_defined
);
await_all_others_done
();
CPPA_CHECKPOINT
();
self
->
trap_exit
(
true
);
...
...
unit_testing/test_sync_send.cpp
View file @
f9b9aade
...
...
@@ -215,7 +215,7 @@ int main() {
.
continue_with
([
&
]
{
continuation_called
=
true
;
});
self
->
exec_behavior_stack
();
CPPA_CHECK_EQUAL
(
continuation_called
,
true
);
quit_actor
(
mirror
,
exit_reason
::
user_defined
);
send_exit
(
mirror
,
exit_reason
::
user_defined
);
await_all_others_done
();
CPPA_CHECKPOINT
();
auto
await_success_message
=
[
&
]
{
...
...
@@ -271,7 +271,7 @@ int main() {
sync_send
(
c
,
atom
(
"gogo"
)).
then
(
CPPA_CHECKPOINT_CB
())
.
continue_with
(
CPPA_CHECKPOINT_CB
());
self
->
exec_behavior_stack
();
quit_actor
(
c
,
exit_reason
::
user_defined
);
send_exit
(
c
,
exit_reason
::
user_defined
);
await_all_others_done
();
CPPA_CHECKPOINT
();
...
...
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