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
22d4342c
Commit
22d4342c
authored
Jun 21, 2012
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
maintenance
parent
c0705e59
Changes
11
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
266 additions
and
149 deletions
+266
-149
CMakeLists.txt
CMakeLists.txt
+0
-1
cppa.files
cppa.files
+0
-1
cppa/cppa.hpp
cppa/cppa.hpp
+38
-53
cppa/intrusive_ptr.hpp
cppa/intrusive_ptr.hpp
+12
-0
cppa/self.hpp
cppa/self.hpp
+52
-10
src/context_switching_actor.cpp
src/context_switching_actor.cpp
+15
-7
src/cppa.cpp
src/cppa.cpp
+0
-48
src/event_based_actor.cpp
src/event_based_actor.cpp
+3
-7
src/scheduled_actor.cpp
src/scheduled_actor.cpp
+8
-1
src/self.cpp
src/self.cpp
+23
-13
unit_testing/test__spawn.cpp
unit_testing/test__spawn.cpp
+115
-8
No files found.
CMakeLists.txt
View file @
22d4342c
...
@@ -21,7 +21,6 @@ set(LIBCPPA_SRC
...
@@ -21,7 +21,6 @@ set(LIBCPPA_SRC
src/binary_serializer.cpp
src/binary_serializer.cpp
src/channel.cpp
src/channel.cpp
src/thread_mapped_actor.cpp
src/thread_mapped_actor.cpp
src/cppa.cpp
src/demangle.cpp
src/demangle.cpp
src/deserializer.cpp
src/deserializer.cpp
src/duration.cpp
src/duration.cpp
...
...
cppa.files
View file @
22d4342c
...
@@ -202,7 +202,6 @@ src/binary_deserializer.cpp
...
@@ -202,7 +202,6 @@ src/binary_deserializer.cpp
src/binary_serializer.cpp
src/binary_serializer.cpp
src/channel.cpp
src/channel.cpp
src/thread_mapped_actor.cpp
src/thread_mapped_actor.cpp
src/cppa.cpp
src/demangle.cpp
src/demangle.cpp
src/deserializer.cpp
src/deserializer.cpp
src/duration.cpp
src/duration.cpp
...
...
cppa/cppa.hpp
View file @
22d4342c
...
@@ -535,78 +535,63 @@ channel_ptr& operator<<(channel_ptr& whom, const any_tuple& what);
...
@@ -535,78 +535,63 @@ channel_ptr& operator<<(channel_ptr& whom, const any_tuple& what);
#else
#else
template
<
class
C
,
typename
Arg0
,
typename
...
Args
>
namespace
detail
{
void
send
(
intrusive_ptr
<
C
>&
whom
,
const
Arg0
&
arg0
,
const
Args
&
...
args
)
{
static_assert
(
std
::
is_base_of
<
channel
,
C
>::
value
,
"C is not a channel"
);
if
(
whom
)
self
->
send_message
(
whom
.
get
(),
make_cow_tuple
(
arg0
,
args
...));
}
template
<
class
C
,
typename
Arg0
,
typename
...
Args
>
inline
void
send_impl
(
channel
*
whom
,
any_tuple
&&
what
)
{
void
send
(
intrusive_ptr
<
C
>&&
whom
,
const
Arg0
&
arg0
,
const
Args
&
...
args
)
{
if
(
whom
!=
nullptr
)
whom
->
enqueue
(
self
.
get
(),
std
::
move
(
what
));
static_assert
(
std
::
is_base_of
<
channel
,
C
>::
value
,
"C is not a channel"
);
intrusive_ptr
<
C
>
tmp
(
std
::
move
(
whom
));
send
(
tmp
,
arg0
,
args
...);
}
}
// matches "send(this, ...)" in event-based actors
template
<
typename
Arg0
,
typename
...
Args
>
template
<
typename
Arg0
,
typename
...
Args
>
inline
void
send
(
local_actor
*
whom
,
const
Arg0
&
arg0
,
const
Args
&
...
args
)
{
inline
void
send_tpl_impl
(
channel
*
whom
,
Arg0
&&
arg0
,
Args
&&
...
args
)
{
CPPA_REQUIRE
(
whom
!=
nullptr
);
if
(
whom
!=
nullptr
)
{
whom
->
enqueue
(
whom
,
make_cow_tuple
(
arg0
,
args
...));
whom
->
enqueue
(
self
.
get
(),
make_any_tuple
(
std
::
forward
<
Arg0
>
(
arg0
),
std
::
forward
<
Args
>
(
args
)...));
}
}
}
inline
void
send_impl
(
actor
*
whom
,
any_tuple
&&
what
)
{
if
(
whom
)
self
->
send_message
(
whom
,
std
::
move
(
what
));
}
// matches send(self, ...);
template
<
typename
Arg0
,
typename
...
Args
>
template
<
typename
Arg0
,
typename
...
Args
>
inline
void
send
(
const
self_type
&
,
const
Arg0
&
arg0
,
const
Args
&
...
args
)
{
inline
void
send_tpl_impl
(
actor
*
whom
,
Arg0
&&
arg0
,
Args
&&
...
args
)
{
send
(
static_cast
<
local_actor
*>
(
self
),
arg0
,
args
...);
if
(
whom
)
{
self
->
send_message
(
whom
,
make_any_tuple
(
std
::
forward
<
Arg0
>
(
arg0
),
std
::
forward
<
Args
>
(
args
)...));
}
}
}
}
// namespace detail
template
<
class
C
>
template
<
class
C
>
typename
std
::
enable_if
<
typename
std
::
enable_if
<
std
::
is_base_of
<
channel
,
C
>::
value
,
std
::
is_base_of
<
channel
,
C
>::
value
,
const
intrusive_ptr
<
C
>&
>::
type
intrusive_ptr
<
C
>&
operator
<<
(
const
intrusive_ptr
<
C
>&
whom
,
any_tuple
what
)
{
>::
type
detail
::
send_impl
(
whom
.
get
(),
std
::
move
(
what
));
operator
<<
(
intrusive_ptr
<
C
>&
whom
,
const
any_tuple
&
what
)
{
if
(
whom
)
self
->
send_message
(
whom
.
get
(),
what
);
return
whom
;
return
whom
;
}
}
template
<
class
C
>
inline
const
self_type
&
operator
<<
(
const
self_type
&
s
,
any_tuple
what
)
{
typename
std
::
enable_if
<
detail
::
send_impl
(
s
.
get
(),
std
::
move
(
what
));
std
::
is_base_of
<
channel
,
C
>::
value
,
return
s
;
intrusive_ptr
<
C
>
>::
type
operator
<<
(
intrusive_ptr
<
C
>&&
whom
,
const
any_tuple
&
what
)
{
intrusive_ptr
<
C
>
tmp
(
std
::
move
(
whom
));
tmp
<<
what
;
return
std
::
move
(
tmp
);
}
}
template
<
class
C
>
typename
std
::
enable_if
<
std
::
is_base_of
<
channel
,
C
>::
value
,
intrusive_ptr
<
C
>&
>::
type
operator
<<
(
intrusive_ptr
<
C
>&
whom
,
any_tuple
&&
what
)
{
if
(
whom
)
self
->
send_message
(
whom
.
get
(),
std
::
move
(
what
));
return
whom
;
}
template
<
class
C
>
template
<
class
C
,
typename
Arg0
,
typename
...
Args
>
typename
std
::
enable_if
<
inline
typename
std
::
enable_if
<
std
::
is_base_of
<
channel
,
C
>::
value
>::
type
std
::
is_base_of
<
channel
,
C
>::
value
,
send
(
const
intrusive_ptr
<
C
>&
whom
,
Arg0
&&
arg0
,
Args
&&
...
args
)
{
intrusive_ptr
<
C
>
detail
::
send_tpl_impl
(
whom
.
get
(),
>::
type
std
::
forward
<
Arg0
>
(
arg0
),
operator
<<
(
intrusive_ptr
<
C
>&&
whom
,
any_tuple
&&
what
)
{
std
::
forward
<
Args
>
(
args
)...);
intrusive_ptr
<
C
>
tmp
(
std
::
move
(
whom
));
tmp
<<
std
::
move
(
what
);
return
std
::
move
(
tmp
);
}
}
const
self_type
&
operator
<<
(
const
self_type
&
s
,
const
any_tuple
&
what
);
// matches "send(this, ...)" in event-based actors
template
<
typename
Arg0
,
typename
...
Args
>
const
self_type
&
operator
<<
(
const
self_type
&
s
,
any_tuple
&&
what
);
inline
void
send
(
local_actor
*
whom
,
Arg0
&&
arg0
,
Args
&&
...
args
)
{
detail
::
send_tpl_impl
(
whom
,
std
::
forward
<
Arg0
>
(
arg0
),
std
::
forward
<
Args
>
(
args
)...);
}
#endif // CPPA_DOCUMENTATION
#endif // CPPA_DOCUMENTATION
...
...
cppa/intrusive_ptr.hpp
View file @
22d4342c
...
@@ -92,12 +92,23 @@ class intrusive_ptr : util::comparable<intrusive_ptr<T> >,
...
@@ -92,12 +92,23 @@ class intrusive_ptr : util::comparable<intrusive_ptr<T> >,
std
::
swap
(
m_ptr
,
other
.
m_ptr
);
std
::
swap
(
m_ptr
,
other
.
m_ptr
);
}
}
/**
* @brief Returns the raw pointer without modifying reference count.
*/
pointer
release
()
{
pointer
release
()
{
auto
result
=
m_ptr
;
auto
result
=
m_ptr
;
m_ptr
=
nullptr
;
m_ptr
=
nullptr
;
return
result
;
return
result
;
}
}
/**
* @brief Sets this pointer to @p ptr without modifying reference count.
*/
void
adopt
(
pointer
ptr
)
{
reset
();
m_ptr
=
ptr
;
}
void
reset
(
pointer
new_value
=
nullptr
)
{
void
reset
(
pointer
new_value
=
nullptr
)
{
if
(
m_ptr
&&
!
m_ptr
->
deref
())
delete
m_ptr
;
if
(
m_ptr
&&
!
m_ptr
->
deref
())
delete
m_ptr
;
set_ptr
(
new_value
);
set_ptr
(
new_value
);
...
@@ -136,6 +147,7 @@ class intrusive_ptr : util::comparable<intrusive_ptr<T> >,
...
@@ -136,6 +147,7 @@ class intrusive_ptr : util::comparable<intrusive_ptr<T> >,
inline
pointer
operator
->
()
const
{
return
m_ptr
;
}
inline
pointer
operator
->
()
const
{
return
m_ptr
;
}
inline
reference
operator
*
()
const
{
return
*
m_ptr
;
}
inline
reference
operator
*
()
const
{
return
*
m_ptr
;
}
inline
bool
operator
!
()
const
{
return
m_ptr
==
nullptr
;
}
inline
explicit
operator
bool
()
const
{
return
m_ptr
!=
nullptr
;
}
inline
explicit
operator
bool
()
const
{
return
m_ptr
!=
nullptr
;
}
inline
ptrdiff_t
compare
(
const_pointer
ptr
)
const
{
inline
ptrdiff_t
compare
(
const_pointer
ptr
)
const
{
...
...
cppa/self.hpp
View file @
22d4342c
...
@@ -44,7 +44,7 @@ namespace cppa {
...
@@ -44,7 +44,7 @@ namespace cppa {
*/
*/
extern
local_actor
*
self
;
extern
local_actor
*
self
;
#else
#else
// CPPA_DOCUMENTATION
class
local_actor
;
class
local_actor
;
...
@@ -56,6 +56,8 @@ class self_type : public convertible<self_type, actor*> {
...
@@ -56,6 +56,8 @@ class self_type : public convertible<self_type, actor*> {
public:
public:
typedef
local_actor
*
pointer
;
constexpr
self_type
()
{
}
constexpr
self_type
()
{
}
// "inherited" from convertible<...>
// "inherited" from convertible<...>
...
@@ -63,38 +65,54 @@ class self_type : public convertible<self_type, actor*> {
...
@@ -63,38 +65,54 @@ class self_type : public convertible<self_type, actor*> {
return
convert_impl
();
return
convert_impl
();
}
}
inline
pointer
get
()
const
{
return
get_impl
();
}
// allow "self" wherever an local_actor or actor pointer is expected
// allow "self" wherever an local_actor or actor pointer is expected
inline
operator
local_actor
*
()
const
{
inline
operator
pointer
()
const
{
return
get_impl
();
return
get_impl
();
}
}
inline
local_actor
*
operator
->
()
const
{
inline
pointer
operator
->
()
const
{
return
get_impl
();
return
get_impl
();
}
}
// @pre get_unchecked() == nullptr
// @pre get_unchecked() == nullptr
inline
void
set
(
local_actor
*
ptr
)
const
{
inline
void
set
(
pointer
ptr
)
const
{
set_impl
(
ptr
);
set_impl
(
ptr
);
}
}
// @returns The current value without converting the calling context
// @returns The current value without converting the calling context
// to an actor on-the-fly.
// to an actor on-the-fly.
inline
local_actor
*
unchecked
()
const
{
inline
pointer
unchecked
()
const
{
return
get_unchecked_impl
();
return
get_unchecked_impl
();
}
}
static
void
cleanup_fun
(
local_actor
*
);
inline
pointer
release
()
const
{
return
release_impl
();
}
inline
void
adopt
(
pointer
ptr
)
const
{
adopt_impl
(
ptr
);
}
static
void
cleanup_fun
(
pointer
);
private:
private:
static
void
set_impl
(
local_actor
*
);
static
void
set_impl
(
pointer
);
static
local_actor
*
get_unchecked_impl
();
static
pointer
get_unchecked_impl
();
static
local_actor
*
get_impl
();
static
pointer
get_impl
();
static
actor
*
convert_impl
();
static
actor
*
convert_impl
();
static
pointer
release_impl
();
static
void
adopt_impl
(
pointer
);
};
};
/*
/*
...
@@ -103,7 +121,31 @@ class self_type : public convertible<self_type, actor*> {
...
@@ -103,7 +121,31 @@ class self_type : public convertible<self_type, actor*> {
*/
*/
constexpr
self_type
self
;
constexpr
self_type
self
;
#endif
class
scoped_self_setter
{
scoped_self_setter
(
const
scoped_self_setter
&
)
=
delete
;
scoped_self_setter
&
operator
=
(
const
scoped_self_setter
&
)
=
delete
;
public:
inline
scoped_self_setter
(
local_actor
*
new_value
)
{
m_original_value
=
self
.
release
();
self
.
adopt
(
new_value
);
}
inline
~
scoped_self_setter
()
{
// restore self
static_cast
<
void
>
(
self
.
release
());
self
.
adopt
(
m_original_value
);
}
private:
local_actor
*
m_original_value
;
};
#endif // CPPA_DOCUMENTATION
}
// namespace cppa
}
// namespace cppa
...
...
src/context_switching_actor.cpp
View file @
22d4342c
...
@@ -47,7 +47,12 @@ context_switching_actor::context_switching_actor(std::function<void()> fun)
...
@@ -47,7 +47,12 @@ context_switching_actor::context_switching_actor(std::function<void()> fun)
}
}
void
context_switching_actor
::
run
()
{
void
context_switching_actor
::
run
()
{
if
(
m_behavior
)
m_behavior
();
if
(
m_bhvr_stack_ptr
)
{
m_bhvr_stack_ptr
->
exec
();
}
else
if
(
m_behavior
)
{
m_behavior
();
}
}
}
void
context_switching_actor
::
trampoline
(
void
*
this_ptr
)
{
void
context_switching_actor
::
trampoline
(
void
*
this_ptr
)
{
...
@@ -98,7 +103,7 @@ void context_switching_actor::dequeue(behavior& bhvr) {
...
@@ -98,7 +103,7 @@ void context_switching_actor::dequeue(behavior& bhvr) {
}
}
else
if
(
m_recv_policy
.
invoke_from_cache
(
this
,
bhvr
)
==
false
)
{
else
if
(
m_recv_policy
.
invoke_from_cache
(
this
,
bhvr
)
==
false
)
{
if
(
bhvr
.
timeout
().
is_zero
())
{
if
(
bhvr
.
timeout
().
is_zero
())
{
for
(
auto
e
=
m_mailbox
.
try_pop
();
e
!=
0
;
e
=
m_mailbox
.
try_pop
())
{
for
(
auto
e
=
m_mailbox
.
try_pop
();
e
!=
0
;
e
=
m_mailbox
.
try_pop
()){
CPPA_REQUIRE
(
e
->
marked
==
false
);
CPPA_REQUIRE
(
e
->
marked
==
false
);
if
(
m_recv_policy
.
invoke
(
this
,
e
,
bhvr
))
return
;
if
(
m_recv_policy
.
invoke
(
this
,
e
,
bhvr
))
return
;
}
}
...
@@ -106,14 +111,14 @@ void context_switching_actor::dequeue(behavior& bhvr) {
...
@@ -106,14 +111,14 @@ void context_switching_actor::dequeue(behavior& bhvr) {
}
}
else
{
else
{
request_timeout
(
bhvr
.
timeout
());
request_timeout
(
bhvr
.
timeout
());
while
(
m_recv_policy
.
invoke
(
this
,
receive_node
(),
bhvr
)
==
false
)
{
}
while
(
m_recv_policy
.
invoke
(
this
,
receive_node
(),
bhvr
)
==
false
)
{}
}
}
}
}
}
}
resume_result
context_switching_actor
::
resume
(
util
::
fiber
*
from
)
{
resume_result
context_switching_actor
::
resume
(
util
::
fiber
*
from
)
{
using
namespace
detail
;
using
namespace
detail
;
s
elf
.
set
(
this
)
;
s
coped_self_setter
sss
{
this
}
;
for
(;;)
{
for
(;;)
{
switch
(
call
(
&
m_fiber
,
from
))
{
switch
(
call
(
&
m_fiber
,
from
))
{
case
yield_state
:
:
done
:
{
case
yield_state
:
:
done
:
{
...
@@ -149,7 +154,7 @@ void context_switching_actor::unbecome() {
...
@@ -149,7 +154,7 @@ void context_switching_actor::unbecome() {
if
(
m_bhvr_stack_ptr
)
{
if
(
m_bhvr_stack_ptr
)
{
m_bhvr_stack_ptr
->
pop_back
();
m_bhvr_stack_ptr
->
pop_back
();
}
}
else
{
else
if
(
m_scheduler
!=
nullptr
)
{
quit
();
quit
();
}
}
}
}
...
@@ -161,9 +166,12 @@ void context_switching_actor::do_become(behavior* bhvr, bool ownership, bool dis
...
@@ -161,9 +166,12 @@ void context_switching_actor::do_become(behavior* bhvr, bool ownership, bool dis
}
}
else
{
else
{
m_bhvr_stack_ptr
.
reset
(
new
detail
::
behavior_stack
);
m_bhvr_stack_ptr
.
reset
(
new
detail
::
behavior_stack
);
// scheduler == nullptr if and only if become() is called inside init()
if
(
m_scheduler
!=
nullptr
)
{
m_bhvr_stack_ptr
->
exec
();
m_bhvr_stack_ptr
->
exec
();
quit
();
quit
();
}
}
}
}
}
...
...
src/cppa.cpp
deleted
100644 → 0
View file @
c0705e59
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \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/cppa.hpp"
#include "cppa/local_actor.hpp"
namespace
cppa
{
const
self_type
&
operator
<<
(
const
self_type
&
s
,
const
any_tuple
&
what
)
{
local_actor
*
sptr
=
s
;
sptr
->
enqueue
(
sptr
,
what
);
return
s
;
}
const
self_type
&
operator
<<
(
const
self_type
&
s
,
any_tuple
&&
what
)
{
local_actor
*
sptr
=
s
;
sptr
->
enqueue
(
sptr
,
std
::
move
(
what
));
return
s
;
}
}
// namespace cppa
src/event_based_actor.cpp
View file @
22d4342c
...
@@ -49,12 +49,12 @@ void event_based_actor::dequeue(partial_function&) {
...
@@ -49,12 +49,12 @@ void event_based_actor::dequeue(partial_function&) {
}
}
resume_result
event_based_actor
::
resume
(
util
::
fiber
*
)
{
resume_result
event_based_actor
::
resume
(
util
::
fiber
*
)
{
scoped_self_setter
sss
{
this
};
auto
done_cb
=
[
&
]()
{
auto
done_cb
=
[
&
]()
{
m_state
.
store
(
abstract_scheduled_actor
::
done
);
m_state
.
store
(
abstract_scheduled_actor
::
done
);
m_bhvr_stack
.
clear
();
m_bhvr_stack
.
clear
();
on_exit
();
on_exit
();
};
};
self
.
set
(
this
);
try
{
try
{
detail
::
recursive_queue_node
*
e
;
detail
::
recursive_queue_node
*
e
;
for
(;;)
{
for
(;;)
{
...
@@ -88,12 +88,8 @@ resume_result event_based_actor::resume(util::fiber*) {
...
@@ -88,12 +88,8 @@ resume_result event_based_actor::resume(util::fiber*) {
}
}
}
}
}
}
catch
(
actor_exited
&
what
)
{
catch
(
actor_exited
&
what
)
{
cleanup
(
what
.
reason
());
}
cleanup
(
what
.
reason
());
catch
(...)
{
cleanup
(
exit_reason
::
unhandled_exception
);
}
}
catch
(...)
{
cleanup
(
exit_reason
::
unhandled_exception
);
}
done_cb
();
done_cb
();
return
resume_result
::
actor_done
;
return
resume_result
::
actor_done
;
}
}
...
...
src/scheduled_actor.cpp
View file @
22d4342c
...
@@ -42,8 +42,15 @@ void scheduled_actor::init() { }
...
@@ -42,8 +42,15 @@ void scheduled_actor::init() { }
scheduled_actor
*
scheduled_actor
::
attach_to_scheduler
(
scheduler
*
sched
)
{
scheduled_actor
*
scheduled_actor
::
attach_to_scheduler
(
scheduler
*
sched
)
{
CPPA_REQUIRE
(
sched
!=
nullptr
);
CPPA_REQUIRE
(
sched
!=
nullptr
);
// init is called by the spawning actor, manipulate self to
// point to this actor
scoped_self_setter
sss
{
this
};
// initialize this actor
try
{
init
();
}
catch
(...)
{
}
// make sure scheduler is not set until init() is done
std
::
atomic_thread_fence
(
std
::
memory_order_seq_cst
);
m_scheduler
=
sched
;
m_scheduler
=
sched
;
init
();
return
this
;
return
this
;
}
}
...
...
src/self.cpp
View file @
22d4342c
...
@@ -40,33 +40,35 @@
...
@@ -40,33 +40,35 @@
namespace
{
namespace
{
boost
::
thread_specific_ptr
<
cppa
::
local_actor
>
t_this_
context
(
&
cppa
::
self_type
::
cleanup_fun
);
boost
::
thread_specific_ptr
<
cppa
::
local_actor
>
t_this_
actor
(
&
cppa
::
self_type
::
cleanup_fun
);
}
// namespace <anonymous>
}
// namespace <anonymous>
namespace
cppa
{
namespace
cppa
{
void
self_type
::
cleanup_fun
(
cppa
::
local_actor
*
what
)
{
void
self_type
::
cleanup_fun
(
cppa
::
local_actor
*
what
)
{
if
(
what
)
{
auto
ptr
=
dynamic_cast
<
thread_mapped_actor
*>
(
what
);
auto
ptr
=
dynamic_cast
<
thread_mapped_actor
*>
(
what
);
if
(
ptr
)
{
if
(
ptr
)
{
// make sure "unspawned" actors quit properly
// make sure "unspawned" actors quit properly
ptr
->
cleanup
(
cppa
::
exit_reason
::
normal
);
ptr
->
cleanup
(
cppa
::
exit_reason
::
normal
);
}
}
if
(
what
&&
!
what
->
deref
())
delete
what
;
if
(
what
->
deref
()
==
false
)
delete
what
;
}
}
}
void
self_type
::
set_impl
(
local_actor
*
ptr
)
{
void
self_type
::
set_impl
(
self_type
::
pointer
ptr
)
{
if
(
ptr
)
ptr
->
ref
();
if
(
ptr
)
ptr
->
ref
();
t_this_
context
.
reset
(
ptr
);
t_this_
actor
.
reset
(
ptr
);
}
}
local_actor
*
self_type
::
get_impl
()
{
self_type
::
pointer
self_type
::
get_impl
()
{
auto
result
=
t_this_
context
.
get
();
auto
result
=
t_this_
actor
.
get
();
if
(
result
==
nullptr
)
{
if
(
result
==
nullptr
)
{
result
=
new
thread_mapped_actor
;
result
=
new
thread_mapped_actor
;
result
->
ref
();
result
->
ref
();
get_scheduler
()
->
register_converted_context
(
result
);
get_scheduler
()
->
register_converted_context
(
result
);
t_this_
context
.
reset
(
result
);
t_this_
actor
.
reset
(
result
);
}
}
return
result
;
return
result
;
}
}
...
@@ -75,8 +77,16 @@ actor* self_type::convert_impl() {
...
@@ -75,8 +77,16 @@ actor* self_type::convert_impl() {
return
get_impl
();
return
get_impl
();
}
}
local_actor
*
self_type
::
get_unchecked_impl
()
{
self_type
::
pointer
self_type
::
get_unchecked_impl
()
{
return
t_this_context
.
get
();
return
t_this_actor
.
get
();
}
void
self_type
::
adopt_impl
(
self_type
::
pointer
ptr
)
{
t_this_actor
.
reset
(
ptr
);
}
self_type
::
pointer
self_type
::
release_impl
()
{
return
t_this_actor
.
release
();
}
}
}
// namespace cppa
}
// namespace cppa
unit_testing/test__spawn.cpp
View file @
22d4342c
//#define CPPA_VERBOSE_CHECK
#include <stack>
#include <stack>
#include <chrono>
#include <chrono>
#include <iostream>
#include <iostream>
...
@@ -14,6 +16,7 @@
...
@@ -14,6 +16,7 @@
#include "cppa/to_string.hpp"
#include "cppa/to_string.hpp"
#include "cppa/exit_reason.hpp"
#include "cppa/exit_reason.hpp"
#include "cppa/event_based_actor.hpp"
#include "cppa/event_based_actor.hpp"
#include "cppa/util/callable_trait.hpp"
using
std
::
cerr
;
using
std
::
cerr
;
using
std
::
cout
;
using
std
::
cout
;
...
@@ -21,7 +24,6 @@ using std::endl;
...
@@ -21,7 +24,6 @@ using std::endl;
using
namespace
cppa
;
using
namespace
cppa
;
#if (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 7)
#if (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 7)
struct
simple_mirror
:
fsm_actor
<
simple_mirror
>
{
struct
simple_mirror
:
fsm_actor
<
simple_mirror
>
{
...
@@ -324,6 +326,64 @@ auto actor_prototype(const Args&... args) -> actor_template<decltype(mexpr_conca
...
@@ -324,6 +326,64 @@ auto actor_prototype(const Args&... args) -> actor_template<decltype(mexpr_conca
return
{
mexpr_concat
(
args
...)};
return
{
mexpr_concat
(
args
...)};
}
}
class
actor_factory
{
public:
virtual
~
actor_factory
()
{
}
virtual
actor_ptr
spawn
()
=
0
;
};
template
<
typename
InitFun
,
typename
...
Members
>
class
simple_event_based_actor_impl
:
public
event_based_actor
{
public:
simple_event_based_actor_impl
(
InitFun
fun
)
:
m_fun
(
std
::
move
(
fun
))
{
}
void
init
()
{
apply
();
}
private:
InitFun
m_fun
;
std
::
tuple
<
Members
...
>
m_members
;
void
apply
(
typename
std
::
add_pointer
<
Members
>::
type
...
args
)
{
m_fun
(
args
...);
}
template
<
typename
...
Args
>
void
apply
(
Args
...
args
)
{
apply
(
args
...,
&
std
::
get
<
sizeof
...(
Args
)
>
(
m_members
));
}
};
template
<
typename
InitFun
,
typename
...
Members
>
class
actor_tpl
:
public
actor_factory
{
InitFun
m_init_fun
;
public:
actor_tpl
(
InitFun
fun
)
:
m_init_fun
(
std
::
move
(
fun
))
{
}
actor_ptr
spawn
()
{
return
cppa
::
spawn
(
new
simple_event_based_actor_impl
<
InitFun
,
Members
...
>
(
m_init_fun
));
}
};
template
<
typename
InitFun
,
class
TypeList
>
struct
actor_tpl_from_type_list
;
template
<
typename
InitFun
,
typename
...
Ts
>
struct
actor_tpl_from_type_list
<
InitFun
,
util
::
type_list
<
Ts
...
>
>
{
typedef
actor_tpl
<
InitFun
,
Ts
...
>
type
;
};
class
str_wrapper
{
class
str_wrapper
{
str_wrapper
()
=
delete
;
str_wrapper
()
=
delete
;
...
@@ -382,10 +442,28 @@ void foobar(const str_wrapper& x, const std::string& y) {
...
@@ -382,10 +442,28 @@ void foobar(const str_wrapper& x, const std::string& y) {
);
);
}
}
template
<
typename
Fun
>
std
::
unique_ptr
<
actor_factory
>
foobaz
(
Fun
fun
)
{
typedef
typename
util
::
get_callable_trait
<
Fun
>::
type
ctrait
;
typedef
typename
ctrait
::
arg_types
arg_types
;
static_assert
(
util
::
tl_forall
<
arg_types
,
std
::
is_pointer
>::
value
,
"Functor takes non-pointer arguments"
);
typedef
typename
util
::
tl_map
<
arg_types
,
std
::
remove_pointer
>::
type
mems
;
typedef
typename
actor_tpl_from_type_list
<
Fun
,
mems
>::
type
tpl_type
;
return
std
::
unique_ptr
<
actor_factory
>
{
new
tpl_type
(
fun
)};
}
size_t
test__spawn
()
{
size_t
test__spawn
()
{
using
std
::
string
;
using
std
::
string
;
CPPA_TEST
(
test__spawn
);
CPPA_TEST
(
test__spawn
);
/*
actor_tpl<int, float, std::string> atpl;
atpl([](int* i, float* f, std::string* s) {
cout << "SUCCESS: " << *i << ", " << *f << ", \"" << *s << "\"" << endl;
});
*/
/*
/*
actor_ptr tst = actor_facade<some_integer>()
actor_ptr tst = actor_facade<some_integer>()
.reply_to().when().with()
.reply_to().when().with()
...
@@ -419,6 +497,13 @@ size_t test__spawn() {
...
@@ -419,6 +497,13 @@ size_t test__spawn() {
).spawn();
).spawn();
*/
*/
CPPA_IF_VERBOSE
(
cout
<<
"test echo actor ... "
<<
std
::
flush
);
auto
mecho
=
spawn
(
echo_actor
);
send
(
mecho
,
"hello echo"
);
receive
(
on
(
"hello echo"
)
>>
[]()
{
});
await_all_others_done
();
CPPA_IF_VERBOSE
(
cout
<<
"ok"
<<
endl
);
auto
mirror
=
spawn
(
new
simple_mirror
);
auto
mirror
=
spawn
(
new
simple_mirror
);
CPPA_IF_VERBOSE
(
cout
<<
"test mirror ... "
<<
std
::
flush
);
CPPA_IF_VERBOSE
(
cout
<<
"test mirror ... "
<<
std
::
flush
);
...
@@ -459,13 +544,6 @@ size_t test__spawn() {
...
@@ -459,13 +544,6 @@ size_t test__spawn() {
receive
(
after
(
std
::
chrono
::
seconds
(
1
))
>>
[]()
{
});
receive
(
after
(
std
::
chrono
::
seconds
(
1
))
>>
[]()
{
});
CPPA_IF_VERBOSE
(
cout
<<
"ok"
<<
endl
);
CPPA_IF_VERBOSE
(
cout
<<
"ok"
<<
endl
);
CPPA_IF_VERBOSE
(
cout
<<
"test echo actor ... "
<<
std
::
flush
);
auto
mecho
=
spawn
(
echo_actor
);
send
(
mecho
,
"hello echo"
);
receive
(
on
(
"hello echo"
)
>>
[]()
{
});
await_all_others_done
();
CPPA_IF_VERBOSE
(
cout
<<
"ok"
<<
endl
);
CPPA_IF_VERBOSE
(
cout
<<
"testee1 ... "
<<
std
::
flush
);
CPPA_IF_VERBOSE
(
cout
<<
"testee1 ... "
<<
std
::
flush
);
spawn
(
testee1
);
spawn
(
testee1
);
await_all_others_done
();
await_all_others_done
();
...
@@ -488,6 +566,35 @@ size_t test__spawn() {
...
@@ -488,6 +566,35 @@ size_t test__spawn() {
await_all_others_done
();
await_all_others_done
();
CPPA_IF_VERBOSE
(
cout
<<
"ok"
<<
endl
);
CPPA_IF_VERBOSE
(
cout
<<
"ok"
<<
endl
);
/*
CPPA_IF_VERBOSE(cout << "test factory ... " << std::flush);
auto factory = foobaz([&](int* i, float*, std::string*) {
self->become (
on(atom("get_int")) >> [i]() {
reply(*i);
},
on(atom("set_int"), arg_match) >> [i](int new_value) {
*i = new_value;
},
on(atom("done")) >> []() {
self->quit();
}
);
});
auto foobaz_actor = factory->spawn();
send(foobaz_actor, atom("set_int"), 42);
send(foobaz_actor, atom("get_int"));
send(foobaz_actor, atom("done"));
receive (
on_arg_match >> [&](int value) {
CPPA_CHECK_EQUAL(42, value);
}
);
await_all_others_done();
CPPA_IF_VERBOSE(cout << "ok" << endl);
*/
{
{
bool
invoked
=
false
;
bool
invoked
=
false
;
str_wrapper
actor_facade_builder
{
"x"
};
str_wrapper
actor_facade_builder
{
"x"
};
...
...
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