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
920472e6
Commit
920472e6
authored
Dec 12, 2011
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fsm_actor and scheduled_actor
parent
99626f2c
Changes
25
Hide whitespace changes
Inline
Side-by-side
Showing
25 changed files
with
518 additions
and
466 deletions
+518
-466
Makefile.am
Makefile.am
+6
-5
cppa.files
cppa.files
+6
-5
cppa/abstract_actor.hpp
cppa/abstract_actor.hpp
+2
-2
cppa/abstract_event_based_actor.hpp
cppa/abstract_event_based_actor.hpp
+41
-45
cppa/actor_proxy.hpp
cppa/actor_proxy.hpp
+3
-3
cppa/cppa.hpp
cppa/cppa.hpp
+5
-5
cppa/detail/abstract_scheduled_actor.hpp
cppa/detail/abstract_scheduled_actor.hpp
+10
-11
cppa/detail/converted_thread_context.hpp
cppa/detail/converted_thread_context.hpp
+1
-2
cppa/detail/get_behavior.hpp
cppa/detail/get_behavior.hpp
+13
-13
cppa/detail/mock_scheduler.hpp
cppa/detail/mock_scheduler.hpp
+2
-2
cppa/detail/task_scheduler.hpp
cppa/detail/task_scheduler.hpp
+6
-6
cppa/detail/thread_pool_scheduler.hpp
cppa/detail/thread_pool_scheduler.hpp
+6
-6
cppa/detail/yielding_actor.hpp
cppa/detail/yielding_actor.hpp
+6
-6
cppa/fsm_actor.hpp
cppa/fsm_actor.hpp
+23
-0
cppa/scheduled_actor.hpp
cppa/scheduled_actor.hpp
+2
-2
cppa/scheduler.hpp
cppa/scheduler.hpp
+2
-2
src/abstract_event_based_actor.cpp
src/abstract_event_based_actor.cpp
+7
-7
src/abstract_scheduled_actor.cpp
src/abstract_scheduled_actor.cpp
+217
-0
src/actor_behavior.cpp
src/actor_behavior.cpp
+0
-13
src/mock_scheduler.cpp
src/mock_scheduler.cpp
+4
-4
src/scheduled_actor.cpp
src/scheduled_actor.cpp
+5
-209
src/task_scheduler.cpp
src/task_scheduler.cpp
+11
-11
src/thread_pool_scheduler.cpp
src/thread_pool_scheduler.cpp
+11
-11
src/yielding_actor.cpp
src/yielding_actor.cpp
+6
-6
unit_testing/test__spawn.cpp
unit_testing/test__spawn.cpp
+123
-90
No files found.
Makefile.am
View file @
920472e6
...
@@ -5,7 +5,7 @@ lib_LTLIBRARIES = libcppa.la
...
@@ -5,7 +5,7 @@ lib_LTLIBRARIES = libcppa.la
libcppa_la_SOURCES
=
\
libcppa_la_SOURCES
=
\
src/abstract_event_based_actor.cpp
\
src/abstract_event_based_actor.cpp
\
src/abstract_tuple.cpp
\
src/abstract_tuple.cpp
\
src/
actor_behavi
or.cpp
\
src/
scheduled_act
or.cpp
\
src/actor_count.cpp
\
src/actor_count.cpp
\
src/actor.cpp
\
src/actor.cpp
\
src/actor_proxy_cache.cpp
\
src/actor_proxy_cache.cpp
\
...
@@ -46,7 +46,7 @@ libcppa_la_SOURCES = \
...
@@ -46,7 +46,7 @@ libcppa_la_SOURCES = \
src/primitive_variant.cpp
\
src/primitive_variant.cpp
\
src/process_information.cpp
\
src/process_information.cpp
\
src/ripemd_160.cpp
\
src/ripemd_160.cpp
\
src/scheduled_actor.cpp
\
src/
abstract_
scheduled_actor.cpp
\
src/scheduler.cpp
\
src/scheduler.cpp
\
src/serializer.cpp
\
src/serializer.cpp
\
src/shared_spinlock.cpp
\
src/shared_spinlock.cpp
\
...
@@ -68,7 +68,8 @@ library_includedir = $(includedir)/
...
@@ -68,7 +68,8 @@ library_includedir = $(includedir)/
endif
endif
nobase_library_include_HEADERS
=
\
nobase_library_include_HEADERS
=
\
cppa/actor_behavior.hpp
\
cppa/abstract_actor.hpp
\
cppa/scheduled_actor.hpp
\
cppa/actor.hpp
\
cppa/actor.hpp
\
cppa/actor_proxy.hpp
\
cppa/actor_proxy.hpp
\
cppa/announce.hpp
\
cppa/announce.hpp
\
...
@@ -86,7 +87,6 @@ nobase_library_include_HEADERS = \
...
@@ -86,7 +87,6 @@ nobase_library_include_HEADERS = \
cppa/deserializer.hpp
\
cppa/deserializer.hpp
\
cppa/event_based_actor.hpp
\
cppa/event_based_actor.hpp
\
cppa/event_based_actor_mixin.hpp
\
cppa/event_based_actor_mixin.hpp
\
cppa/detail/abstract_actor.hpp
\
cppa/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
\
...
@@ -124,7 +124,7 @@ nobase_library_include_HEADERS = \
...
@@ -124,7 +124,7 @@ nobase_library_include_HEADERS = \
cppa/detail/ptype_to_type.hpp
\
cppa/detail/ptype_to_type.hpp
\
cppa/detail/receive_loop_helper.hpp
\
cppa/detail/receive_loop_helper.hpp
\
cppa/detail/ref_counted_impl.hpp
\
cppa/detail/ref_counted_impl.hpp
\
cppa/detail/scheduled_actor.hpp
\
cppa/detail/
abstract_
scheduled_actor.hpp
\
cppa/detail/serialize_tuple.hpp
\
cppa/detail/serialize_tuple.hpp
\
cppa/detail/singleton_manager.hpp
\
cppa/detail/singleton_manager.hpp
\
cppa/detail/swap_bytes.hpp
\
cppa/detail/swap_bytes.hpp
\
...
@@ -141,6 +141,7 @@ nobase_library_include_HEADERS = \
...
@@ -141,6 +141,7 @@ nobase_library_include_HEADERS = \
cppa/exception.hpp
\
cppa/exception.hpp
\
cppa/exit_reason.hpp
\
cppa/exit_reason.hpp
\
cppa/from_string.hpp
\
cppa/from_string.hpp
\
cppa/fsm_actor.hpp
\
cppa/get.hpp
\
cppa/get.hpp
\
cppa/get_view.hpp
\
cppa/get_view.hpp
\
cppa/group.hpp
\
cppa/group.hpp
\
...
...
cppa.files
View file @
920472e6
...
@@ -69,10 +69,10 @@ cppa/util/eval_first_n.hpp
...
@@ -69,10 +69,10 @@ cppa/util/eval_first_n.hpp
cppa/local_actor.hpp
cppa/local_actor.hpp
cppa/channel.hpp
cppa/channel.hpp
src/channel.cpp
src/channel.cpp
cppa/
actor_behavi
or.hpp
cppa/
scheduled_act
or.hpp
cppa/cppa.hpp
cppa/cppa.hpp
cppa/scheduling_hint.hpp
cppa/scheduling_hint.hpp
src/
actor_behavi
or.cpp
src/
scheduled_act
or.cpp
cppa/group.hpp
cppa/group.hpp
src/group.cpp
src/group.cpp
queue_performances/main.cpp
queue_performances/main.cpp
...
@@ -163,7 +163,7 @@ cppa/detail/atom_val.hpp
...
@@ -163,7 +163,7 @@ cppa/detail/atom_val.hpp
src/atom.cpp
src/atom.cpp
src/cppa.cpp
src/cppa.cpp
cppa/exit_reason.hpp
cppa/exit_reason.hpp
cppa/
detail/
abstract_actor.hpp
cppa/abstract_actor.hpp
cppa/detail/mailman.hpp
cppa/detail/mailman.hpp
src/mailman.cpp
src/mailman.cpp
cppa/detail/native_socket.hpp
cppa/detail/native_socket.hpp
...
@@ -179,8 +179,8 @@ cppa/util/fiber.hpp
...
@@ -179,8 +179,8 @@ cppa/util/fiber.hpp
src/fiber.cpp
src/fiber.cpp
cppa/detail/yield_interface.hpp
cppa/detail/yield_interface.hpp
src/yield_interface.cpp
src/yield_interface.cpp
cppa/detail/scheduled_actor.hpp
cppa/detail/
abstract_
scheduled_actor.hpp
src/scheduled_actor.cpp
src/
abstract_
scheduled_actor.cpp
src/intermediate.cpp
src/intermediate.cpp
src/invokable.cpp
src/invokable.cpp
cppa/detail/thread_pool_scheduler.hpp
cppa/detail/thread_pool_scheduler.hpp
...
@@ -239,3 +239,4 @@ src/event_based_actor.cpp
...
@@ -239,3 +239,4 @@ src/event_based_actor.cpp
cppa/stacked_event_based_actor.hpp
cppa/stacked_event_based_actor.hpp
src/stacked_event_based_actor.cpp
src/stacked_event_based_actor.cpp
cppa/event_based_actor_mixin.hpp
cppa/event_based_actor_mixin.hpp
cppa/fsm_actor.hpp
cppa/
detail/
abstract_actor.hpp
→
cppa/abstract_actor.hpp
View file @
920472e6
...
@@ -16,7 +16,7 @@
...
@@ -16,7 +16,7 @@
#include "cppa/attachable.hpp"
#include "cppa/attachable.hpp"
#include "cppa/exit_reason.hpp"
#include "cppa/exit_reason.hpp"
namespace
cppa
{
namespace
detail
{
namespace
cppa
{
// implements linking and monitoring for actors
// implements linking and monitoring for actors
template
<
class
Base
>
template
<
class
Base
>
...
@@ -257,6 +257,6 @@ class abstract_actor : public Base
...
@@ -257,6 +257,6 @@ class abstract_actor : public Base
};
};
}
}
// namespace cppa::detail
}
// namespace cppa
#endif // ABSTRACT_ACTOR_HPP
#endif // ABSTRACT_ACTOR_HPP
cppa/abstract_event_based_actor.hpp
View file @
920472e6
...
@@ -8,17 +8,55 @@
...
@@ -8,17 +8,55 @@
#include "cppa/pattern.hpp"
#include "cppa/pattern.hpp"
#include "cppa/invoke_rules.hpp"
#include "cppa/invoke_rules.hpp"
#include "cppa/util/either.hpp"
#include "cppa/util/either.hpp"
#include "cppa/detail/scheduled_actor.hpp"
#include "cppa/detail/
abstract_
scheduled_actor.hpp"
namespace
cppa
{
namespace
cppa
{
class
abstract_event_based_actor
:
public
detail
::
scheduled_actor
class
abstract_event_based_actor
:
public
detail
::
abstract_
scheduled_actor
{
{
typedef
detail
::
scheduled_actor
super
;
typedef
detail
::
abstract_
scheduled_actor
super
;
typedef
super
::
queue_node
queue_node
;
typedef
super
::
queue_node
queue_node
;
typedef
super
::
queue_node_buffer
queue_node_buffer
;
typedef
super
::
queue_node_buffer
queue_node_buffer
;
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
*
,
abstract_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:
protected:
struct
stack_element
struct
stack_element
...
@@ -29,18 +67,10 @@ class abstract_event_based_actor : public detail::scheduled_actor
...
@@ -29,18 +67,10 @@ class abstract_event_based_actor : public detail::scheduled_actor
:
m_ptr
(
ptr
),
m_ownership
(
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
)
inline
stack_element
(
timed_invoke_rules
*
ptr
,
bool
take_ownership
)
:
m_ptr
(
ptr
),
m_ownership
(
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
()
inline
~
stack_element
()
{
{
if
(
m_ownership
)
if
(
m_ownership
)
...
@@ -76,40 +106,6 @@ class abstract_event_based_actor : public detail::scheduled_actor
...
@@ -76,40 +106,6 @@ class abstract_event_based_actor : public detail::scheduled_actor
queue_node_buffer
m_buffer
;
queue_node_buffer
m_buffer
;
std
::
stack
<
stack_element
,
std
::
vector
<
stack_element
>
>
m_loop_stack
;
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
// provoke compiler errors for usage of receive() and related functions
template
<
typename
...
Args
>
template
<
typename
...
Args
>
...
...
cppa/actor_proxy.hpp
View file @
920472e6
...
@@ -2,17 +2,17 @@
...
@@ -2,17 +2,17 @@
#define ACTOR_PROXY_HPP
#define ACTOR_PROXY_HPP
#include "cppa/actor.hpp"
#include "cppa/actor.hpp"
#include "cppa/
detail/
abstract_actor.hpp"
#include "cppa/abstract_actor.hpp"
namespace
cppa
{
namespace
cppa
{
/**
/**
* @brief Represents a remote Actor.
* @brief Represents a remote Actor.
*/
*/
class
actor_proxy
:
public
detail
::
abstract_actor
<
actor
>
class
actor_proxy
:
public
abstract_actor
<
actor
>
{
{
typedef
detail
::
abstract_actor
<
actor
>
super
;
typedef
abstract_actor
<
actor
>
super
;
void
forward_message
(
const
process_information_ptr
&
,
void
forward_message
(
const
process_information_ptr
&
,
actor
*
,
const
any_tuple
&
);
actor
*
,
const
any_tuple
&
);
...
...
cppa/cppa.hpp
View file @
920472e6
...
@@ -47,7 +47,7 @@
...
@@ -47,7 +47,7 @@
#include "cppa/local_actor.hpp"
#include "cppa/local_actor.hpp"
#include "cppa/exit_reason.hpp"
#include "cppa/exit_reason.hpp"
#include "cppa/invoke_rules.hpp"
#include "cppa/invoke_rules.hpp"
#include "cppa/
actor_behavi
or.hpp"
#include "cppa/
scheduled_act
or.hpp"
#include "cppa/scheduling_hint.hpp"
#include "cppa/scheduling_hint.hpp"
#include "cppa/event_based_actor.hpp"
#include "cppa/event_based_actor.hpp"
...
@@ -461,13 +461,13 @@ inline void trap_exit(bool new_value)
...
@@ -461,13 +461,13 @@ inline void trap_exit(bool new_value)
self
()
->
trap_exit
(
new_value
);
self
()
->
trap_exit
(
new_value
);
}
}
inline
actor_ptr
spawn
(
actor_behavi
or
*
what
)
inline
actor_ptr
spawn
(
scheduled_act
or
*
what
)
{
{
return
get_scheduler
()
->
spawn
(
what
,
scheduled
);
return
get_scheduler
()
->
spawn
(
what
,
scheduled
);
}
}
template
<
scheduling_hint
Hint
>
template
<
scheduling_hint
Hint
>
inline
actor_ptr
spawn
(
actor_behavi
or
*
what
)
inline
actor_ptr
spawn
(
scheduled_act
or
*
what
)
{
{
return
get_scheduler
()
->
spawn
(
what
,
Hint
);
return
get_scheduler
()
->
spawn
(
what
,
Hint
);
}
}
...
@@ -487,7 +487,7 @@ inline actor_ptr spawn(abstract_event_based_actor* what)
...
@@ -487,7 +487,7 @@ inline actor_ptr spawn(abstract_event_based_actor* what)
template
<
scheduling_hint
Hint
,
typename
F
,
typename
...
Args
>
template
<
scheduling_hint
Hint
,
typename
F
,
typename
...
Args
>
auto
//actor_ptr
auto
//actor_ptr
spawn
(
F
&&
what
,
const
Args
&
...
args
)
spawn
(
F
&&
what
,
const
Args
&
...
args
)
->
typename
util
::
disable_if_c
<
std
::
is_convertible
<
typename
util
::
rm_ref
<
F
>::
type
,
actor_behavi
or
*>::
value
->
typename
util
::
disable_if_c
<
std
::
is_convertible
<
typename
util
::
rm_ref
<
F
>::
type
,
scheduled_act
or
*>::
value
||
std
::
is_convertible
<
typename
util
::
rm_ref
<
F
>::
type
,
event_based_actor
*>::
value
,
||
std
::
is_convertible
<
typename
util
::
rm_ref
<
F
>::
type
,
event_based_actor
*>::
value
,
actor_ptr
>::
type
actor_ptr
>::
type
{
{
...
@@ -506,7 +506,7 @@ spawn(F&& what, const Args&... args)
...
@@ -506,7 +506,7 @@ spawn(F&& what, const Args&... args)
template
<
typename
F
,
typename
...
Args
>
template
<
typename
F
,
typename
...
Args
>
auto
// actor_ptr
auto
// actor_ptr
spawn
(
F
&&
what
,
const
Args
&
...
args
)
spawn
(
F
&&
what
,
const
Args
&
...
args
)
->
typename
util
::
disable_if_c
<
std
::
is_convertible
<
typename
util
::
rm_ref
<
F
>::
type
,
actor_behavi
or
*>::
value
->
typename
util
::
disable_if_c
<
std
::
is_convertible
<
typename
util
::
rm_ref
<
F
>::
type
,
scheduled_act
or
*>::
value
||
std
::
is_convertible
<
typename
util
::
rm_ref
<
F
>::
type
,
event_based_actor
*>::
value
,
||
std
::
is_convertible
<
typename
util
::
rm_ref
<
F
>::
type
,
event_based_actor
*>::
value
,
actor_ptr
>::
type
actor_ptr
>::
type
{
{
...
...
cppa/detail/scheduled_actor.hpp
→
cppa/detail/
abstract_
scheduled_actor.hpp
View file @
920472e6
...
@@ -2,14 +2,14 @@
...
@@ -2,14 +2,14 @@
#define SCHEDULED_ACTOR_HPP
#define SCHEDULED_ACTOR_HPP
#include "cppa/local_actor.hpp"
#include "cppa/local_actor.hpp"
#include "cppa/actor_behavior.hpp"
#include "cppa/scheduled_actor.hpp"
#include "cppa/abstract_actor.hpp"
#include "cppa/util/fiber.hpp"
#include "cppa/util/fiber.hpp"
#include "cppa/util/singly_linked_list.hpp"
#include "cppa/util/singly_linked_list.hpp"
#include "cppa/util/single_reader_queue.hpp"
#include "cppa/util/single_reader_queue.hpp"
#include "cppa/detail/delegate.hpp"
#include "cppa/detail/delegate.hpp"
#include "cppa/detail/abstract_actor.hpp"
namespace
cppa
{
namespace
detail
{
namespace
cppa
{
namespace
detail
{
...
@@ -18,13 +18,13 @@ class task_scheduler;
...
@@ -18,13 +18,13 @@ class task_scheduler;
/**
/**
* @brief A spawned, scheduled Actor.
* @brief A spawned, scheduled Actor.
*/
*/
class
scheduled_actor
:
public
abstract_actor
<
local_actor
>
class
abstract_
scheduled_actor
:
public
abstract_actor
<
local_actor
>
{
{
friend
class
task_scheduler
;
friend
class
task_scheduler
;
friend
class
util
::
single_reader_queue
<
scheduled_actor
>
;
friend
class
util
::
single_reader_queue
<
abstract_
scheduled_actor
>
;
scheduled_actor
*
next
;
// intrusive next pointer (single_reader_queue)
abstract_scheduled_actor
*
next
;
// intrusive next pointer (single_reader_queue)
void
enqueue_node
(
queue_node
*
node
);
void
enqueue_node
(
queue_node
*
node
);
...
@@ -33,7 +33,7 @@ class scheduled_actor : public abstract_actor<local_actor>
...
@@ -33,7 +33,7 @@ class scheduled_actor : public abstract_actor<local_actor>
std
::
atomic
<
int
>
m_state
;
std
::
atomic
<
int
>
m_state
;
delegate
m_enqueue_to_scheduler
;
delegate
m_enqueue_to_scheduler
;
typedef
abstract_actor
<
local_actor
>
super
;
typedef
abstract_actor
super
;
typedef
super
::
queue_node
queue_node
;
typedef
super
::
queue_node
queue_node
;
typedef
util
::
singly_linked_list
<
queue_node
>
queue_node_buffer
;
typedef
util
::
singly_linked_list
<
queue_node
>
queue_node_buffer
;
...
@@ -87,10 +87,11 @@ class scheduled_actor : public abstract_actor<local_actor>
...
@@ -87,10 +87,11 @@ class scheduled_actor : public abstract_actor<local_actor>
static
constexpr
int
blocked
=
0x02
;
static
constexpr
int
blocked
=
0x02
;
static
constexpr
int
about_to_block
=
0x04
;
static
constexpr
int
about_to_block
=
0x04
;
scheduled_actor
();
abstract_
scheduled_actor
();
template
<
typename
Scheduler
>
template
<
typename
Scheduler
>
scheduled_actor
(
void
(
*
enqueue_fun
)(
Scheduler
*
,
scheduled_actor
*
),
abstract_scheduled_actor
(
void
(
*
enqueue_fun
)(
Scheduler
*
,
abstract_scheduled_actor
*
),
Scheduler
*
sched
)
Scheduler
*
sched
)
:
next
(
nullptr
)
:
next
(
nullptr
)
,
m_state
(
ready
)
,
m_state
(
ready
)
...
@@ -106,8 +107,6 @@ class scheduled_actor : public abstract_actor<local_actor>
...
@@ -106,8 +107,6 @@ class scheduled_actor : public abstract_actor<local_actor>
void
enqueue
(
actor
*
sender
,
const
any_tuple
&
msg
);
void
enqueue
(
actor
*
sender
,
const
any_tuple
&
msg
);
//inline std::atomic<int>& state() { return m_mailbox.m_state; }
int
compare_exchange_state
(
int
expected
,
int
new_value
);
int
compare_exchange_state
(
int
expected
,
int
new_value
);
struct
resume_callback
struct
resume_callback
...
@@ -126,7 +125,7 @@ class scheduled_actor : public abstract_actor<local_actor>
...
@@ -126,7 +125,7 @@ class scheduled_actor : public abstract_actor<local_actor>
};
};
struct
scheduled_actor_dummy
:
scheduled_actor
struct
scheduled_actor_dummy
:
abstract_
scheduled_actor
{
{
void
resume
(
util
::
fiber
*
,
resume_callback
*
);
void
resume
(
util
::
fiber
*
,
resume_callback
*
);
void
quit
(
std
::
uint32_t
);
void
quit
(
std
::
uint32_t
);
...
...
cppa/detail/converted_thread_context.hpp
View file @
920472e6
...
@@ -16,8 +16,7 @@
...
@@ -16,8 +16,7 @@
#include "cppa/pattern.hpp"
#include "cppa/pattern.hpp"
#include "cppa/local_actor.hpp"
#include "cppa/local_actor.hpp"
#include "cppa/exit_reason.hpp"
#include "cppa/exit_reason.hpp"
#include "cppa/abstract_actor.hpp"
#include "cppa/detail/abstract_actor.hpp"
#include "cppa/util/either.hpp"
#include "cppa/util/either.hpp"
#include "cppa/util/singly_linked_list.hpp"
#include "cppa/util/singly_linked_list.hpp"
...
...
cppa/detail/get_behavior.hpp
View file @
920472e6
...
@@ -6,13 +6,13 @@
...
@@ -6,13 +6,13 @@
#include "cppa/invoke.hpp"
#include "cppa/invoke.hpp"
#include "cppa/util/rm_ref.hpp"
#include "cppa/util/rm_ref.hpp"
#include "cppa/detail/tdata.hpp"
#include "cppa/detail/tdata.hpp"
#include "cppa/
actor_behavi
or.hpp"
#include "cppa/
scheduled_act
or.hpp"
namespace
cppa
{
namespace
detail
{
namespace
cppa
{
namespace
detail
{
// default: <true, false, F>
// default: <true, false, F>
template
<
bool
IsFunctionPtr
,
bool
HasArguments
,
typename
F
,
typename
...
Args
>
template
<
bool
IsFunctionPtr
,
bool
HasArguments
,
typename
F
,
typename
...
Args
>
class
ftor_behavior
:
public
actor_behavi
or
class
ftor_behavior
:
public
scheduled_act
or
{
{
F
m_fun
;
F
m_fun
;
...
@@ -26,7 +26,7 @@ class ftor_behavior : public actor_behavior
...
@@ -26,7 +26,7 @@ class ftor_behavior : public actor_behavior
};
};
template
<
typename
F
,
typename
...
Args
>
template
<
typename
F
,
typename
...
Args
>
class
ftor_behavior
<
true
,
true
,
F
,
Args
...
>
:
public
actor_behavi
or
class
ftor_behavior
<
true
,
true
,
F
,
Args
...
>
:
public
scheduled_act
or
{
{
static_assert
(
sizeof
...(
Args
)
>
0
,
"sizeof...(Args) == 0"
);
static_assert
(
sizeof
...(
Args
)
>
0
,
"sizeof...(Args) == 0"
);
...
@@ -43,7 +43,7 @@ class ftor_behavior<true, true, F, Args...> : public actor_behavior
...
@@ -43,7 +43,7 @@ class ftor_behavior<true, true, F, Args...> : public actor_behavior
};
};
template
<
typename
F
>
template
<
typename
F
>
class
ftor_behavior
<
false
,
false
,
F
>
:
public
actor_behavi
or
class
ftor_behavior
<
false
,
false
,
F
>
:
public
scheduled_act
or
{
{
F
m_fun
;
F
m_fun
;
...
@@ -59,7 +59,7 @@ class ftor_behavior<false, false, F> : public actor_behavior
...
@@ -59,7 +59,7 @@ class ftor_behavior<false, false, F> : public actor_behavior
};
};
template
<
typename
F
,
typename
...
Args
>
template
<
typename
F
,
typename
...
Args
>
class
ftor_behavior
<
false
,
true
,
F
,
Args
...
>
:
public
actor_behavi
or
class
ftor_behavior
<
false
,
true
,
F
,
Args
...
>
:
public
scheduled_act
or
{
{
static_assert
(
sizeof
...(
Args
)
>
0
,
"sizeof...(Args) == 0"
);
static_assert
(
sizeof
...(
Args
)
>
0
,
"sizeof...(Args) == 0"
);
...
@@ -83,9 +83,9 @@ class ftor_behavior<false, true, F, Args...> : public actor_behavior
...
@@ -83,9 +83,9 @@ class ftor_behavior<false, true, F, Args...> : public actor_behavior
};
};
template
<
typename
R
>
template
<
typename
R
>
actor_behavi
or
*
get_behavior
(
std
::
integral_constant
<
bool
,
true
>
,
R
(
*
fptr
)())
scheduled_act
or
*
get_behavior
(
std
::
integral_constant
<
bool
,
true
>
,
R
(
*
fptr
)())
{
{
static_assert
(
std
::
is_convertible
<
R
,
actor_behavi
or
*>::
value
==
false
,
static_assert
(
std
::
is_convertible
<
R
,
scheduled_act
or
*>::
value
==
false
,
"Spawning a function returning an actor_behavior? "
"Spawning a function returning an actor_behavior? "
"Are you sure that you do not want to spawn the behavior "
"Are you sure that you do not want to spawn the behavior "
"returned by that function?"
);
"returned by that function?"
);
...
@@ -93,9 +93,9 @@ actor_behavior* get_behavior(std::integral_constant<bool,true>, R (*fptr)())
...
@@ -93,9 +93,9 @@ actor_behavior* get_behavior(std::integral_constant<bool,true>, R (*fptr)())
}
}
template
<
typename
F
>
template
<
typename
F
>
actor_behavi
or
*
get_behavior
(
std
::
integral_constant
<
bool
,
false
>
,
F
&&
ftor
)
scheduled_act
or
*
get_behavior
(
std
::
integral_constant
<
bool
,
false
>
,
F
&&
ftor
)
{
{
static_assert
(
std
::
is_convertible
<
decltype
(
ftor
()),
actor_behavi
or
*>::
value
==
false
,
static_assert
(
std
::
is_convertible
<
decltype
(
ftor
()),
scheduled_act
or
*>::
value
==
false
,
"Spawning a functor returning an actor_behavior? "
"Spawning a functor returning an actor_behavior? "
"Are you sure that you do not want to spawn the behavior "
"Are you sure that you do not want to spawn the behavior "
"returned by that functor?"
);
"returned by that functor?"
);
...
@@ -104,12 +104,12 @@ actor_behavior* get_behavior(std::integral_constant<bool,false>, F&& ftor)
...
@@ -104,12 +104,12 @@ actor_behavior* get_behavior(std::integral_constant<bool,false>, F&& ftor)
}
}
template
<
typename
F
,
typename
Arg0
,
typename
...
Args
>
template
<
typename
F
,
typename
Arg0
,
typename
...
Args
>
actor_behavi
or
*
get_behavior
(
std
::
integral_constant
<
bool
,
true
>
,
scheduled_act
or
*
get_behavior
(
std
::
integral_constant
<
bool
,
true
>
,
F
fptr
,
F
fptr
,
const
Arg0
&
arg0
,
const
Arg0
&
arg0
,
const
Args
&
...
args
)
const
Args
&
...
args
)
{
{
static_assert
(
std
::
is_convertible
<
decltype
(
fptr
(
arg0
,
args
...)),
actor_behavi
or
*>::
value
==
false
,
static_assert
(
std
::
is_convertible
<
decltype
(
fptr
(
arg0
,
args
...)),
scheduled_act
or
*>::
value
==
false
,
"Spawning a function returning an actor_behavior? "
"Spawning a function returning an actor_behavior? "
"Are you sure that you do not want to spawn the behavior "
"Are you sure that you do not want to spawn the behavior "
"returned by that function?"
);
"returned by that function?"
);
...
@@ -118,12 +118,12 @@ actor_behavior* get_behavior(std::integral_constant<bool,true>,
...
@@ -118,12 +118,12 @@ actor_behavior* get_behavior(std::integral_constant<bool,true>,
}
}
template
<
typename
F
,
typename
Arg0
,
typename
...
Args
>
template
<
typename
F
,
typename
Arg0
,
typename
...
Args
>
actor_behavi
or
*
get_behavior
(
std
::
integral_constant
<
bool
,
false
>
,
scheduled_act
or
*
get_behavior
(
std
::
integral_constant
<
bool
,
false
>
,
F
ftor
,
F
ftor
,
const
Arg0
&
arg0
,
const
Arg0
&
arg0
,
const
Args
&
...
args
)
const
Args
&
...
args
)
{
{
static_assert
(
std
::
is_convertible
<
decltype
(
ftor
(
arg0
,
args
...)),
actor_behavi
or
*>::
value
==
false
,
static_assert
(
std
::
is_convertible
<
decltype
(
ftor
(
arg0
,
args
...)),
scheduled_act
or
*>::
value
==
false
,
"Spawning a functor returning an actor_behavior? "
"Spawning a functor returning an actor_behavior? "
"Are you sure that you do not want to spawn the behavior "
"Are you sure that you do not want to spawn the behavior "
"returned by that functor?"
);
"returned by that functor?"
);
...
...
cppa/detail/mock_scheduler.hpp
View file @
920472e6
...
@@ -12,9 +12,9 @@ class mock_scheduler : public scheduler
...
@@ -12,9 +12,9 @@ class mock_scheduler : public scheduler
actor_ptr
spawn
(
abstract_event_based_actor
*
what
);
actor_ptr
spawn
(
abstract_event_based_actor
*
what
);
actor_ptr
spawn
(
actor_behavi
or
*
,
scheduling_hint
);
actor_ptr
spawn
(
scheduled_act
or
*
,
scheduling_hint
);
static
actor_ptr
spawn
(
actor_behavi
or
*
);
static
actor_ptr
spawn
(
scheduled_act
or
*
);
};
};
...
...
cppa/detail/task_scheduler.hpp
View file @
920472e6
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
#include "cppa/scheduler.hpp"
#include "cppa/scheduler.hpp"
#include "cppa/detail/thread.hpp"
#include "cppa/detail/thread.hpp"
#include "cppa/detail/scheduled_actor.hpp"
#include "cppa/detail/
abstract_
scheduled_actor.hpp"
#include "cppa/util/single_reader_queue.hpp"
#include "cppa/util/single_reader_queue.hpp"
namespace
cppa
{
namespace
detail
{
namespace
cppa
{
namespace
detail
{
...
@@ -13,13 +13,13 @@ class task_scheduler : public scheduler
...
@@ -13,13 +13,13 @@ class task_scheduler : public scheduler
typedef
scheduler
super
;
typedef
scheduler
super
;
typedef
util
::
single_reader_queue
<
scheduled_actor
>
job_queue
;
typedef
util
::
single_reader_queue
<
abstract_
scheduled_actor
>
job_queue
;
job_queue
m_queue
;
job_queue
m_queue
;
scheduled_actor_dummy
m_dummy
;
scheduled_actor_dummy
m_dummy
;
thread
m_worker
;
thread
m_worker
;
static
void
worker_loop
(
job_queue
*
,
scheduled_actor
*
dummy
);
static
void
worker_loop
(
job_queue
*
,
abstract_
scheduled_actor
*
dummy
);
public:
public:
...
@@ -27,15 +27,15 @@ class task_scheduler : public scheduler
...
@@ -27,15 +27,15 @@ class task_scheduler : public scheduler
virtual
void
stop
();
virtual
void
stop
();
void
schedule
(
scheduled_actor
*
what
);
void
schedule
(
abstract_
scheduled_actor
*
what
);
actor_ptr
spawn
(
abstract_event_based_actor
*
what
);
actor_ptr
spawn
(
abstract_event_based_actor
*
what
);
actor_ptr
spawn
(
actor_behavi
or
*
,
scheduling_hint
);
actor_ptr
spawn
(
scheduled_act
or
*
,
scheduling_hint
);
private:
private:
actor_ptr
spawn_impl
(
scheduled_actor
*
what
);
actor_ptr
spawn_impl
(
abstract_
scheduled_actor
*
what
);
};
};
...
...
cppa/detail/thread_pool_scheduler.hpp
View file @
920472e6
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
#include "cppa/scheduler.hpp"
#include "cppa/scheduler.hpp"
#include "cppa/detail/thread.hpp"
#include "cppa/detail/thread.hpp"
#include "cppa/detail/scheduled_actor.hpp"
#include "cppa/detail/
abstract_
scheduled_actor.hpp"
namespace
cppa
{
namespace
detail
{
namespace
cppa
{
namespace
detail
{
...
@@ -20,24 +20,24 @@ class thread_pool_scheduler : public scheduler
...
@@ -20,24 +20,24 @@ class thread_pool_scheduler : public scheduler
void
stop
()
/*override*/
;
void
stop
()
/*override*/
;
void
schedule
(
scheduled_actor
*
what
)
/*override*/
;
void
schedule
(
abstract_
scheduled_actor
*
what
)
/*override*/
;
actor_ptr
spawn
(
abstract_event_based_actor
*
what
);
actor_ptr
spawn
(
abstract_event_based_actor
*
what
);
actor_ptr
spawn
(
actor_behavi
or
*
behavior
,
scheduling_hint
hint
);
actor_ptr
spawn
(
scheduled_act
or
*
behavior
,
scheduling_hint
hint
);
private:
private:
typedef
util
::
single_reader_queue
<
scheduled_actor
>
job_queue
;
typedef
util
::
single_reader_queue
<
abstract_
scheduled_actor
>
job_queue
;
job_queue
m_queue
;
job_queue
m_queue
;
scheduled_actor_dummy
m_dummy
;
scheduled_actor_dummy
m_dummy
;
thread
m_supervisor
;
thread
m_supervisor
;
actor_ptr
spawn_impl
(
scheduled_actor
*
what
);
actor_ptr
spawn_impl
(
abstract_
scheduled_actor
*
what
);
static
void
worker_loop
(
worker
*
);
static
void
worker_loop
(
worker
*
);
static
void
supervisor_loop
(
job_queue
*
,
scheduled_actor
*
);
static
void
supervisor_loop
(
job_queue
*
,
abstract_
scheduled_actor
*
);
};
};
...
...
cppa/detail/yielding_actor.hpp
View file @
920472e6
...
@@ -6,7 +6,7 @@
...
@@ -6,7 +6,7 @@
#include "cppa/pattern.hpp"
#include "cppa/pattern.hpp"
#include "cppa/detail/delegate.hpp"
#include "cppa/detail/delegate.hpp"
#include "cppa/detail/scheduled_actor.hpp"
#include "cppa/detail/
abstract_
scheduled_actor.hpp"
#include "cppa/detail/yield_interface.hpp"
#include "cppa/detail/yield_interface.hpp"
#include "cppa/util/either.hpp"
#include "cppa/util/either.hpp"
...
@@ -14,15 +14,15 @@
...
@@ -14,15 +14,15 @@
namespace
cppa
{
namespace
detail
{
namespace
cppa
{
namespace
detail
{
class
yielding_actor
:
public
scheduled_actor
class
yielding_actor
:
public
abstract_
scheduled_actor
{
{
typedef
scheduled_actor
super
;
typedef
abstract_
scheduled_actor
super
;
typedef
super
::
queue_node
queue_node
;
typedef
super
::
queue_node
queue_node
;
typedef
util
::
singly_linked_list
<
queue_node
>
queue_node_buffer
;
typedef
util
::
singly_linked_list
<
queue_node
>
queue_node_buffer
;
util
::
fiber
m_fiber
;
util
::
fiber
m_fiber
;
actor_behavi
or
*
m_behavior
;
scheduled_act
or
*
m_behavior
;
static
void
run
(
void
*
_this
);
static
void
run
(
void
*
_this
);
...
@@ -33,8 +33,8 @@ class yielding_actor : public scheduled_actor
...
@@ -33,8 +33,8 @@ class yielding_actor : public scheduled_actor
public:
public:
template
<
typename
Scheduler
>
template
<
typename
Scheduler
>
yielding_actor
(
actor_behavi
or
*
behavior
,
yielding_actor
(
scheduled_act
or
*
behavior
,
void
(
*
enqueue_fun
)(
Scheduler
*
,
scheduled_actor
*
),
void
(
*
enqueue_fun
)(
Scheduler
*
,
abstract_
scheduled_actor
*
),
Scheduler
*
sched
)
Scheduler
*
sched
)
:
super
(
enqueue_fun
,
sched
)
:
super
(
enqueue_fun
,
sched
)
,
m_fiber
(
&
yielding_actor
::
run
,
this
)
,
m_fiber
(
&
yielding_actor
::
run
,
this
)
...
...
cppa/fsm_actor.hpp
0 → 100644
View file @
920472e6
#ifndef FSM_ACTOR_HPP
#define FSM_ACTOR_HPP
#include "cppa/event_based_actor.hpp"
namespace
cppa
{
template
<
class
Derived
>
class
fsm_actor
:
public
event_based_actor
{
public:
void
init
()
{
become
(
&
(
static_cast
<
Derived
*>
(
this
)
->
init_state
));
}
};
}
// namespace cppa
#endif // FSM_ACTOR_HPP
cppa/
actor_behavi
or.hpp
→
cppa/
scheduled_act
or.hpp
View file @
920472e6
...
@@ -3,12 +3,12 @@
...
@@ -3,12 +3,12 @@
namespace
cppa
{
namespace
cppa
{
class
actor_behavi
or
class
scheduled_act
or
{
{
public:
public:
virtual
~
actor_behavi
or
();
virtual
~
scheduled_act
or
();
virtual
void
on_exit
();
virtual
void
on_exit
();
virtual
void
act
()
=
0
;
virtual
void
act
()
=
0
;
...
...
cppa/scheduler.hpp
View file @
920472e6
...
@@ -18,7 +18,7 @@
...
@@ -18,7 +18,7 @@
namespace
cppa
{
namespace
cppa
{
//class local_actor;
//class local_actor;
class
actor_behavi
or
;
class
scheduled_act
or
;
class
scheduler_helper
;
class
scheduler_helper
;
/**
/**
...
@@ -53,7 +53,7 @@ class scheduler
...
@@ -53,7 +53,7 @@ class scheduler
* @brief Spawns a new actor that executes <code>behavior->act()</code>
* @brief Spawns a new actor that executes <code>behavior->act()</code>
* with the scheduling policy @p hint if possible.
* with the scheduling policy @p hint if possible.
*/
*/
virtual
actor_ptr
spawn
(
actor_behavi
or
*
behavior
,
virtual
actor_ptr
spawn
(
scheduled_act
or
*
behavior
,
scheduling_hint
hint
)
=
0
;
scheduling_hint
hint
)
=
0
;
/**
/**
...
...
src/abstract_event_based_actor.cpp
View file @
920472e6
...
@@ -64,7 +64,7 @@ void abstract_event_based_actor::resume(util::fiber*, resume_callback* callback)
...
@@ -64,7 +64,7 @@ void abstract_event_based_actor::resume(util::fiber*, resume_callback* callback)
set_self
(
this
);
set_self
(
this
);
auto
done_cb
=
[
&
]()
auto
done_cb
=
[
&
]()
{
{
m_state
.
store
(
scheduled_actor
::
done
);
m_state
.
store
(
abstract_
scheduled_actor
::
done
);
while
(
!
m_loop_stack
.
empty
())
m_loop_stack
.
pop
();
while
(
!
m_loop_stack
.
empty
())
m_loop_stack
.
pop
();
on_exit
();
on_exit
();
callback
->
exec_done
();
callback
->
exec_done
();
...
@@ -82,25 +82,25 @@ void abstract_event_based_actor::resume(util::fiber*, resume_callback* callback)
...
@@ -82,25 +82,25 @@ void abstract_event_based_actor::resume(util::fiber*, resume_callback* callback)
}
}
else
if
(
m_mailbox
.
empty
())
else
if
(
m_mailbox
.
empty
())
{
{
m_state
.
store
(
scheduled_actor
::
about_to_block
);
m_state
.
store
(
abstract_
scheduled_actor
::
about_to_block
);
CPPA_MEMORY_BARRIER
();
CPPA_MEMORY_BARRIER
();
if
(
!
m_mailbox
.
empty
())
if
(
!
m_mailbox
.
empty
())
{
{
// someone preempt us
// someone preempt us
m_state
.
store
(
scheduled_actor
::
ready
);
m_state
.
store
(
abstract_
scheduled_actor
::
ready
);
}
}
else
else
{
{
// nothing to do (wait for new messages)
// nothing to do (wait for new messages)
switch
(
compare_exchange_state
(
scheduled_actor
::
about_to_block
,
switch
(
compare_exchange_state
(
abstract_
scheduled_actor
::
about_to_block
,
scheduled_actor
::
blocked
))
abstract_
scheduled_actor
::
blocked
))
{
{
case
scheduled_actor
:
:
ready
:
case
abstract_
scheduled_actor
:
:
ready
:
{
{
// got a new job
// got a new job
break
;
break
;
}
}
case
scheduled_actor
:
:
blocked
:
case
abstract_
scheduled_actor
:
:
blocked
:
{
{
// done
// done
return
;
return
;
...
...
src/abstract_scheduled_actor.cpp
0 → 100644
View file @
920472e6
#include "cppa/cppa.hpp"
#include "cppa/exception.hpp"
#include "cppa/detail/task_scheduler.hpp"
#include "cppa/detail/abstract_scheduled_actor.hpp"
#include "cppa/detail/yield_interface.hpp"
namespace
{
void
dummy_enqueue
(
void
*
,
cppa
::
detail
::
abstract_scheduled_actor
*
)
{
}
}
namespace
cppa
{
namespace
detail
{
abstract_scheduled_actor
::
abstract_scheduled_actor
()
:
next
(
nullptr
)
,
m_state
(
abstract_scheduled_actor
::
done
)
,
m_enqueue_to_scheduler
(
dummy_enqueue
,
static_cast
<
void
*>
(
nullptr
),
this
)
,
m_has_pending_timeout_request
(
false
)
,
m_active_timeout_id
(
0
)
{
}
abstract_scheduled_actor
::
resume_callback
::~
resume_callback
()
{
}
void
abstract_scheduled_actor
::
quit
(
std
::
uint32_t
reason
)
{
cleanup
(
reason
);
throw
actor_exited
(
reason
);
//yield(yield_state::done);
}
void
abstract_scheduled_actor
::
enqueue_node
(
queue_node
*
node
)
{
if
(
m_mailbox
.
_push_back
(
node
))
{
for
(;;)
{
int
state
=
m_state
.
load
();
switch
(
state
)
{
case
blocked
:
{
if
(
m_state
.
compare_exchange_weak
(
state
,
ready
))
{
m_enqueue_to_scheduler
();
return
;
}
break
;
}
case
about_to_block
:
{
if
(
m_state
.
compare_exchange_weak
(
state
,
ready
))
{
return
;
}
break
;
}
default:
return
;
}
}
}
}
void
abstract_scheduled_actor
::
enqueue
(
actor
*
sender
,
any_tuple
&&
msg
)
{
enqueue_node
(
new
queue_node
(
sender
,
std
::
move
(
msg
)));
}
void
abstract_scheduled_actor
::
enqueue
(
actor
*
sender
,
const
any_tuple
&
msg
)
{
enqueue_node
(
new
queue_node
(
sender
,
msg
));
}
int
abstract_scheduled_actor
::
compare_exchange_state
(
int
expected
,
int
new_value
)
{
int
e
=
expected
;
do
{
if
(
m_state
.
compare_exchange_weak
(
e
,
new_value
))
{
return
new_value
;
}
}
while
(
e
==
expected
);
return
e
;
}
void
abstract_scheduled_actor
::
request_timeout
(
const
util
::
duration
&
d
)
{
future_send
(
this
,
d
,
atom
(
":Timeout"
),
++
m_active_timeout_id
);
m_has_pending_timeout_request
=
true
;
}
abstract_scheduled_actor
::
filter_result
abstract_scheduled_actor
::
filter_msg
(
const
any_tuple
&
msg
)
{
if
(
m_pattern
(
msg
))
{
auto
v0
=
*
reinterpret_cast
<
const
atom_value
*>
(
msg
.
at
(
0
));
auto
v1
=
*
reinterpret_cast
<
const
std
::
uint32_t
*>
(
msg
.
at
(
1
));
if
(
v0
==
atom
(
":Exit"
))
{
if
(
m_trap_exit
==
false
)
{
if
(
v1
!=
exit_reason
::
normal
)
{
quit
(
v1
);
}
return
normal_exit_signal
;
}
}
else
if
(
v0
==
atom
(
":Timeout"
))
{
return
(
v1
==
m_active_timeout_id
)
?
timeout_message
:
expired_timeout_message
;
}
}
return
ordinary_message
;
}
abstract_scheduled_actor
::
dq_result
abstract_scheduled_actor
::
dq
(
std
::
unique_ptr
<
queue_node
>&
node
,
invoke_rules_base
&
rules
,
queue_node_buffer
&
buffer
)
{
switch
(
filter_msg
(
node
->
msg
))
{
case
normal_exit_signal
:
case
expired_timeout_message
:
{
// skip message
return
dq_indeterminate
;
}
case
timeout_message
:
{
// m_active_timeout_id is already invalid
m_has_pending_timeout_request
=
false
;
// restore mailbox before calling client
if
(
!
buffer
.
empty
())
{
m_mailbox
.
push_front
(
std
::
move
(
buffer
));
buffer
.
clear
();
}
return
dq_timeout_occured
;
}
default:
break
;
}
auto
imd
=
rules
.
get_intermediate
(
node
->
msg
);
if
(
imd
)
{
m_last_dequeued
=
std
::
move
(
node
->
msg
);
m_last_sender
=
std
::
move
(
node
->
sender
);
// restore mailbox before invoking imd
if
(
!
buffer
.
empty
())
{
m_mailbox
.
push_front
(
std
::
move
(
buffer
));
buffer
.
clear
();
}
// expire pending request
if
(
m_has_pending_timeout_request
)
{
++
m_active_timeout_id
;
m_has_pending_timeout_request
=
false
;
}
imd
->
invoke
();
return
dq_done
;
}
else
{
buffer
.
push_back
(
node
.
release
());
return
dq_indeterminate
;
}
}
// dummy
void
scheduled_actor_dummy
::
resume
(
util
::
fiber
*
,
resume_callback
*
)
{
}
void
scheduled_actor_dummy
::
quit
(
std
::
uint32_t
)
{
}
void
scheduled_actor_dummy
::
dequeue
(
invoke_rules
&
)
{
}
void
scheduled_actor_dummy
::
dequeue
(
timed_invoke_rules
&
)
{
}
void
scheduled_actor_dummy
::
link_to
(
intrusive_ptr
<
actor
>&
)
{
}
void
scheduled_actor_dummy
::
unlink_from
(
intrusive_ptr
<
actor
>&
)
{
}
bool
scheduled_actor_dummy
::
establish_backlink
(
intrusive_ptr
<
actor
>&
)
{
return
false
;
}
bool
scheduled_actor_dummy
::
remove_backlink
(
intrusive_ptr
<
actor
>&
)
{
return
false
;
}
void
scheduled_actor_dummy
::
detach
(
const
attachable
::
token
&
)
{
}
bool
scheduled_actor_dummy
::
attach
(
attachable
*
)
{
return
false
;
}
}
}
// namespace cppa::detail
src/actor_behavior.cpp
deleted
100644 → 0
View file @
99626f2c
#include "cppa/actor_behavior.hpp"
namespace
cppa
{
actor_behavior
::~
actor_behavior
()
{
}
void
actor_behavior
::
on_exit
()
{
}
}
// namespace cppa
src/mock_scheduler.cpp
View file @
920472e6
...
@@ -9,7 +9,7 @@
...
@@ -9,7 +9,7 @@
#include "cppa/scheduler.hpp"
#include "cppa/scheduler.hpp"
#include "cppa/attachable.hpp"
#include "cppa/attachable.hpp"
#include "cppa/invoke_rules.hpp"
#include "cppa/invoke_rules.hpp"
#include "cppa/
actor_behavi
or.hpp"
#include "cppa/
scheduled_act
or.hpp"
#include "cppa/detail/thread.hpp"
#include "cppa/detail/thread.hpp"
#include "cppa/detail/actor_count.hpp"
#include "cppa/detail/actor_count.hpp"
...
@@ -23,7 +23,7 @@ using std::endl;
...
@@ -23,7 +23,7 @@ using std::endl;
namespace
{
namespace
{
void
run_actor
(
cppa
::
intrusive_ptr
<
cppa
::
local_actor
>
m_self
,
void
run_actor
(
cppa
::
intrusive_ptr
<
cppa
::
local_actor
>
m_self
,
cppa
::
actor_behavi
or
*
behavior
)
cppa
::
scheduled_act
or
*
behavior
)
{
{
cppa
::
set_self
(
m_self
.
get
());
cppa
::
set_self
(
m_self
.
get
());
if
(
behavior
)
if
(
behavior
)
...
@@ -41,7 +41,7 @@ void run_actor(cppa::intrusive_ptr<cppa::local_actor> m_self,
...
@@ -41,7 +41,7 @@ void run_actor(cppa::intrusive_ptr<cppa::local_actor> m_self,
namespace
cppa
{
namespace
detail
{
namespace
cppa
{
namespace
detail
{
actor_ptr
mock_scheduler
::
spawn
(
actor_behavi
or
*
behavior
)
actor_ptr
mock_scheduler
::
spawn
(
scheduled_act
or
*
behavior
)
{
{
inc_actor_count
();
inc_actor_count
();
CPPA_MEMORY_BARRIER
();
CPPA_MEMORY_BARRIER
();
...
@@ -57,7 +57,7 @@ actor_ptr mock_scheduler::spawn(abstract_event_based_actor* what)
...
@@ -57,7 +57,7 @@ actor_ptr mock_scheduler::spawn(abstract_event_based_actor* what)
return
nullptr
;
return
nullptr
;
}
}
actor_ptr
mock_scheduler
::
spawn
(
actor_behavi
or
*
behavior
,
scheduling_hint
)
actor_ptr
mock_scheduler
::
spawn
(
scheduled_act
or
*
behavior
,
scheduling_hint
)
{
{
return
spawn
(
behavior
);
return
spawn
(
behavior
);
}
}
...
...
src/scheduled_actor.cpp
View file @
920472e6
#include "cppa/cppa.hpp"
#include "cppa/scheduled_actor.hpp"
#include "cppa/exception.hpp"
#include "cppa/detail/task_scheduler.hpp"
#include "cppa/detail/scheduled_actor.hpp"
#include "cppa/detail/yield_interface.hpp"
namespace
{
void
dummy_enqueue
(
void
*
,
cppa
::
detail
::
scheduled_actor
*
)
{
}
}
namespace
cppa
{
namespace
cppa
{
namespace
detail
{
scheduled_actor
::~
scheduled_actor
()
scheduled_actor
::
scheduled_actor
()
:
next
(
nullptr
)
,
m_state
(
scheduled_actor
::
done
)
,
m_enqueue_to_scheduler
(
dummy_enqueue
,
static_cast
<
void
*>
(
nullptr
),
this
)
,
m_has_pending_timeout_request
(
false
)
,
m_active_timeout_id
(
0
)
{
}
scheduled_actor
::
resume_callback
::~
resume_callback
()
{
}
void
scheduled_actor
::
quit
(
std
::
uint32_t
reason
)
{
cleanup
(
reason
);
throw
actor_exited
(
reason
);
//yield(yield_state::done);
}
void
scheduled_actor
::
enqueue_node
(
queue_node
*
node
)
{
if
(
m_mailbox
.
_push_back
(
node
))
{
for
(;;)
{
int
state
=
m_state
.
load
();
switch
(
state
)
{
case
blocked
:
{
if
(
m_state
.
compare_exchange_weak
(
state
,
ready
))
{
m_enqueue_to_scheduler
();
return
;
}
break
;
}
case
about_to_block
:
{
if
(
m_state
.
compare_exchange_weak
(
state
,
ready
))
{
return
;
}
break
;
}
default:
return
;
}
}
}
}
void
scheduled_actor
::
enqueue
(
actor
*
sender
,
any_tuple
&&
msg
)
{
enqueue_node
(
new
queue_node
(
sender
,
std
::
move
(
msg
)));
}
void
scheduled_actor
::
enqueue
(
actor
*
sender
,
const
any_tuple
&
msg
)
{
enqueue_node
(
new
queue_node
(
sender
,
msg
));
}
int
scheduled_actor
::
compare_exchange_state
(
int
expected
,
int
new_value
)
{
int
e
=
expected
;
do
{
if
(
m_state
.
compare_exchange_weak
(
e
,
new_value
))
{
return
new_value
;
}
}
while
(
e
==
expected
);
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
)
{
if
(
m_pattern
(
msg
))
{
auto
v0
=
*
reinterpret_cast
<
const
atom_value
*>
(
msg
.
at
(
0
));
auto
v1
=
*
reinterpret_cast
<
const
std
::
uint32_t
*>
(
msg
.
at
(
1
));
if
(
v0
==
atom
(
":Exit"
))
{
if
(
m_trap_exit
==
false
)
{
if
(
v1
!=
exit_reason
::
normal
)
{
quit
(
v1
);
}
return
normal_exit_signal
;
}
}
else
if
(
v0
==
atom
(
":Timeout"
))
{
return
(
v1
==
m_active_timeout_id
)
?
timeout_message
:
expired_timeout_message
;
}
}
return
ordinary_message
;
}
scheduled_actor
::
dq_result
scheduled_actor
::
dq
(
std
::
unique_ptr
<
queue_node
>&
node
,
invoke_rules_base
&
rules
,
queue_node_buffer
&
buffer
)
{
switch
(
filter_msg
(
node
->
msg
))
{
case
normal_exit_signal
:
case
expired_timeout_message
:
{
// skip message
return
dq_indeterminate
;
}
case
timeout_message
:
{
// m_active_timeout_id is already invalid
m_has_pending_timeout_request
=
false
;
// restore mailbox before calling client
if
(
!
buffer
.
empty
())
{
m_mailbox
.
push_front
(
std
::
move
(
buffer
));
buffer
.
clear
();
}
return
dq_timeout_occured
;
}
default:
break
;
}
auto
imd
=
rules
.
get_intermediate
(
node
->
msg
);
if
(
imd
)
{
m_last_dequeued
=
std
::
move
(
node
->
msg
);
m_last_sender
=
std
::
move
(
node
->
sender
);
// restore mailbox before invoking imd
if
(
!
buffer
.
empty
())
{
m_mailbox
.
push_front
(
std
::
move
(
buffer
));
buffer
.
clear
();
}
// expire pending request
if
(
m_has_pending_timeout_request
)
{
++
m_active_timeout_id
;
m_has_pending_timeout_request
=
false
;
}
imd
->
invoke
();
return
dq_done
;
}
else
{
buffer
.
push_back
(
node
.
release
());
return
dq_indeterminate
;
}
}
// dummy
void
scheduled_actor_dummy
::
resume
(
util
::
fiber
*
,
resume_callback
*
)
{
}
void
scheduled_actor_dummy
::
quit
(
std
::
uint32_t
)
{
}
void
scheduled_actor_dummy
::
dequeue
(
invoke_rules
&
)
{
}
void
scheduled_actor_dummy
::
dequeue
(
timed_invoke_rules
&
)
{
}
void
scheduled_actor_dummy
::
link_to
(
intrusive_ptr
<
actor
>&
)
{
}
void
scheduled_actor_dummy
::
unlink_from
(
intrusive_ptr
<
actor
>&
)
{
}
bool
scheduled_actor_dummy
::
establish_backlink
(
intrusive_ptr
<
actor
>&
)
{
return
false
;
}
bool
scheduled_actor_dummy
::
remove_backlink
(
intrusive_ptr
<
actor
>&
)
{
return
false
;
}
void
scheduled_actor_dummy
::
detach
(
const
attachable
::
token
&
)
{
{
}
}
bool
scheduled_actor_dummy
::
attach
(
attachable
*
)
void
scheduled_actor
::
on_exit
(
)
{
{
return
false
;
}
}
}
}
// namespace cppa::detail
}
// namespace cppa
src/task_scheduler.cpp
View file @
920472e6
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
#include "cppa/config.hpp"
#include "cppa/config.hpp"
#include "cppa/local_actor.hpp"
#include "cppa/local_actor.hpp"
#include "cppa/util/fiber.hpp"
#include "cppa/util/fiber.hpp"
#include "cppa/
actor_behavi
or.hpp"
#include "cppa/
scheduled_act
or.hpp"
#include "cppa/detail/invokable.hpp"
#include "cppa/detail/invokable.hpp"
#include "cppa/detail/actor_count.hpp"
#include "cppa/detail/actor_count.hpp"
#include "cppa/detail/task_scheduler.hpp"
#include "cppa/detail/task_scheduler.hpp"
...
@@ -18,7 +18,7 @@ using std::endl;
...
@@ -18,7 +18,7 @@ using std::endl;
namespace
{
namespace
{
void
enqueue_fun
(
cppa
::
detail
::
task_scheduler
*
where
,
void
enqueue_fun
(
cppa
::
detail
::
task_scheduler
*
where
,
cppa
::
detail
::
scheduled_actor
*
what
)
cppa
::
detail
::
abstract_
scheduled_actor
*
what
)
{
{
where
->
schedule
(
what
);
where
->
schedule
(
what
);
}
}
...
@@ -27,14 +27,14 @@ void enqueue_fun(cppa::detail::task_scheduler* where,
...
@@ -27,14 +27,14 @@ void enqueue_fun(cppa::detail::task_scheduler* where,
namespace
cppa
{
namespace
detail
{
namespace
cppa
{
namespace
detail
{
void
task_scheduler
::
worker_loop
(
job_queue
*
jq
,
scheduled_actor
*
dummy
)
void
task_scheduler
::
worker_loop
(
job_queue
*
jq
,
abstract_
scheduled_actor
*
dummy
)
{
{
cppa
::
util
::
fiber
fself
;
cppa
::
util
::
fiber
fself
;
scheduled_actor
*
job
=
nullptr
;
abstract_
scheduled_actor
*
job
=
nullptr
;
struct
handler
:
scheduled_actor
::
resume_callback
struct
handler
:
abstract_
scheduled_actor
::
resume_callback
{
{
scheduled_actor
**
job_ptr
;
abstract_
scheduled_actor
**
job_ptr
;
handler
(
scheduled_actor
**
jptr
)
:
job_ptr
(
jptr
)
{
}
handler
(
abstract_
scheduled_actor
**
jptr
)
:
job_ptr
(
jptr
)
{
}
bool
still_ready
()
bool
still_ready
()
{
{
return
true
;
return
true
;
...
@@ -72,7 +72,7 @@ void task_scheduler::stop()
...
@@ -72,7 +72,7 @@ void task_scheduler::stop()
super
::
stop
();
super
::
stop
();
}
}
void
task_scheduler
::
schedule
(
scheduled_actor
*
what
)
void
task_scheduler
::
schedule
(
abstract_
scheduled_actor
*
what
)
{
{
if
(
what
)
if
(
what
)
{
{
...
@@ -87,11 +87,11 @@ void task_scheduler::schedule(scheduled_actor* what)
...
@@ -87,11 +87,11 @@ void task_scheduler::schedule(scheduled_actor* what)
}
}
}
}
actor_ptr
task_scheduler
::
spawn_impl
(
scheduled_actor
*
what
)
actor_ptr
task_scheduler
::
spawn_impl
(
abstract_
scheduled_actor
*
what
)
{
{
inc_actor_count
();
inc_actor_count
();
CPPA_MEMORY_BARRIER
();
CPPA_MEMORY_BARRIER
();
intrusive_ptr
<
scheduled_actor
>
ctx
(
what
);
intrusive_ptr
<
abstract_
scheduled_actor
>
ctx
(
what
);
// add an implicit reference to ctx
// add an implicit reference to ctx
ctx
->
ref
();
ctx
->
ref
();
m_queue
.
push_back
(
ctx
.
get
());
m_queue
.
push_back
(
ctx
.
get
());
...
@@ -104,7 +104,7 @@ actor_ptr task_scheduler::spawn(abstract_event_based_actor* what)
...
@@ -104,7 +104,7 @@ 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
));
}
}
actor_ptr
task_scheduler
::
spawn
(
actor_behavi
or
*
behavior
,
scheduling_hint
)
actor_ptr
task_scheduler
::
spawn
(
scheduled_act
or
*
behavior
,
scheduling_hint
)
{
{
return
spawn_impl
(
new
yielding_actor
(
behavior
,
enqueue_fun
,
this
));
return
spawn_impl
(
new
yielding_actor
(
behavior
,
enqueue_fun
,
this
));
}
}
...
...
src/thread_pool_scheduler.cpp
View file @
920472e6
...
@@ -16,7 +16,7 @@ namespace cppa { namespace detail {
...
@@ -16,7 +16,7 @@ namespace cppa { namespace detail {
namespace
{
namespace
{
void
enqueue_fun
(
cppa
::
detail
::
thread_pool_scheduler
*
where
,
void
enqueue_fun
(
cppa
::
detail
::
thread_pool_scheduler
*
where
,
cppa
::
detail
::
scheduled_actor
*
what
)
cppa
::
detail
::
abstract_
scheduled_actor
*
what
)
{
{
where
->
schedule
(
what
);
where
->
schedule
(
what
);
}
}
...
@@ -33,7 +33,7 @@ struct thread_pool_scheduler::worker
...
@@ -33,7 +33,7 @@ struct thread_pool_scheduler::worker
worker
*
next
;
worker
*
next
;
bool
m_done
;
bool
m_done
;
job_queue
*
m_job_queue
;
job_queue
*
m_job_queue
;
volatile
scheduled_actor
*
m_job
;
volatile
abstract_
scheduled_actor
*
m_job
;
worker_queue
*
m_supervisor_queue
;
worker_queue
*
m_supervisor_queue
;
mutex
m_mtx
;
mutex
m_mtx
;
condition_variable
m_cv
;
condition_variable
m_cv
;
...
@@ -60,11 +60,11 @@ struct thread_pool_scheduler::worker
...
@@ -60,11 +60,11 @@ struct thread_pool_scheduler::worker
// enqueue as idle worker
// enqueue as idle worker
m_supervisor_queue
->
push_back
(
this
);
m_supervisor_queue
->
push_back
(
this
);
util
::
fiber
fself
;
util
::
fiber
fself
;
struct
handler
:
scheduled_actor
::
resume_callback
struct
handler
:
abstract_
scheduled_actor
::
resume_callback
{
{
time_type
timeout
;
time_type
timeout
;
bool
reschedule
;
bool
reschedule
;
scheduled_actor
*
job
;
abstract_
scheduled_actor
*
job
;
handler
()
:
timeout
(
now
()),
reschedule
(
false
),
job
(
nullptr
)
handler
()
:
timeout
(
now
()),
reschedule
(
false
),
job
(
nullptr
)
{
{
}
}
...
@@ -97,7 +97,7 @@ struct thread_pool_scheduler::worker
...
@@ -97,7 +97,7 @@ struct thread_pool_scheduler::worker
}
}
if
(
m_done
)
return
;
if
(
m_done
)
return
;
}
}
h
.
job
=
const_cast
<
scheduled_actor
*>
(
m_job
);
h
.
job
=
const_cast
<
abstract_
scheduled_actor
*>
(
m_job
);
// run actor up to 300ms
// run actor up to 300ms
h
.
reschedule
=
false
;
h
.
reschedule
=
false
;
h
.
timeout
=
now
();
h
.
timeout
=
now
();
...
@@ -121,7 +121,7 @@ void thread_pool_scheduler::worker_loop(thread_pool_scheduler::worker* w)
...
@@ -121,7 +121,7 @@ void thread_pool_scheduler::worker_loop(thread_pool_scheduler::worker* w)
}
}
void
thread_pool_scheduler
::
supervisor_loop
(
job_queue
*
jqueue
,
void
thread_pool_scheduler
::
supervisor_loop
(
job_queue
*
jqueue
,
scheduled_actor
*
dummy
)
abstract_
scheduled_actor
*
dummy
)
{
{
worker_queue
wqueue
;
worker_queue
wqueue
;
std
::
vector
<
worker_ptr
>
workers
;
std
::
vector
<
worker_ptr
>
workers
;
...
@@ -142,7 +142,7 @@ void thread_pool_scheduler::supervisor_loop(job_queue* jqueue,
...
@@ -142,7 +142,7 @@ void thread_pool_scheduler::supervisor_loop(job_queue* jqueue,
do
do
{
{
// fetch next job
// fetch next job
scheduled_actor
*
job
=
jqueue
->
pop
();
abstract_
scheduled_actor
*
job
=
jqueue
->
pop
();
if
(
job
==
dummy
)
if
(
job
==
dummy
)
{
{
done
=
true
;
done
=
true
;
...
@@ -201,16 +201,16 @@ void thread_pool_scheduler::stop()
...
@@ -201,16 +201,16 @@ void thread_pool_scheduler::stop()
super
::
stop
();
super
::
stop
();
}
}
void
thread_pool_scheduler
::
schedule
(
scheduled_actor
*
what
)
void
thread_pool_scheduler
::
schedule
(
abstract_
scheduled_actor
*
what
)
{
{
m_queue
.
push_back
(
what
);
m_queue
.
push_back
(
what
);
}
}
actor_ptr
thread_pool_scheduler
::
spawn_impl
(
scheduled_actor
*
what
)
actor_ptr
thread_pool_scheduler
::
spawn_impl
(
abstract_
scheduled_actor
*
what
)
{
{
inc_actor_count
();
inc_actor_count
();
CPPA_MEMORY_BARRIER
();
CPPA_MEMORY_BARRIER
();
intrusive_ptr
<
scheduled_actor
>
ctx
(
what
);
intrusive_ptr
<
abstract_
scheduled_actor
>
ctx
(
what
);
ctx
->
ref
();
ctx
->
ref
();
m_queue
.
push_back
(
ctx
.
get
());
m_queue
.
push_back
(
ctx
.
get
());
return
std
::
move
(
ctx
);
return
std
::
move
(
ctx
);
...
@@ -222,7 +222,7 @@ actor_ptr thread_pool_scheduler::spawn(abstract_event_based_actor* what)
...
@@ -222,7 +222,7 @@ 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
));
}
}
actor_ptr
thread_pool_scheduler
::
spawn
(
actor_behavi
or
*
behavior
,
actor_ptr
thread_pool_scheduler
::
spawn
(
scheduled_act
or
*
behavior
,
scheduling_hint
hint
)
scheduling_hint
hint
)
{
{
if
(
hint
==
detached
)
if
(
hint
==
detached
)
...
...
src/yielding_actor.cpp
View file @
920472e6
...
@@ -40,7 +40,7 @@ void yielding_actor::yield_until_not_empty()
...
@@ -40,7 +40,7 @@ void yielding_actor::yield_until_not_empty()
{
{
while
(
m_mailbox
.
empty
())
while
(
m_mailbox
.
empty
())
{
{
m_state
.
store
(
scheduled_actor
::
about_to_block
);
m_state
.
store
(
abstract_
scheduled_actor
::
about_to_block
);
CPPA_MEMORY_BARRIER
();
CPPA_MEMORY_BARRIER
();
// make sure mailbox is empty
// make sure mailbox is empty
if
(
!
m_mailbox
.
empty
())
if
(
!
m_mailbox
.
empty
())
...
@@ -48,7 +48,7 @@ void yielding_actor::yield_until_not_empty()
...
@@ -48,7 +48,7 @@ void yielding_actor::yield_until_not_empty()
// someone preempt us
// someone preempt us
//compare_exchange_state(scheduled_actor::about_to_block,
//compare_exchange_state(scheduled_actor::about_to_block,
// scheduled_actor::ready);
// scheduled_actor::ready);
m_state
.
store
(
scheduled_actor
::
ready
);
m_state
.
store
(
abstract_
scheduled_actor
::
ready
);
return
;
return
;
}
}
else
else
...
@@ -120,15 +120,15 @@ void yielding_actor::resume(util::fiber* from, resume_callback* callback)
...
@@ -120,15 +120,15 @@ void yielding_actor::resume(util::fiber* from, resume_callback* callback)
}
}
case
yield_state
:
:
blocked
:
case
yield_state
:
:
blocked
:
{
{
switch
(
compare_exchange_state
(
scheduled_actor
::
about_to_block
,
switch
(
compare_exchange_state
(
abstract_
scheduled_actor
::
about_to_block
,
scheduled_actor
::
blocked
))
abstract_
scheduled_actor
::
blocked
))
{
{
case
scheduled_actor
:
:
ready
:
case
abstract_
scheduled_actor
:
:
ready
:
{
{
if
(
callback
->
still_ready
())
break
;
if
(
callback
->
still_ready
())
break
;
else
return
;
else
return
;
}
}
case
scheduled_actor
:
:
blocked
:
case
abstract_
scheduled_actor
:
:
blocked
:
{
{
// wait until someone re-schedules that actor
// wait until someone re-schedules that actor
return
;
return
;
...
...
unit_testing/test__spawn.cpp
View file @
920472e6
#define CPPA_VERBOSE_CHECK
#include <stack>
#include <stack>
#include <chrono>
#include <chrono>
#include <iostream>
#include <iostream>
...
@@ -12,6 +10,7 @@
...
@@ -12,6 +10,7 @@
#include "cppa/cppa.hpp"
#include "cppa/cppa.hpp"
#include "cppa/actor.hpp"
#include "cppa/actor.hpp"
#include "cppa/scheduler.hpp"
#include "cppa/scheduler.hpp"
#include "cppa/fsm_actor.hpp"
#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"
...
@@ -26,117 +25,126 @@ using namespace cppa;
...
@@ -26,117 +25,126 @@ using namespace cppa;
// GCC 4.7 supports non-static member initialization
// GCC 4.7 supports non-static member initialization
#if (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 7)
#if (__GNUC__ >= 4) && (__GNUC_MINOR__ >= 7)
class
event_testee
:
public
event_based_actor
class
event_testee
:
public
fsm_actor
<
event_testee
>
{
{
friend
class
fsm_actor
<
event_testee
>
;
invoke_rules
wait4string
=
invoke_rules
wait4string
=
(
(
on
<
std
::
string
>
()
>>
[
=
](
const
std
::
string
&
value
)
on
<
std
::
string
>
()
>>
[
=
]()
{
become
(
&
init_state
);
},
on
<
atom
(
"GetState"
)
>
()
>>
[
=
]()
{
{
cout
<<
"event_testee[string]: "
<<
value
<<
endl
;
reply
(
"wait4string"
);
// switch back to wait4int
unbecome
();
unbecome
();
}
}
);
);
invoke_rules
wait4float
=
invoke_rules
wait4float
=
(
(
on
<
float
>
()
>>
[
=
](
float
value
)
on
<
float
>
()
>>
[
=
]()
{
{
cout
<<
"event_testee[float]: "
<<
value
<<
endl
;
become
(
&
wait4string
);
become
(
wait4string
);
},
on
<
atom
(
"GetState"
)
>
()
>>
[
=
]()
{
reply
(
"wait4float"
);
}
}
);
);
invoke_rules
wait4int
=
invoke_rules
init_state
=
(
(
on
<
int
>
()
>>
[
=
](
int
value
)
on
<
int
>
()
>>
[
=
]()
{
become
(
&
wait4float
);
},
on
<
atom
(
"GetState"
)
>
()
>>
[
=
]()
{
{
cout
<<
"event_testee[int]: "
<<
value
<<
endl
;
reply
(
"init_state"
);
become
(
wait4float
);
}
}
);
);
public:
void
on_exit
()
{
cout
<<
"event_testee[GCC47]::on_exit()"
<<
endl
;
}
void
init
()
{
cout
<<
"event_testee[GCC47]::init()"
<<
endl
;
become
(
wait4int
);
}
};
};
#else
#else
class
event_testee
:
public
event_based_actor
class
event_testee
:
public
fsm_actor
<
event_testee
>
{
{
friend
class
fsm_actor
<
event_testee
>
;
invoke_rules
wait4string
;
invoke_rules
wait4string
;
invoke_rules
wait4float
;
invoke_rules
wait4float
;
invoke_rules
wait4int
;
invoke_rules
init_state
;
public:
public:
void
on_exit
()
event_testee
()
{
cout
<<
"event_testee::on_exit()"
<<
endl
;
}
void
init
()
{
{
wait4string
=
wait4string
=
(
(
on
<
std
::
string
>
()
>>
[
=
](
const
std
::
string
&
value
)
on
<
std
::
string
>
()
>>
[
=
]()
{
{
cout
<<
"event_testee[string]: "
<<
value
<<
endl
;
become
(
&
init_state
);
become
(
&
wait4int
);
},
on
<
atom
(
"GetState"
)
>
()
>>
[
=
]()
{
reply
(
"wait4string"
);
}
}
);
);
wait4float
=
wait4float
=
(
(
on
<
float
>
()
>>
[
=
](
float
value
)
on
<
float
>
()
>>
[
=
]()
{
{
cout
<<
"event_testee[float]: "
<<
value
<<
endl
;
//become(&wait4string);
become
(
&
wait4string
);
become
(
on
<
std
::
string
>
()
>>
[
=
]()
{
become
(
&
init_state
);
},
on
<
atom
(
"GetState"
)
>
()
>>
[]()
{
reply
(
"wait4string"
);
}
);
},
on
<
atom
(
"GetState"
)
>
()
>>
[
=
]()
{
reply
(
"wait4float"
);
}
}
);
);
wait4int
=
init_state
=
(
(
on
<
int
>
()
>>
[
=
](
int
value
)
on
<
int
>
()
>>
[
=
]()
{
{
cout
<<
"event_testee[int]: "
<<
value
<<
endl
;
become
(
&
wait4float
);
become
(
&
wait4float
);
},
on
<
atom
(
"GetState"
)
>
()
>>
[
=
]()
{
reply
(
"init_state"
);
}
}
);
);
cout
<<
"event_testee::init()"
<<
endl
;
become
(
&
wait4int
);
}
}
};
};
#endif
#endif
// quits after 5 timeouts
abstract_event_based_actor
*
event_testee2
()
abstract_event_based_actor
*
event_testee2
()
{
{
struct
impl
:
event_based_actor
struct
impl
:
fsm_actor
<
impl
>
{
{
int
num_timeouts
;
int
num_timeouts
;
impl
()
:
num_timeouts
(
0
)
{
}
timed_invoke_rules
init_state
;
impl
()
:
num_timeouts
(
0
)
timed_invoke_rules
state
;
void
init
()
{
{
cout
<<
"event_testee2::impl::init()"
<<
endl
;
init_state
=
state
=
//become
(
(
others
()
>>
[]()
others
()
>>
[]()
{
{
...
@@ -146,66 +154,79 @@ abstract_event_based_actor* event_testee2()
...
@@ -146,66 +154,79 @@ abstract_event_based_actor* event_testee2()
},
},
after
(
std
::
chrono
::
milliseconds
(
50
))
>>
[
=
]()
after
(
std
::
chrono
::
milliseconds
(
50
))
>>
[
=
]()
{
{
cout
<<
"testee2 received timeout nr. "
<<
(
num_timeouts
+
1
)
<<
endl
;
if
(
++
num_timeouts
>=
5
)
if
(
++
num_timeouts
>=
5
)
{
{
quit
(
exit_reason
::
normal
);
quit
(
exit_reason
::
normal
);
}
}
}
}
);
);
become
(
&
state
);
}
}
};
};
return
new
impl
;
return
new
impl
;
}
}
class
testee_
behavior
:
public
actor_behavi
or
class
testee_
actor
:
public
scheduled_act
or
{
{
public:
void
wait4string
()
{
bool
string_received
=
false
;
receive_while
([
&
]()
{
return
!
string_received
;
})
(
on
<
std
::
string
>
()
>>
[
&
]()
{
string_received
=
true
;
},
on
<
atom
(
"GetState"
)
>
()
>>
[
&
]()
{
reply
(
"wait4string"
);
}
);
}
void
ac
t
()
void
wait4floa
t
()
{
{
receive_loop
bool
float_received
=
false
;
receive_while
([
&
]()
{
return
!
float_received
;
})
(
(
on
<
int
>
()
>>
[
&
](
int
i
)
on
<
float
>
()
>>
[
&
](
)
{
{
cout
<<
"testee_behavior[int]: "
<<
i
<<
endl
;
float_received
=
true
;
receive
wait4string
();
(
},
on
<
float
>
()
>>
[
&
](
float
f
)
on
<
atom
(
"GetState"
)
>
()
>>
[
&
]()
{
{
cout
<<
"testee_behavior[float]: "
<<
f
<<
endl
;
reply
(
"wait4float"
);
receive
(
on
<
std
::
string
>
()
>>
[
&
](
const
std
::
string
&
str
)
{
cout
<<
"testee_behavior[string]: "
<<
str
<<
endl
;
}
);
}
);
}
}
);
);
}
}
void
on_exit
()
public:
void
act
()
{
{
cout
<<
"testee_behavior::on_exit()"
<<
endl
;
receive_loop
(
on
<
int
>
()
>>
[
&
]()
{
wait4float
();
},
on
<
atom
(
"GetState"
)
>
()
>>
[
&
]()
{
reply
(
"init_state"
);
}
);
}
}
};
};
// receives one timeout and quits
void
testee1
()
void
testee1
()
{
{
receive_loop
receive_loop
(
(
after
(
std
::
chrono
::
milliseconds
(
10
))
>>
[]()
after
(
std
::
chrono
::
milliseconds
(
10
))
>>
[]()
{
{
cout
<<
"testee1::quit"
<<
endl
;
quit
(
exit_reason
::
user_defined
);
quit
(
exit_reason
::
user_defined
);
}
}
);
);
...
@@ -245,10 +266,10 @@ void testee3(actor_ptr parent)
...
@@ -245,10 +266,10 @@ void testee3(actor_ptr parent)
}
}
template
<
class
Testee
>
template
<
class
Testee
>
void
behavior_test
()
std
::
string
behavior_test
()
{
{
std
::
string
result
;
std
::
string
testee_name
=
detail
::
to_uniform_name
(
typeid
(
Testee
));
std
::
string
testee_name
=
detail
::
to_uniform_name
(
typeid
(
Testee
));
cout
<<
"behavior_test<"
<<
testee_name
<<
">()"
<<
endl
;
auto
et
=
spawn
(
new
Testee
);
auto
et
=
spawn
(
new
Testee
);
send
(
et
,
1
);
send
(
et
,
1
);
send
(
et
,
2
);
send
(
et
,
2
);
...
@@ -259,22 +280,34 @@ void behavior_test()
...
@@ -259,22 +280,34 @@ void behavior_test()
send
(
et
,
.3
f
);
send
(
et
,
.3
f
);
send
(
et
,
"hello again "
+
testee_name
);
send
(
et
,
"hello again "
+
testee_name
);
send
(
et
,
"goodbye "
+
testee_name
);
send
(
et
,
"goodbye "
+
testee_name
);
send
(
et
,
atom
(
"GetState"
));
receive
(
on
<
std
::
string
>
()
>>
[
&
](
const
std
::
string
&
str
)
{
result
=
str
;
},
after
(
std
::
chrono
::
seconds
(
2
))
>>
[
&
]()
{
throw
std
::
runtime_error
(
testee_name
+
" does not reply"
);
}
);
send
(
et
,
atom
(
":Exit"
),
exit_reason
::
user_defined
);
send
(
et
,
atom
(
":Exit"
),
exit_reason
::
user_defined
);
await_all_others_done
();
await_all_others_done
();
cout
<<
endl
;
return
result
;
}
}
size_t
test__spawn
()
size_t
test__spawn
()
{
{
CPPA_TEST
(
test__spawn
);
CPPA_TEST
(
test__spawn
);
//
spawn(testee1);
spawn
(
testee1
);
spawn
(
event_testee2
());
spawn
(
event_testee2
());
await_all_others_done
();
await_all_others_done
();
behavior_test
<
testee_behavior
>
(
);
CPPA_CHECK_EQUAL
(
behavior_test
<
testee_actor
>
(),
"init_state"
);
behavior_test
<
event_testee
>
(
);
CPPA_CHECK_EQUAL
(
behavior_test
<
event_testee
>
(),
"init_state"
);
return
CPPA_TEST_RESULT
;
return
CPPA_TEST_RESULT
;
...
...
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