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
99626f2c
Commit
99626f2c
authored
Dec 12, 2011
by
neverlord
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
event actor, stacked event actor, mixin, etc.
parent
e09e8634
Changes
25
Hide whitespace changes
Inline
Side-by-side
Showing
25 changed files
with
436 additions
and
196 deletions
+436
-196
Makefile.am
Makefile.am
+4
-1
cppa.files
cppa.files
+4
-1
cppa/abstract_event_based_actor.hpp
cppa/abstract_event_based_actor.hpp
+145
-0
cppa/config.hpp
cppa/config.hpp
+3
-1
cppa/cppa.hpp
cppa/cppa.hpp
+1
-1
cppa/detail/abstract_event_based_actor.hpp
cppa/detail/abstract_event_based_actor.hpp
+0
-50
cppa/detail/mailman.hpp
cppa/detail/mailman.hpp
+1
-1
cppa/detail/mock_scheduler.hpp
cppa/detail/mock_scheduler.hpp
+1
-1
cppa/detail/task_scheduler.hpp
cppa/detail/task_scheduler.hpp
+1
-1
cppa/detail/thread_pool_scheduler.hpp
cppa/detail/thread_pool_scheduler.hpp
+1
-1
cppa/event_based_actor.hpp
cppa/event_based_actor.hpp
+7
-78
cppa/event_based_actor_mixin.hpp
cppa/event_based_actor_mixin.hpp
+67
-0
cppa/invoke_rules.hpp
cppa/invoke_rules.hpp
+3
-1
cppa/scheduler.hpp
cppa/scheduler.hpp
+2
-2
cppa/stacked_event_based_actor.hpp
cppa/stacked_event_based_actor.hpp
+26
-0
src/abstract_event_based_actor.cpp
src/abstract_event_based_actor.cpp
+23
-5
src/event_based_actor.cpp
src/event_based_actor.cpp
+10
-10
src/invoke_rules.cpp
src/invoke_rules.cpp
+12
-2
src/mock_scheduler.cpp
src/mock_scheduler.cpp
+1
-1
src/scheduled_actor.cpp
src/scheduled_actor.cpp
+6
-6
src/stacked_event_based_actor.cpp
src/stacked_event_based_actor.cpp
+24
-0
src/task_scheduler.cpp
src/task_scheduler.cpp
+1
-1
src/thread_pool_scheduler.cpp
src/thread_pool_scheduler.cpp
+1
-1
src/yielding_actor.cpp
src/yielding_actor.cpp
+5
-4
unit_testing/test__spawn.cpp
unit_testing/test__spawn.cpp
+87
-27
No files found.
Makefile.am
View file @
99626f2c
...
@@ -51,6 +51,7 @@ libcppa_la_SOURCES = \
...
@@ -51,6 +51,7 @@ libcppa_la_SOURCES = \
src/serializer.cpp
\
src/serializer.cpp
\
src/shared_spinlock.cpp
\
src/shared_spinlock.cpp
\
src/singleton_manager.cpp
\
src/singleton_manager.cpp
\
src/stacked_event_based_actor.cpp
\
src/string_serialization.cpp
\
src/string_serialization.cpp
\
src/task_scheduler.cpp
\
src/task_scheduler.cpp
\
src/thread_pool_scheduler.cpp
\
src/thread_pool_scheduler.cpp
\
...
@@ -84,8 +85,9 @@ nobase_library_include_HEADERS = \
...
@@ -84,8 +85,9 @@ nobase_library_include_HEADERS = \
cppa/cppa.hpp
\
cppa/cppa.hpp
\
cppa/deserializer.hpp
\
cppa/deserializer.hpp
\
cppa/event_based_actor.hpp
\
cppa/event_based_actor.hpp
\
cppa/event_based_actor_mixin.hpp
\
cppa/detail/abstract_actor.hpp
\
cppa/detail/abstract_actor.hpp
\
cppa/
detail/
abstract_event_based_actor.hpp
\
cppa/abstract_event_based_actor.hpp
\
cppa/detail/abstract_tuple.hpp
\
cppa/detail/abstract_tuple.hpp
\
cppa/detail/actor_count.hpp
\
cppa/detail/actor_count.hpp
\
cppa/detail/actor_proxy_cache.hpp
\
cppa/detail/actor_proxy_cache.hpp
\
...
@@ -156,6 +158,7 @@ nobase_library_include_HEADERS = \
...
@@ -156,6 +158,7 @@ nobase_library_include_HEADERS = \
cppa/scheduler.hpp
\
cppa/scheduler.hpp
\
cppa/scheduling_hint.hpp
\
cppa/scheduling_hint.hpp
\
cppa/serializer.hpp
\
cppa/serializer.hpp
\
cppa/stacked_event_based_actor.hpp
\
cppa/to_string.hpp
\
cppa/to_string.hpp
\
cppa/tuple.hpp
\
cppa/tuple.hpp
\
cppa/tuple_view.hpp
\
cppa/tuple_view.hpp
\
...
...
cppa.files
View file @
99626f2c
...
@@ -232,7 +232,10 @@ examples/math_actor_example.cpp
...
@@ -232,7 +232,10 @@ examples/math_actor_example.cpp
cppa/detail/yielding_actor.hpp
cppa/detail/yielding_actor.hpp
src/yielding_actor.cpp
src/yielding_actor.cpp
cppa/util/either.hpp
cppa/util/either.hpp
cppa/
detail/
abstract_event_based_actor.hpp
cppa/abstract_event_based_actor.hpp
src/abstract_event_based_actor.cpp
src/abstract_event_based_actor.cpp
cppa/event_based_actor.hpp
cppa/event_based_actor.hpp
src/event_based_actor.cpp
src/event_based_actor.cpp
cppa/stacked_event_based_actor.hpp
src/stacked_event_based_actor.cpp
cppa/event_based_actor_mixin.hpp
cppa/abstract_event_based_actor.hpp
0 → 100644
View file @
99626f2c
#ifndef EVENT_DRIVEN_ACTOR_HPP
#define EVENT_DRIVEN_ACTOR_HPP
#include <stack>
#include <memory>
#include <vector>
#include "cppa/pattern.hpp"
#include "cppa/invoke_rules.hpp"
#include "cppa/util/either.hpp"
#include "cppa/detail/scheduled_actor.hpp"
namespace
cppa
{
class
abstract_event_based_actor
:
public
detail
::
scheduled_actor
{
typedef
detail
::
scheduled_actor
super
;
typedef
super
::
queue_node
queue_node
;
typedef
super
::
queue_node_buffer
queue_node_buffer
;
protected:
struct
stack_element
{
util
::
either
<
invoke_rules
*
,
timed_invoke_rules
*>
m_ptr
;
bool
m_ownership
;
inline
stack_element
(
invoke_rules
*
ptr
,
bool
take_ownership
)
:
m_ptr
(
ptr
),
m_ownership
(
take_ownership
)
{
}
inline
stack_element
(
invoke_rules
&&
from
)
:
m_ptr
(
new
invoke_rules
(
std
::
move
(
from
))),
m_ownership
(
true
)
{
}
inline
stack_element
(
timed_invoke_rules
*
ptr
,
bool
take_ownership
)
:
m_ptr
(
ptr
),
m_ownership
(
take_ownership
)
{
}
inline
stack_element
(
timed_invoke_rules
&&
from
)
:
m_ptr
(
new
timed_invoke_rules
(
std
::
move
(
from
))),
m_ownership
(
true
)
{
}
inline
~
stack_element
()
{
if
(
m_ownership
)
{
if
(
m_ptr
.
is_left
())
{
delete
m_ptr
.
left
();
}
else
{
delete
m_ptr
.
right
();
}
}
}
inline
bool
is_left
()
{
return
m_ptr
.
is_left
();
}
inline
bool
is_right
()
{
return
m_ptr
.
is_right
();
}
inline
invoke_rules
&
left
()
{
return
*
(
m_ptr
.
left
());
}
inline
timed_invoke_rules
&
right
()
{
return
*
(
m_ptr
.
right
());
}
};
queue_node_buffer
m_buffer
;
std
::
stack
<
stack_element
,
std
::
vector
<
stack_element
>
>
m_loop_stack
;
public:
void
dequeue
(
invoke_rules
&
)
/*override*/
;
void
dequeue
(
timed_invoke_rules
&
)
/*override*/
;
void
resume
(
util
::
fiber
*
,
resume_callback
*
callback
)
/*override*/
;
virtual
void
init
()
=
0
;
virtual
void
on_exit
();
template
<
typename
Scheduler
>
abstract_event_based_actor
*
attach_to_scheduler
(
void
(
*
enqueue_fun
)(
Scheduler
*
,
scheduled_actor
*
),
Scheduler
*
sched
)
{
m_enqueue_to_scheduler
.
reset
(
enqueue_fun
,
sched
,
this
);
this
->
init
();
return
this
;
}
private:
void
handle_message
(
std
::
unique_ptr
<
queue_node
>&
node
,
invoke_rules
&
behavior
);
void
handle_message
(
std
::
unique_ptr
<
queue_node
>&
node
,
timed_invoke_rules
&
behavior
);
void
handle_message
(
std
::
unique_ptr
<
queue_node
>&
node
);
protected:
// provoke compiler errors for usage of receive() and related functions
template
<
typename
...
Args
>
void
receive
(
Args
&&
...)
{
static_assert
(
sizeof
...(
Args
)
<
0
,
"You shall not use receive in an event-based actor. "
"Use become()/unbecome() instead."
);
}
template
<
typename
...
Args
>
void
receive_loop
(
Args
&&
...
args
)
{
receive
(
std
::
forward
<
Args
>
(
args
)...);
}
template
<
typename
...
Args
>
void
receive_while
(
Args
&&
...
args
)
{
receive
(
std
::
forward
<
Args
>
(
args
)...);
}
template
<
typename
...
Args
>
void
do_receive
(
Args
&&
...
args
)
{
receive
(
std
::
forward
<
Args
>
(
args
)...);
}
};
}
// namespace cppa
#endif // EVENT_DRIVEN_ACTOR_HPP
cppa/config.hpp
View file @
99626f2c
...
@@ -7,7 +7,9 @@
...
@@ -7,7 +7,9 @@
#if defined(__APPLE__)
#if defined(__APPLE__)
# define CPPA_MACOS
# define CPPA_MACOS
# define _GLIBCXX_HAS_GTHREADS
# ifndef _GLIBCXX_HAS_GTHREADS
# define _GLIBCXX_HAS_GTHREADS
# endif
#elif defined(__GNUC__) && defined(__linux__)
#elif defined(__GNUC__) && defined(__linux__)
# define CPPA_LINUX
# define CPPA_LINUX
#elif defined(WIN32)
#elif defined(WIN32)
...
...
cppa/cppa.hpp
View file @
99626f2c
...
@@ -472,7 +472,7 @@ inline actor_ptr spawn(actor_behavior* what)
...
@@ -472,7 +472,7 @@ inline actor_ptr spawn(actor_behavior* what)
return
get_scheduler
()
->
spawn
(
what
,
Hint
);
return
get_scheduler
()
->
spawn
(
what
,
Hint
);
}
}
inline
actor_ptr
spawn
(
event_based_actor
*
what
)
inline
actor_ptr
spawn
(
abstract_
event_based_actor
*
what
)
{
{
return
get_scheduler
()
->
spawn
(
what
);
return
get_scheduler
()
->
spawn
(
what
);
}
}
...
...
cppa/detail/abstract_event_based_actor.hpp
deleted
100644 → 0
View file @
e09e8634
#ifndef EVENT_DRIVEN_ACTOR_HPP
#define EVENT_DRIVEN_ACTOR_HPP
#include <stack>
#include <memory>
#include "cppa/pattern.hpp"
#include "cppa/invoke_rules.hpp"
#include "cppa/util/either.hpp"
#include "cppa/detail/scheduled_actor.hpp"
namespace
cppa
{
namespace
detail
{
class
abstract_event_based_actor
:
public
scheduled_actor
{
typedef
scheduled_actor
super
;
typedef
super
::
queue_node
queue_node
;
typedef
super
::
queue_node_buffer
queue_node_buffer
;
protected:
queue_node_buffer
m_buffer
;
std
::
stack
<
util
::
either
<
invoke_rules
,
timed_invoke_rules
>
>
m_loop_stack
;
public:
void
dequeue
(
invoke_rules
&
)
/*override*/
;
void
dequeue
(
timed_invoke_rules
&
)
/*override*/
;
void
resume
(
util
::
fiber
*
,
resume_callback
*
callback
)
/*override*/
;
virtual
void
on_exit
()
=
0
;
private:
void
handle_message
(
std
::
unique_ptr
<
queue_node
>&
node
,
invoke_rules
&
behavior
);
void
handle_message
(
std
::
unique_ptr
<
queue_node
>&
node
,
timed_invoke_rules
&
behavior
);
void
handle_message
(
std
::
unique_ptr
<
queue_node
>&
node
);
};
}
}
// namespace cppa::detail
#endif // EVENT_DRIVEN_ACTOR_HPP
cppa/detail/mailman.hpp
View file @
99626f2c
...
@@ -100,7 +100,7 @@ class mailman_job
...
@@ -100,7 +100,7 @@ class mailman_job
mailman_add_peer
m_add_socket
;
mailman_add_peer
m_add_socket
;
};
};
constexpr
mailman_job
(
job_type
jt
)
:
next
(
nullptr
),
m_type
(
jt
)
{
}
inline
mailman_job
(
job_type
jt
)
:
next
(
nullptr
),
m_type
(
jt
)
{
}
};
};
...
...
cppa/detail/mock_scheduler.hpp
View file @
99626f2c
...
@@ -10,7 +10,7 @@ class mock_scheduler : public scheduler
...
@@ -10,7 +10,7 @@ class mock_scheduler : public scheduler
public:
public:
actor_ptr
spawn
(
event_based_actor
*
what
);
actor_ptr
spawn
(
abstract_
event_based_actor
*
what
);
actor_ptr
spawn
(
actor_behavior
*
,
scheduling_hint
);
actor_ptr
spawn
(
actor_behavior
*
,
scheduling_hint
);
...
...
cppa/detail/task_scheduler.hpp
View file @
99626f2c
...
@@ -29,7 +29,7 @@ class task_scheduler : public scheduler
...
@@ -29,7 +29,7 @@ class task_scheduler : public scheduler
void
schedule
(
scheduled_actor
*
what
);
void
schedule
(
scheduled_actor
*
what
);
actor_ptr
spawn
(
event_based_actor
*
what
);
actor_ptr
spawn
(
abstract_
event_based_actor
*
what
);
actor_ptr
spawn
(
actor_behavior
*
,
scheduling_hint
);
actor_ptr
spawn
(
actor_behavior
*
,
scheduling_hint
);
...
...
cppa/detail/thread_pool_scheduler.hpp
View file @
99626f2c
...
@@ -22,7 +22,7 @@ class thread_pool_scheduler : public scheduler
...
@@ -22,7 +22,7 @@ class thread_pool_scheduler : public scheduler
void
schedule
(
scheduled_actor
*
what
)
/*override*/
;
void
schedule
(
scheduled_actor
*
what
)
/*override*/
;
actor_ptr
spawn
(
event_based_actor
*
what
);
actor_ptr
spawn
(
abstract_
event_based_actor
*
what
);
actor_ptr
spawn
(
actor_behavior
*
behavior
,
scheduling_hint
hint
);
actor_ptr
spawn
(
actor_behavior
*
behavior
,
scheduling_hint
hint
);
...
...
cppa/event_based_actor.hpp
View file @
99626f2c
#ifndef EVENT_BASED_ACTOR_HPP
#ifndef EVENT_BASED_ACTOR_HPP
#define EVENT_BASED_ACTOR_HPP
#define EVENT_BASED_ACTOR_HPP
#include "cppa/
detail/abstract_event_based_actor
.hpp"
#include "cppa/
event_based_actor_mixin
.hpp"
namespace
cppa
{
namespace
cppa
{
class
event_based_actor
:
public
detail
::
abstract_event_based_actor
class
event_based_actor
:
public
event_based_actor_mixin
<
event_based_actor
>
{
{
inline
void
become_impl
(
invoke_rules
&
rules
)
friend
class
event_based_actor_mixin
<
event_based_actor
>
;
{
become
(
std
::
move
(
rules
));
}
inline
void
become_impl
(
timed_invoke_rules
&&
rules
)
typedef
abstract_event_based_actor
::
stack_element
stack_element
;
{
become
(
std
::
move
(
rules
));
}
template
<
typename
Head
,
typename
...
Tail
>
void
clear
();
void
become_impl
(
invoke_rules
&
rules
,
Head
&&
head
,
Tail
&&
...
tail
)
void
do_become
(
invoke_rules
*
behavior
,
bool
has_ownership
);
{
void
do_become
(
timed_invoke_rules
*
behavior
,
bool
has_ownership
);
become_impl
(
rules
.
splice
(
std
::
forward
<
Head
>
(
head
)),
std
::
forward
<
Tail
>
(
tail
)...);
}
protected:
void
unbecome
();
void
become
(
invoke_rules
&&
behavior
);
void
become
(
timed_invoke_rules
&&
behavior
);
template
<
typename
Head
,
typename
...
Tail
>
void
become
(
invoke_rules
&&
rules
,
Head
&&
head
,
Tail
&&
...
tail
)
{
invoke_rules
tmp
(
std
::
move
(
rules
));
become_impl
(
tmp
.
splice
(
std
::
forward
<
Head
>
(
head
)),
std
::
forward
<
Tail
>
(
tail
)...);
}
public:
virtual
void
init
()
=
0
;
virtual
void
on_exit
();
template
<
typename
Scheduler
>
abstract_event_based_actor
*
attach_to_scheduler
(
void
(
*
enqueue_fun
)(
Scheduler
*
,
scheduled_actor
*
),
Scheduler
*
sched
)
{
m_enqueue_to_scheduler
.
reset
(
enqueue_fun
,
sched
,
this
);
this
->
init
();
return
this
;
}
protected:
// provoke compiler errors for usage of receive() and related functions
template
<
typename
...
Args
>
void
receive
(
Args
&&
...)
{
static_assert
(
sizeof
...(
Args
)
<
0
,
"You shall not use receive in an event-based actor. "
"Use become()/unbecome() instead."
);
}
template
<
typename
...
Args
>
void
receive_loop
(
Args
&&
...
args
)
{
receive
(
std
::
forward
<
Args
>
(
args
)...);
}
template
<
typename
...
Args
>
void
receive_while
(
Args
&&
...
args
)
{
receive
(
std
::
forward
<
Args
>
(
args
)...);
}
template
<
typename
...
Args
>
void
do_receive
(
Args
&&
...
args
)
{
receive
(
std
::
forward
<
Args
>
(
args
)...);
}
};
};
...
...
cppa/event_based_actor_mixin.hpp
0 → 100644
View file @
99626f2c
#ifndef EVENT_BASED_ACTOR_MIXIN_HPP
#define EVENT_BASED_ACTOR_MIXIN_HPP
#include "cppa/abstract_event_based_actor.hpp"
namespace
cppa
{
template
<
typename
Derived
>
class
event_based_actor_mixin
:
public
abstract_event_based_actor
{
typedef
abstract_event_based_actor
super
;
inline
void
become_impl
(
invoke_rules
&
rules
)
{
become
(
std
::
move
(
rules
));
}
inline
void
become_impl
(
timed_invoke_rules
&&
rules
)
{
become
(
std
::
move
(
rules
));
}
template
<
typename
Head
,
typename
...
Tail
>
void
become_impl
(
invoke_rules
&
rules
,
Head
&&
head
,
Tail
&&
...
tail
)
{
become_impl
(
rules
.
splice
(
std
::
forward
<
Head
>
(
head
)),
std
::
forward
<
Tail
>
(
tail
)...);
}
inline
Derived
*
d_this
()
{
return
static_cast
<
Derived
*>
(
this
);
}
protected:
void
become
(
invoke_rules
*
behavior
)
{
d_this
()
->
do_become
(
behavior
,
false
);
}
void
become
(
timed_invoke_rules
*
behavior
)
{
d_this
()
->
do_become
(
behavior
,
false
);
}
void
become
(
invoke_rules
&&
behavior
)
{
d_this
()
->
do_become
(
new
invoke_rules
(
std
::
move
(
behavior
)),
true
);
}
void
become
(
timed_invoke_rules
&&
behavior
)
{
d_this
()
->
do_become
(
new
timed_invoke_rules
(
std
::
move
(
behavior
)),
true
);
}
template
<
typename
Head
,
typename
...
Tail
>
void
become
(
invoke_rules
&&
rules
,
Head
&&
head
,
Tail
&&
...
tail
)
{
invoke_rules
tmp
(
std
::
move
(
rules
));
become_impl
(
tmp
.
splice
(
std
::
forward
<
Head
>
(
head
)),
std
::
forward
<
Tail
>
(
tail
)...);
}
};
}
// namespace cppa
#endif // EVENT_BASED_ACTOR_MIXIN_HPP
cppa/invoke_rules.hpp
View file @
99626f2c
...
@@ -113,15 +113,17 @@ class timed_invoke_rules : public invoke_rules_base
...
@@ -113,15 +113,17 @@ class timed_invoke_rules : public invoke_rules_base
friend
class
invoke_rules
;
friend
class
invoke_rules
;
timed_invoke_rules
()
=
delete
;
timed_invoke_rules
(
const
timed_invoke_rules
&
)
=
delete
;
timed_invoke_rules
(
const
timed_invoke_rules
&
)
=
delete
;
timed_invoke_rules
&
operator
=
(
const
timed_invoke_rules
&
)
=
delete
;
timed_invoke_rules
&
operator
=
(
const
timed_invoke_rules
&
)
=
delete
;
timed_invoke_rules
(
invokable_list
&&
prepended_list
,
timed_invoke_rules
(
invokable_list
&&
prepended_list
,
timed_invoke_rules
&&
other
);
timed_invoke_rules
&&
other
);
static
util
::
duration
default_timeout
;
public:
public:
timed_invoke_rules
();
timed_invoke_rules
(
timed_invoke_rules
&&
arg
);
timed_invoke_rules
(
timed_invoke_rules
&&
arg
);
timed_invoke_rules
(
detail
::
timed_invokable_ptr
&&
arg
);
timed_invoke_rules
(
detail
::
timed_invokable_ptr
&&
arg
);
...
...
cppa/scheduler.hpp
View file @
99626f2c
...
@@ -11,7 +11,7 @@
...
@@ -11,7 +11,7 @@
#include "cppa/attachable.hpp"
#include "cppa/attachable.hpp"
#include "cppa/local_actor.hpp"
#include "cppa/local_actor.hpp"
#include "cppa/scheduling_hint.hpp"
#include "cppa/scheduling_hint.hpp"
#include "cppa/event_based_actor.hpp"
#include "cppa/
abstract_
event_based_actor.hpp"
#include "cppa/util/duration.hpp"
#include "cppa/util/duration.hpp"
...
@@ -59,7 +59,7 @@ class scheduler
...
@@ -59,7 +59,7 @@ class scheduler
/**
/**
* @brief Spawns a new event-based actor.
* @brief Spawns a new event-based actor.
*/
*/
virtual
actor_ptr
spawn
(
event_based_actor
*
what
)
=
0
;
virtual
actor_ptr
spawn
(
abstract_
event_based_actor
*
what
)
=
0
;
/**
/**
* @brief Informs the scheduler about a converted context
* @brief Informs the scheduler about a converted context
...
...
cppa/stacked_event_based_actor.hpp
0 → 100644
View file @
99626f2c
#ifndef STACKED_EVENT_BASED_ACTOR_HPP
#define STACKED_EVENT_BASED_ACTOR_HPP
#include "cppa/event_based_actor_mixin.hpp"
namespace
cppa
{
class
stacked_event_based_actor
:
public
event_based_actor_mixin
<
stacked_event_based_actor
>
{
friend
class
event_based_actor_mixin
<
stacked_event_based_actor
>
;
typedef
abstract_event_based_actor
::
stack_element
stack_element
;
void
do_become
(
invoke_rules
*
behavior
,
bool
has_ownership
);
void
do_become
(
timed_invoke_rules
*
behavior
,
bool
has_ownership
);
protected:
void
unbecome
();
};
}
// namespace cppa
#endif // STACKED_EVENT_BASED_ACTOR_HPP
src/abstract_event_based_actor.cpp
View file @
99626f2c
#include "cppa/detail/invokable.hpp"
#include "cppa/detail/invokable.hpp"
#include "cppa/
detail/
abstract_event_based_actor.hpp"
#include "cppa/abstract_event_based_actor.hpp"
namespace
cppa
{
namespace
detail
{
namespace
cppa
{
void
abstract_event_based_actor
::
dequeue
(
invoke_rules
&
)
void
abstract_event_based_actor
::
dequeue
(
invoke_rules
&
)
{
{
...
@@ -91,8 +91,22 @@ void abstract_event_based_actor::resume(util::fiber*, resume_callback* callback)
...
@@ -91,8 +91,22 @@ void abstract_event_based_actor::resume(util::fiber*, resume_callback* callback)
}
}
else
else
{
{
// nothing to do
// nothing to do (wait for new messages)
return
;
switch
(
compare_exchange_state
(
scheduled_actor
::
about_to_block
,
scheduled_actor
::
blocked
))
{
case
scheduled_actor
:
:
ready
:
{
// got a new job
break
;
}
case
scheduled_actor
:
:
blocked
:
{
// done
return
;
}
default:
exit
(
7
);
// illegal state
};
}
}
}
}
node
.
reset
(
m_mailbox
.
pop
());
node
.
reset
(
m_mailbox
.
pop
());
...
@@ -119,4 +133,8 @@ void abstract_event_based_actor::resume(util::fiber*, resume_callback* callback)
...
@@ -119,4 +133,8 @@ void abstract_event_based_actor::resume(util::fiber*, resume_callback* callback)
while
(
callback
->
still_ready
());
while
(
callback
->
still_ready
());
}
}
}
}
// namespace cppa::detail
void
abstract_event_based_actor
::
on_exit
()
{
}
}
// namespace cppa
src/event_based_actor.cpp
View file @
99626f2c
...
@@ -2,25 +2,25 @@
...
@@ -2,25 +2,25 @@
namespace
cppa
{
namespace
cppa
{
void
event_based_actor
::
on_exit
()
void
event_based_actor
::
clear
()
{
}
void
event_based_actor
::
unbecome
()
{
{
if
(
!
m_loop_stack
.
empty
())
m_loop_stack
.
pop
();
if
(
!
m_loop_stack
.
empty
())
m_loop_stack
.
pop
();
}
}
void
event_based_actor
::
become
(
invoke_rules
&&
behavior
)
void
event_based_actor
::
do_become
(
invoke_rules
*
behavior
,
bool
has_ownership
)
{
{
clear
();
reset_timeout
();
reset_timeout
();
m_loop_stack
.
push
(
st
d
::
move
(
behavior
));
m_loop_stack
.
push
(
st
ack_element
(
behavior
,
has_ownership
));
}
}
void
event_based_actor
::
become
(
timed_invoke_rules
&&
behavior
)
void
event_based_actor
::
do_become
(
timed_invoke_rules
*
behavior
,
bool
has_ownership
)
{
{
request_timeout
(
behavior
.
timeout
());
clear
();
m_loop_stack
.
push
(
std
::
move
(
behavior
));
request_timeout
(
behavior
->
timeout
());
m_loop_stack
.
push
(
stack_element
(
behavior
,
has_ownership
));
}
}
}
// namespace cppa
}
// namespace cppa
src/invoke_rules.cpp
View file @
99626f2c
...
@@ -33,6 +33,7 @@
...
@@ -33,6 +33,7 @@
namespace
cppa
{
namespace
cppa
{
util
::
duration
timed_invoke_rules
::
default_timeout
;
// invoke_rules_base
// invoke_rules_base
invoke_rules_base
::
invoke_rules_base
(
invoke_rules_base
&&
other
)
invoke_rules_base
::
invoke_rules_base
(
invoke_rules_base
&&
other
)
...
@@ -72,6 +73,10 @@ invoke_rules_base::get_intermediate(const any_tuple& t) const
...
@@ -72,6 +73,10 @@ invoke_rules_base::get_intermediate(const any_tuple& t) const
// timed_invoke_rules
// timed_invoke_rules
timed_invoke_rules
::
timed_invoke_rules
()
{
}
timed_invoke_rules
::
timed_invoke_rules
(
timed_invoke_rules
&&
other
)
timed_invoke_rules
::
timed_invoke_rules
(
timed_invoke_rules
&&
other
)
:
super
(
std
::
move
(
other
)),
m_ti
(
std
::
move
(
other
.
m_ti
))
:
super
(
std
::
move
(
other
)),
m_ti
(
std
::
move
(
other
.
m_ti
))
{
{
...
@@ -99,13 +104,13 @@ timed_invoke_rules& timed_invoke_rules::operator=(timed_invoke_rules&& other)
...
@@ -99,13 +104,13 @@ timed_invoke_rules& timed_invoke_rules::operator=(timed_invoke_rules&& other)
const
util
::
duration
&
timed_invoke_rules
::
timeout
()
const
const
util
::
duration
&
timed_invoke_rules
::
timeout
()
const
{
{
return
m_ti
->
timeout
()
;
return
(
m_ti
!=
nullptr
)
?
m_ti
->
timeout
()
:
default_timeout
;
}
}
void
timed_invoke_rules
::
handle_timeout
()
const
void
timed_invoke_rules
::
handle_timeout
()
const
{
{
// safe, because timed_invokable ignores the given argument
// safe, because timed_invokable ignores the given argument
m_ti
->
invoke
(
*
static_cast
<
any_tuple
*>
(
nullptr
));
if
(
m_ti
!=
nullptr
)
m_ti
->
invoke
(
*
static_cast
<
any_tuple
*>
(
nullptr
));
}
}
// invoke_rules
// invoke_rules
...
@@ -145,6 +150,11 @@ invoke_rules invoke_rules::operator,(invoke_rules&& other)
...
@@ -145,6 +150,11 @@ invoke_rules invoke_rules::operator,(invoke_rules&& other)
return
std
::
move
(
m_list
);
return
std
::
move
(
m_list
);
}
}
timed_invoke_rules
invoke_rules
::
operator
,(
timed_invoke_rules
&&
other
)
{
return
timed_invoke_rules
(
std
::
move
(
m_list
),
std
::
move
(
other
));
}
invoke_rules
&
invoke_rules
::
operator
=
(
invoke_rules
&&
other
)
invoke_rules
&
invoke_rules
::
operator
=
(
invoke_rules
&&
other
)
{
{
m_list
=
std
::
move
(
other
.
m_list
);
m_list
=
std
::
move
(
other
.
m_list
);
...
...
src/mock_scheduler.cpp
View file @
99626f2c
...
@@ -50,7 +50,7 @@ actor_ptr mock_scheduler::spawn(actor_behavior* behavior)
...
@@ -50,7 +50,7 @@ actor_ptr mock_scheduler::spawn(actor_behavior* behavior)
return
ctx
;
return
ctx
;
}
}
actor_ptr
mock_scheduler
::
spawn
(
event_based_actor
*
what
)
actor_ptr
mock_scheduler
::
spawn
(
abstract_
event_based_actor
*
what
)
{
{
// TODO: don't delete what :)
// TODO: don't delete what :)
delete
what
;
delete
what
;
...
...
src/scheduled_actor.cpp
View file @
99626f2c
...
@@ -28,12 +28,6 @@ void scheduled_actor::quit(std::uint32_t reason)
...
@@ -28,12 +28,6 @@ void scheduled_actor::quit(std::uint32_t reason)
//yield(yield_state::done);
//yield(yield_state::done);
}
}
void
scheduled_actor
::
request_timeout
(
const
util
::
duration
&
d
)
{
future_send
(
this
,
d
,
atom
(
":Timeout"
),
++
m_active_timeout_id
);
m_has_pending_timeout_request
=
true
;
}
void
scheduled_actor
::
enqueue_node
(
queue_node
*
node
)
void
scheduled_actor
::
enqueue_node
(
queue_node
*
node
)
{
{
if
(
m_mailbox
.
_push_back
(
node
))
if
(
m_mailbox
.
_push_back
(
node
))
...
@@ -90,6 +84,12 @@ int scheduled_actor::compare_exchange_state(int expected, int new_value)
...
@@ -90,6 +84,12 @@ int scheduled_actor::compare_exchange_state(int expected, int new_value)
return
e
;
return
e
;
}
}
void
scheduled_actor
::
request_timeout
(
const
util
::
duration
&
d
)
{
future_send
(
this
,
d
,
atom
(
":Timeout"
),
++
m_active_timeout_id
);
m_has_pending_timeout_request
=
true
;
}
scheduled_actor
::
filter_result
scheduled_actor
::
filter_msg
(
const
any_tuple
&
msg
)
scheduled_actor
::
filter_result
scheduled_actor
::
filter_msg
(
const
any_tuple
&
msg
)
{
{
if
(
m_pattern
(
msg
))
if
(
m_pattern
(
msg
))
...
...
src/stacked_event_based_actor.cpp
0 → 100644
View file @
99626f2c
#include "cppa/stacked_event_based_actor.hpp"
namespace
cppa
{
void
stacked_event_based_actor
::
unbecome
()
{
if
(
!
m_loop_stack
.
empty
())
m_loop_stack
.
pop
();
}
void
stacked_event_based_actor
::
do_become
(
invoke_rules
*
behavior
,
bool
has_ownership
)
{
reset_timeout
();
m_loop_stack
.
push
(
stack_element
(
behavior
,
has_ownership
));
}
void
stacked_event_based_actor
::
do_become
(
timed_invoke_rules
*
behavior
,
bool
has_ownership
)
{
request_timeout
(
behavior
->
timeout
());
m_loop_stack
.
push
(
stack_element
(
behavior
,
has_ownership
));
}
}
// namespace cppa
src/task_scheduler.cpp
View file @
99626f2c
...
@@ -99,7 +99,7 @@ actor_ptr task_scheduler::spawn_impl(scheduled_actor* what)
...
@@ -99,7 +99,7 @@ actor_ptr task_scheduler::spawn_impl(scheduled_actor* what)
}
}
actor_ptr
task_scheduler
::
spawn
(
event_based_actor
*
what
)
actor_ptr
task_scheduler
::
spawn
(
abstract_
event_based_actor
*
what
)
{
{
return
spawn_impl
(
what
->
attach_to_scheduler
(
enqueue_fun
,
this
));
return
spawn_impl
(
what
->
attach_to_scheduler
(
enqueue_fun
,
this
));
}
}
...
...
src/thread_pool_scheduler.cpp
View file @
99626f2c
...
@@ -217,7 +217,7 @@ actor_ptr thread_pool_scheduler::spawn_impl(scheduled_actor* what)
...
@@ -217,7 +217,7 @@ actor_ptr thread_pool_scheduler::spawn_impl(scheduled_actor* what)
}
}
actor_ptr
thread_pool_scheduler
::
spawn
(
event_based_actor
*
what
)
actor_ptr
thread_pool_scheduler
::
spawn
(
abstract_
event_based_actor
*
what
)
{
{
return
spawn_impl
(
what
->
attach_to_scheduler
(
enqueue_fun
,
this
));
return
spawn_impl
(
what
->
attach_to_scheduler
(
enqueue_fun
,
this
));
}
}
...
...
src/yielding_actor.cpp
View file @
99626f2c
...
@@ -74,12 +74,13 @@ void yielding_actor::dequeue(timed_invoke_rules& rules)
...
@@ -74,12 +74,13 @@ void yielding_actor::dequeue(timed_invoke_rules& rules)
{
{
queue_node_buffer
buffer
;
queue_node_buffer
buffer
;
// try until a message was successfully dequeued
// try until a message was successfully dequeued
request_timeout
(
rules
.
timeout
());
for
(;;)
for
(;;)
{
{
if
(
m_mailbox
.
empty
()
&&
has_pending_timeout
()
==
false
)
//
if (m_mailbox.empty() && has_pending_timeout() == false)
{
//
{
request_timeout
(
rules
.
timeout
());
//
request_timeout(rules.timeout());
}
//
}
yield_until_not_empty
();
yield_until_not_empty
();
std
::
unique_ptr
<
queue_node
>
node
(
m_mailbox
.
pop
());
std
::
unique_ptr
<
queue_node
>
node
(
m_mailbox
.
pop
());
switch
(
dq
(
node
,
rules
,
buffer
))
switch
(
dq
(
node
,
rules
,
buffer
))
...
...
unit_testing/test__spawn.cpp
View file @
99626f2c
...
@@ -15,6 +15,7 @@
...
@@ -15,6 +15,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/stacked_event_based_actor.hpp"
using
std
::
cerr
;
using
std
::
cerr
;
using
std
::
cout
;
using
std
::
cout
;
...
@@ -22,38 +23,65 @@ using std::endl;
...
@@ -22,38 +23,65 @@ using std::endl;
using
namespace
cppa
;
using
namespace
cppa
;
// GCC 4.7 supports non-static member initialization
#if (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 7)
class
event_testee
:
public
event_based_actor
class
event_testee
:
public
event_based_actor
{
{
invoke_rules
wait4string
()
invoke_rules
wait4string
=
{
(
return
on
<
std
::
string
>
()
>>
[
=
](
const
std
::
string
&
value
)
on
<
std
::
string
>
()
>>
[
=
](
const
std
::
string
&
value
)
{
{
cout
<<
"event_testee[string]: "
<<
value
<<
endl
;
cout
<<
"event_testee[string]: "
<<
value
<<
endl
;
// switch back to wait4int
// switch back to wait4int
unbecome
();
unbecome
();
unbecome
();
unbecome
();
}
;
}
}
);
invoke_rules
wait4float
()
invoke_rules
wait4float
=
{
(
return
on
<
float
>
()
>>
[
=
](
float
value
)
on
<
float
>
()
>>
[
=
](
float
value
)
{
{
cout
<<
"event_testee[float]: "
<<
value
<<
endl
;
cout
<<
"event_testee[float]: "
<<
value
<<
endl
;
become
(
wait4string
()
);
become
(
wait4string
);
}
;
}
}
);
invoke_rules
wait4int
()
invoke_rules
wait4int
=
{
(
return
on
<
int
>
()
>>
[
=
](
int
value
)
on
<
int
>
()
>>
[
=
](
int
value
)
{
{
cout
<<
"event_testee[int]: "
<<
value
<<
endl
;
cout
<<
"event_testee[int]: "
<<
value
<<
endl
;
become
(
wait4float
());
become
(
wait4float
);
};
}
);
public:
void
on_exit
()
{
cout
<<
"event_testee[GCC47]::on_exit()"
<<
endl
;
}
}
void
init
()
{
cout
<<
"event_testee[GCC47]::init()"
<<
endl
;
become
(
wait4int
);
}
};
#else
class
event_testee
:
public
event_based_actor
{
invoke_rules
wait4string
;
invoke_rules
wait4float
;
invoke_rules
wait4int
;
public:
public:
void
on_exit
()
void
on_exit
()
...
@@ -63,21 +91,52 @@ class event_testee : public event_based_actor
...
@@ -63,21 +91,52 @@ class event_testee : public event_based_actor
void
init
()
void
init
()
{
{
wait4string
=
(
on
<
std
::
string
>
()
>>
[
=
](
const
std
::
string
&
value
)
{
cout
<<
"event_testee[string]: "
<<
value
<<
endl
;
become
(
&
wait4int
);
}
);
wait4float
=
(
on
<
float
>
()
>>
[
=
](
float
value
)
{
cout
<<
"event_testee[float]: "
<<
value
<<
endl
;
become
(
&
wait4string
);
}
);
wait4int
=
(
on
<
int
>
()
>>
[
=
](
int
value
)
{
cout
<<
"event_testee[int]: "
<<
value
<<
endl
;
become
(
&
wait4float
);
}
);
cout
<<
"event_testee::init()"
<<
endl
;
cout
<<
"event_testee::init()"
<<
endl
;
become
(
wait4int
()
);
become
(
&
wait4int
);
}
}
};
};
event_based_actor
*
event_testee2
()
#endif
abstract_event_based_actor
*
event_testee2
()
{
{
struct
impl
:
event_based_actor
struct
impl
:
event_based_actor
{
{
int
num_timeouts
;
int
num_timeouts
;
impl
()
:
num_timeouts
(
0
)
{
}
impl
()
:
num_timeouts
(
0
)
{
}
timed_invoke_rules
state
;
void
init
()
void
init
()
{
{
become
cout
<<
"event_testee2::impl::init()"
<<
endl
;
state
=
//become
(
(
others
()
>>
[]()
others
()
>>
[]()
{
{
...
@@ -85,13 +144,17 @@ event_based_actor* event_testee2()
...
@@ -85,13 +144,17 @@ event_based_actor* event_testee2()
<<
to_string
(
last_received
())
<<
to_string
(
last_received
())
<<
endl
;
<<
endl
;
},
},
after
(
std
::
chrono
::
milliseconds
(
50
))
>>
[
this
]()
after
(
std
::
chrono
::
milliseconds
(
50
))
>>
[
=
]()
{
{
cout
<<
"testee2 received timeout nr. "
cout
<<
"testee2 received timeout nr. "
<<
(
num_timeouts
+
1
)
<<
endl
;
<<
(
num_timeouts
+
1
)
<<
endl
;
if
(
++
num_timeouts
>=
5
)
unbecome
();
if
(
++
num_timeouts
>=
5
)
{
quit
(
exit_reason
::
normal
);
}
}
}
);
);
become
(
&
state
);
}
}
};
};
return
new
impl
;
return
new
impl
;
...
@@ -142,6 +205,7 @@ void testee1()
...
@@ -142,6 +205,7 @@ void testee1()
(
(
after
(
std
::
chrono
::
milliseconds
(
10
))
>>
[]()
after
(
std
::
chrono
::
milliseconds
(
10
))
>>
[]()
{
{
cout
<<
"testee1::quit"
<<
endl
;
quit
(
exit_reason
::
user_defined
);
quit
(
exit_reason
::
user_defined
);
}
}
);
);
...
@@ -205,13 +269,9 @@ size_t test__spawn()
...
@@ -205,13 +269,9 @@ size_t test__spawn()
CPPA_TEST
(
test__spawn
);
CPPA_TEST
(
test__spawn
);
//spawn(testee1);
//spawn(testee1);
//spawn(new testee_behavior
);
spawn
(
event_testee2
()
);
//await_all_others_done();
await_all_others_done
();
//spawn(event_testee2());
//auto et = spawn(new event_testee);
behavior_test
<
testee_behavior
>
();
behavior_test
<
testee_behavior
>
();
behavior_test
<
event_testee
>
();
behavior_test
<
event_testee
>
();
...
...
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