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
e9731720
Commit
e9731720
authored
Jun 26, 2012
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
maintenance
parent
3f66a8d1
Changes
29
Show whitespace changes
Inline
Side-by-side
Showing
29 changed files
with
418 additions
and
278 deletions
+418
-278
CMakeLists.txt
CMakeLists.txt
+0
-1
benchmarks/mixed_case.cpp
benchmarks/mixed_case.cpp
+0
-1
cppa.files
cppa.files
+0
-2
cppa/actor.hpp
cppa/actor.hpp
+0
-18
cppa/context_switching_actor.hpp
cppa/context_switching_actor.hpp
+2
-0
cppa/cppa.hpp
cppa/cppa.hpp
+50
-13
cppa/detail/mock_scheduler.hpp
cppa/detail/mock_scheduler.hpp
+0
-60
cppa/detail/scheduled_actor_dummy.hpp
cppa/detail/scheduled_actor_dummy.hpp
+1
-0
cppa/detail/thread_pool_scheduler.hpp
cppa/detail/thread_pool_scheduler.hpp
+26
-3
cppa/event_based_actor.hpp
cppa/event_based_actor.hpp
+4
-2
cppa/local_actor.hpp
cppa/local_actor.hpp
+16
-0
cppa/scheduled_actor.hpp
cppa/scheduled_actor.hpp
+8
-1
cppa/scheduler.hpp
cppa/scheduler.hpp
+23
-3
cppa/scheduling_hint.hpp
cppa/scheduling_hint.hpp
+7
-1
cppa/thread_mapped_actor.hpp
cppa/thread_mapped_actor.hpp
+3
-0
examples/dining_philosophers.cpp
examples/dining_philosophers.cpp
+4
-2
src/actor.cpp
src/actor.cpp
+0
-14
src/context_switching_actor.cpp
src/context_switching_actor.cpp
+4
-0
src/event_based_actor.cpp
src/event_based_actor.cpp
+4
-0
src/local_actor.cpp
src/local_actor.cpp
+11
-0
src/mock_scheduler.cpp
src/mock_scheduler.cpp
+0
-112
src/network_manager.cpp
src/network_manager.cpp
+16
-5
src/scheduled_actor.cpp
src/scheduled_actor.cpp
+1
-2
src/scheduled_actor_dummy.cpp
src/scheduled_actor_dummy.cpp
+12
-9
src/scheduler.cpp
src/scheduler.cpp
+0
-1
src/thread_pool_scheduler.cpp
src/thread_pool_scheduler.cpp
+64
-17
unit_testing/main.cpp
unit_testing/main.cpp
+0
-5
unit_testing/test__local_group.cpp
unit_testing/test__local_group.cpp
+5
-6
unit_testing/test__spawn.cpp
unit_testing/test__spawn.cpp
+157
-0
No files found.
CMakeLists.txt
View file @
e9731720
...
@@ -33,7 +33,6 @@ set(LIBCPPA_SRC
...
@@ -33,7 +33,6 @@ set(LIBCPPA_SRC
src/group_manager.cpp
src/group_manager.cpp
src/local_actor.cpp
src/local_actor.cpp
src/mailman.cpp
src/mailman.cpp
src/mock_scheduler.cpp
src/native_socket.cpp
src/native_socket.cpp
src/network_manager.cpp
src/network_manager.cpp
src/object.cpp
src/object.cpp
...
...
benchmarks/mixed_case.cpp
View file @
e9731720
...
@@ -38,7 +38,6 @@
...
@@ -38,7 +38,6 @@
#include "cppa/cppa.hpp"
#include "cppa/cppa.hpp"
#include "cppa/match.hpp"
#include "cppa/match.hpp"
#include "cppa/sb_actor.hpp"
#include "cppa/sb_actor.hpp"
#include "cppa/detail/mock_scheduler.hpp"
#include "cppa/context_switching_actor.hpp"
#include "cppa/context_switching_actor.hpp"
using
std
::
cout
;
using
std
::
cout
;
...
...
cppa.files
View file @
e9731720
...
@@ -60,7 +60,6 @@ cppa/detail/list_member.hpp
...
@@ -60,7 +60,6 @@ cppa/detail/list_member.hpp
cppa/detail/mailman.hpp
cppa/detail/mailman.hpp
cppa/detail/map_member.hpp
cppa/detail/map_member.hpp
cppa/detail/matches.hpp
cppa/detail/matches.hpp
cppa/detail/mock_scheduler.hpp
cppa/detail/native_socket.hpp
cppa/detail/native_socket.hpp
cppa/detail/network_manager.hpp
cppa/detail/network_manager.hpp
cppa/detail/object_array.hpp
cppa/detail/object_array.hpp
...
@@ -212,7 +211,6 @@ src/group.cpp
...
@@ -212,7 +211,6 @@ src/group.cpp
src/group_manager.cpp
src/group_manager.cpp
src/local_actor.cpp
src/local_actor.cpp
src/mailman.cpp
src/mailman.cpp
src/mock_scheduler.cpp
src/native_socket.cpp
src/native_socket.cpp
src/network_manager.cpp
src/network_manager.cpp
src/object.cpp
src/object.cpp
...
...
cppa/actor.hpp
View file @
e9731720
...
@@ -62,8 +62,6 @@ class actor : public channel {
...
@@ -62,8 +62,6 @@ class actor : public channel {
public:
public:
~
actor
();
/**
/**
* @brief Enqueues @p msg to the actor's mailbox and returns true if
* @brief Enqueues @p msg to the actor's mailbox and returns true if
* this actor is an scheduled actor that successfully changed
* this actor is an scheduled actor that successfully changed
...
@@ -109,22 +107,6 @@ class actor : public channel {
...
@@ -109,22 +107,6 @@ class actor : public channel {
std
::
is_base_of
<
attachable
,
T
>::
value
std
::
is_base_of
<
attachable
,
T
>::
value
>::
type
*
=
0
);
>::
type
*
=
0
);
/**
* @brief Forces this actor to subscribe to the group @p what.
*
* The group will be unsubscribed if the actor finishes execution.
* @param what Group instance that should be joined.
*/
void
join
(
group_ptr
&
what
);
/**
* @brief Forces this actor to leave the group @p what.
* @param what Joined group that should be leaved.
* @note Groups are leaved automatically if the Actor finishes
* execution.
*/
void
leave
(
const
group_ptr
&
what
);
/**
/**
* @brief Links this actor to @p other.
* @brief Links this actor to @p other.
* @param other Actor instance that whose execution is coupled to the
* @param other Actor instance that whose execution is coupled to the
...
...
cppa/context_switching_actor.hpp
View file @
e9731720
...
@@ -85,6 +85,8 @@ class context_switching_actor : public detail::stacked_actor_mixin<
...
@@ -85,6 +85,8 @@ class context_switching_actor : public detail::stacked_actor_mixin<
resume_result
resume
(
util
::
fiber
*
from
);
//override
resume_result
resume
(
util
::
fiber
*
from
);
//override
scheduled_actor_type
impl_type
();
protected:
protected:
context_switching_actor
();
context_switching_actor
();
...
...
cppa/cppa.hpp
View file @
e9731720
...
@@ -424,11 +424,11 @@ namespace cppa {
...
@@ -424,11 +424,11 @@ namespace cppa {
/**
/**
* @ingroup ActorManagement
* @ingroup ActorManagement
* @brief Spawns a new context-switching actor.
* @brief Spawns a new context-switching actor.
* @param
whom
Instance of an event-based actor.
* @param
impl
Instance of an event-based actor.
* @returns An {@link actor_ptr} to the spawned {@link actor}.
* @returns An {@link actor_ptr} to the spawned {@link actor}.
*/
*/
inline
actor_ptr
spawn
(
scheduled_actor
*
whom
)
{
inline
actor_ptr
spawn
(
scheduled_actor
*
impl
)
{
return
get_scheduler
()
->
spawn
(
whom
);
return
get_scheduler
()
->
spawn
(
impl
);
}
}
/**
/**
...
@@ -439,8 +439,8 @@ inline actor_ptr spawn(scheduled_actor* whom) {
...
@@ -439,8 +439,8 @@ inline actor_ptr spawn(scheduled_actor* whom) {
* @returns An {@link actor_ptr} to the spawned {@link actor}.
* @returns An {@link actor_ptr} to the spawned {@link actor}.
*/
*/
template
<
scheduling_hint
Hint
>
template
<
scheduling_hint
Hint
>
inline
actor_ptr
spawn
(
std
::
function
<
void
()
>
bhvr
)
{
inline
actor_ptr
spawn
(
void_function
fun
)
{
return
get_scheduler
()
->
spawn
(
std
::
move
(
bhvr
),
Hint
);
return
get_scheduler
()
->
spawn
(
std
::
move
(
fun
),
Hint
);
}
}
/**
/**
...
@@ -450,8 +450,8 @@ inline actor_ptr spawn(std::function<void()> bhvr) {
...
@@ -450,8 +450,8 @@ inline actor_ptr spawn(std::function<void()> bhvr) {
* @param bhvr A function implementing the actor's behavior.
* @param bhvr A function implementing the actor's behavior.
* @returns An {@link actor_ptr} to the spawned {@link actor}.
* @returns An {@link actor_ptr} to the spawned {@link actor}.
*/
*/
inline
actor_ptr
spawn
(
std
::
function
<
void
()
>
bhvr
)
{
inline
actor_ptr
spawn
(
void_function
fun
)
{
return
get_scheduler
()
->
spawn
(
std
::
move
(
bhvr
),
scheduled
);
return
get_scheduler
()
->
spawn
(
std
::
move
(
fun
),
scheduled
);
}
}
// forwards self_type as actor_ptr
// forwards self_type as actor_ptr
...
@@ -477,11 +477,11 @@ struct spawn_fwd_<self_type> {
...
@@ -477,11 +477,11 @@ struct spawn_fwd_<self_type> {
* @param args Further argumetns to @p bhvr.
* @param args Further argumetns to @p bhvr.
* @returns An {@link actor_ptr} to the spawned {@link actor}.
* @returns An {@link actor_ptr} to the spawned {@link actor}.
*/
*/
template
<
scheduling_hint
Hint
,
typename
F
,
typename
Arg0
,
typename
...
Args
>
template
<
scheduling_hint
Hint
,
typename
F
un
,
typename
Arg0
,
typename
...
Args
>
inline
actor_ptr
spawn
(
F
bhvr
,
Arg0
&&
arg0
,
Args
&&
...
args
)
{
inline
actor_ptr
spawn
(
F
un
fun
,
Arg0
&&
arg0
,
Args
&&
...
args
)
{
return
spawn
<
Hint
>
(
return
spawn
<
Hint
>
(
std
::
bind
(
std
::
bind
(
std
::
move
(
bhvr
),
std
::
move
(
fun
),
spawn_fwd_
<
typename
util
::
rm_ref
<
Arg0
>::
type
>::
_
(
arg0
),
spawn_fwd_
<
typename
util
::
rm_ref
<
Arg0
>::
type
>::
_
(
arg0
),
spawn_fwd_
<
typename
util
::
rm_ref
<
Args
>::
type
>::
_
(
args
)...));
spawn_fwd_
<
typename
util
::
rm_ref
<
Args
>::
type
>::
_
(
args
)...));
}
}
...
@@ -496,9 +496,46 @@ inline actor_ptr spawn(F bhvr, Arg0&& arg0, Args&&... args) {
...
@@ -496,9 +496,46 @@ inline actor_ptr spawn(F bhvr, Arg0&& arg0, Args&&... args) {
* @param args Further argumetns to @p bhvr.
* @param args Further argumetns to @p bhvr.
* @returns An {@link actor_ptr} to the spawned {@link actor}.
* @returns An {@link actor_ptr} to the spawned {@link actor}.
*/
*/
template
<
typename
F
,
typename
Arg0
,
typename
...
Args
>
template
<
typename
Fun
,
typename
Arg0
,
typename
...
Args
>
inline
actor_ptr
spawn
(
F
&&
bhvr
,
Arg0
&&
arg0
,
Args
&&
...
args
)
{
inline
actor_ptr
spawn
(
Fun
&&
fun
,
Arg0
&&
arg0
,
Args
&&
...
args
)
{
return
spawn
<
scheduled
>
(
std
::
forward
<
F
>
(
bhvr
),
return
spawn
<
scheduled
>
(
std
::
forward
<
Fun
>
(
fun
),
std
::
forward
<
Arg0
>
(
arg0
),
std
::
forward
<
Args
>
(
args
)...);
}
inline
actor_ptr
spawn_in_group
(
const
group_ptr
&
grp
,
event_based_actor
*
impl
)
{
return
get_scheduler
()
->
spawn
(
impl
,
[
grp
](
local_actor
*
ptr
)
{
ptr
->
join
(
grp
);
});
}
template
<
scheduling_hint
Hint
>
inline
actor_ptr
spawn_in_group
(
const
group_ptr
&
grp
,
void_function
fun
)
{
return
get_scheduler
()
->
spawn
(
std
::
move
(
fun
),
Hint
,
[
grp
](
local_actor
*
ptr
){
ptr
->
join
(
grp
);
});
}
inline
actor_ptr
spawn_in_group
(
const
group_ptr
&
grp
,
void_function
fun
)
{
return
spawn_in_group
<
scheduled
>
(
grp
,
std
::
move
(
fun
));
}
template
<
scheduling_hint
Hint
,
typename
Fun
,
typename
Arg0
,
typename
...
Args
>
inline
actor_ptr
spawn_in_group
(
const
group_ptr
&
grp
,
Fun
fun
,
Arg0
&&
arg0
,
Args
&&
...
args
)
{
return
spawn_in_group
<
Hint
>
(
grp
,
std
::
bind
(
std
::
move
(
fun
),
spawn_fwd_
<
typename
util
::
rm_ref
<
Arg0
>::
type
>::
_
(
arg0
),
spawn_fwd_
<
typename
util
::
rm_ref
<
Args
>::
type
>::
_
(
args
)...));
}
template
<
typename
Fun
,
typename
Arg0
,
typename
...
Args
>
inline
actor_ptr
spawn_in_group
(
const
group_ptr
&
grp
,
Fun
&&
fun
,
Arg0
&&
arg0
,
Args
&&
...
args
)
{
return
spawn_in_group
<
scheduled
>
(
grp
,
std
::
forward
<
Fun
>
(
fun
),
std
::
forward
<
Arg0
>
(
arg0
),
std
::
forward
<
Arg0
>
(
arg0
),
std
::
forward
<
Args
>
(
args
)...);
std
::
forward
<
Args
>
(
args
)...);
}
}
...
...
cppa/detail/mock_scheduler.hpp
deleted
100644 → 0
View file @
3f66a8d1
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011, 2012 *
* Dominik Charousset <dominik.charousset@haw-hamburg.de> *
* *
* This file is part of libcppa. *
* libcppa is free software: you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation, either version 3 of the License *
* or (at your option) any later version. *
* *
* libcppa is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
\******************************************************************************/
#ifndef CPPA_MOCK_SCHEDULER_HPP
#define CPPA_MOCK_SCHEDULER_HPP
#include <thread>
#include <utility>
#include "cppa/scheduler.hpp"
#include "cppa/detail/tdata.hpp"
namespace
cppa
{
namespace
detail
{
class
mock_scheduler
:
public
scheduler
{
public:
actor_ptr
spawn
(
scheduled_actor
*
what
);
actor_ptr
spawn
(
std
::
function
<
void
()
>
what
,
scheduling_hint
);
static
actor_ptr
spawn_impl
(
std
::
function
<
void
()
>
what
);
static
std
::
thread
spawn_hidden_impl
(
std
::
function
<
void
()
>
what
,
local_actor_ptr
ctx
);
void
enqueue
(
scheduled_actor
*
what
);
};
}
}
// namespace cppa::detail
#endif // CPPA_MOCK_SCHEDULER_HPP
cppa/detail/scheduled_actor_dummy.hpp
View file @
e9731720
...
@@ -49,6 +49,7 @@ struct scheduled_actor_dummy : abstract_scheduled_actor {
...
@@ -49,6 +49,7 @@ struct scheduled_actor_dummy : abstract_scheduled_actor {
void
unbecome
();
void
unbecome
();
void
do_become
(
behavior
*
,
bool
,
bool
);
void
do_become
(
behavior
*
,
bool
,
bool
);
bool
has_behavior
();
bool
has_behavior
();
scheduled_actor_type
impl_type
();
};
};
}
}
// namespace cppa::detail
}
}
// namespace cppa::detail
...
...
cppa/detail/thread_pool_scheduler.hpp
View file @
e9731720
...
@@ -34,6 +34,7 @@
...
@@ -34,6 +34,7 @@
#include <thread>
#include <thread>
#include "cppa/scheduler.hpp"
#include "cppa/scheduler.hpp"
#include "cppa/context_switching_actor.hpp"
#include "cppa/util/producer_consumer_list.hpp"
#include "cppa/util/producer_consumer_list.hpp"
#include "cppa/detail/scheduled_actor_dummy.hpp"
#include "cppa/detail/scheduled_actor_dummy.hpp"
#include "cppa/detail/abstract_scheduled_actor.hpp"
#include "cppa/detail/abstract_scheduled_actor.hpp"
...
@@ -56,7 +57,13 @@ class thread_pool_scheduler : public scheduler {
...
@@ -56,7 +57,13 @@ class thread_pool_scheduler : public scheduler {
actor_ptr
spawn
(
scheduled_actor
*
what
);
actor_ptr
spawn
(
scheduled_actor
*
what
);
actor_ptr
spawn
(
std
::
function
<
void
()
>
what
,
scheduling_hint
hint
);
actor_ptr
spawn
(
scheduled_actor
*
what
,
init_callback
init_cb
);
actor_ptr
spawn
(
void_function
fun
,
scheduling_hint
hint
);
actor_ptr
spawn
(
void_function
what
,
scheduling_hint
hint
,
init_callback
init_cb
);
private:
private:
...
@@ -67,11 +74,27 @@ class thread_pool_scheduler : public scheduler {
...
@@ -67,11 +74,27 @@ class thread_pool_scheduler : public scheduler {
scheduled_actor_dummy
m_dummy
;
scheduled_actor_dummy
m_dummy
;
std
::
thread
m_supervisor
;
std
::
thread
m_supervisor
;
actor_ptr
spawn_impl
(
scheduled_actor_ptr
what
,
bool
push_to_queue
=
true
);
static
void
worker_loop
(
worker
*
);
static
void
worker_loop
(
worker
*
);
static
void
supervisor_loop
(
job_queue
*
,
scheduled_actor
*
);
static
void
supervisor_loop
(
job_queue
*
,
scheduled_actor
*
);
actor_ptr
spawn_impl
(
scheduled_actor_ptr
what
);
actor_ptr
spawn_as_thread
(
void_function
fun
,
init_callback
cb
,
bool
hidden
);
# ifndef CPPA_DISABLE_CONTEXT_SWITCHING
template
<
typename
F
>
actor_ptr
spawn_impl
(
void_function
fun
,
scheduling_hint
sh
,
F
cb
)
{
if
(
sh
==
scheduled
)
{
scheduled_actor_ptr
ptr
{
new
context_switching_actor
(
std
::
move
(
fun
))};
ptr
->
attach_to_scheduler
(
this
);
cb
(
ptr
.
get
());
return
spawn_impl
(
std
::
move
(
ptr
));
}
else
{
return
spawn_as_thread
(
std
::
move
(
fun
),
std
::
move
(
cb
));
}
}
# endif
};
};
}
}
// namespace cppa::detail
}
}
// namespace cppa::detail
...
...
cppa/event_based_actor.hpp
View file @
e9731720
...
@@ -82,12 +82,14 @@ class event_based_actor : public detail::abstract_scheduled_actor {
...
@@ -82,12 +82,14 @@ class event_based_actor : public detail::abstract_scheduled_actor {
void
unbecome
();
void
unbecome
();
bool
has_behavior
();
scheduled_actor_type
impl_type
();
protected:
protected:
event_based_actor
();
event_based_actor
();
virtual
bool
has_behavior
();
// provoke compiler errors for usage of receive() and related functions
// provoke compiler errors for usage of receive() and related functions
/**
/**
...
...
cppa/local_actor.hpp
View file @
e9731720
...
@@ -77,6 +77,22 @@ class local_actor : public actor {
...
@@ -77,6 +77,22 @@ class local_actor : public actor {
public:
public:
/**
* @brief Causes this actor to subscribe to the group @p what.
*
* The group will be unsubscribed if the actor finishes execution.
* @param what Group instance that should be joined.
*/
void
join
(
const
group_ptr
&
what
);
/**
* @brief Causes this actor to leave the group @p what.
* @param what Joined group that should be leaved.
* @note Groups are leaved automatically if the Actor finishes
* execution.
*/
void
leave
(
const
group_ptr
&
what
);
/**
/**
* @brief Finishes execution of this actor.
* @brief Finishes execution of this actor.
*
*
...
...
cppa/scheduled_actor.hpp
View file @
e9731720
...
@@ -44,6 +44,11 @@ enum class resume_result {
...
@@ -44,6 +44,11 @@ enum class resume_result {
actor_done
actor_done
};
};
enum
scheduled_actor_type
{
context_switching_impl
,
event_based_impl
};
/**
/**
* @brief A base class for cooperatively scheduled actors.
* @brief A base class for cooperatively scheduled actors.
*/
*/
...
@@ -61,10 +66,12 @@ class scheduled_actor : public local_actor {
...
@@ -61,10 +66,12 @@ class scheduled_actor : public local_actor {
// called from worker thread
// called from worker thread
virtual
resume_result
resume
(
util
::
fiber
*
from
)
=
0
;
virtual
resume_result
resume
(
util
::
fiber
*
from
)
=
0
;
scheduled_actor
*
attach_to_scheduler
(
scheduler
*
sched
);
void
attach_to_scheduler
(
scheduler
*
sched
);
virtual
bool
has_behavior
()
=
0
;
virtual
bool
has_behavior
()
=
0
;
virtual
scheduled_actor_type
impl_type
()
=
0
;
protected:
protected:
scheduler
*
m_scheduler
;
scheduler
*
m_scheduler
;
...
...
cppa/scheduler.hpp
View file @
e9731720
...
@@ -51,6 +51,10 @@ namespace cppa {
...
@@ -51,6 +51,10 @@ namespace cppa {
class
scheduled_actor
;
class
scheduled_actor
;
class
scheduler_helper
;
class
scheduler_helper
;
typedef
std
::
function
<
void
()
>
void_function
;
typedef
std
::
function
<
void
(
local_actor
*
)
>
init_callback
;
/**
/**
* @brief
* @brief
*/
*/
...
@@ -81,17 +85,33 @@ class scheduler {
...
@@ -81,17 +85,33 @@ class scheduler {
virtual
void
enqueue
(
scheduled_actor
*
)
=
0
;
virtual
void
enqueue
(
scheduled_actor
*
)
=
0
;
/**
/**
* @brief Spawns a new actor that executes <code>
behavior->act
()</code>
* @brief Spawns a new actor that executes <code>
fun
()</code>
* with the scheduling policy @p hint if possible.
* with the scheduling policy @p hint if possible.
*/
*/
virtual
actor_ptr
spawn
(
std
::
function
<
void
()
>
behavior
,
virtual
actor_ptr
spawn
(
void_function
fun
,
scheduling_hint
hint
)
=
0
;
scheduling_hint
hint
)
=
0
;
/**
* @brief Spawns a new actor that executes <code>behavior()</code>
* with the scheduling policy @p hint if possible and calls
* <code>init_cb</code> after the actor is initialized but before
* it starts execution.
*/
virtual
actor_ptr
spawn
(
void_function
fun
,
scheduling_hint
hint
,
init_callback
init_cb
)
=
0
;
/**
/**
* @brief Spawns a new event-based actor.
* @brief Spawns a new event-based actor.
*/
*/
virtual
actor_ptr
spawn
(
scheduled_actor
*
what
)
=
0
;
virtual
actor_ptr
spawn
(
scheduled_actor
*
what
)
=
0
;
/**
* @brief Spawns a new event-based actor and calls
* <code>init_cb</code> after the actor is initialized but before
* it starts execution.
*/
virtual
actor_ptr
spawn
(
scheduled_actor
*
what
,
init_callback
init_cb
)
=
0
;
/**
/**
* @brief Informs the scheduler about a converted context
* @brief Informs the scheduler about a converted context
* (a thread that acts as actor).
* (a thread that acts as actor).
...
...
cppa/scheduling_hint.hpp
View file @
e9731720
...
@@ -47,7 +47,13 @@ enum scheduling_hint {
...
@@ -47,7 +47,13 @@ enum scheduling_hint {
/**
/**
* @brief Indicates that an actor should run in its own thread.
* @brief Indicates that an actor should run in its own thread.
*/
*/
detached
detached
,
/**
* @brief Indicates that an actor should run in its own thread but should
* be ignored by {@link await_others_done()}.
*/
detached_and_hidden
};
};
...
...
cppa/thread_mapped_actor.hpp
View file @
e9731720
...
@@ -47,6 +47,7 @@
...
@@ -47,6 +47,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/intrusive_ptr.hpp"
#include "cppa/detail/abstract_actor.hpp"
#include "cppa/detail/abstract_actor.hpp"
#include "cppa/intrusive/singly_linked_list.hpp"
#include "cppa/intrusive/singly_linked_list.hpp"
...
@@ -141,6 +142,8 @@ class thread_mapped_actor : public detail::stacked_actor_mixin<
...
@@ -141,6 +142,8 @@ class thread_mapped_actor : public detail::stacked_actor_mixin<
};
};
typedef
intrusive_ptr
<
thread_mapped_actor
>
thread_mapped_actor_ptr
;
#endif // CPPA_DOCUMENTATION
#endif // CPPA_DOCUMENTATION
}
// namespace cppa
}
// namespace cppa
...
...
examples/dining_philosophers.cpp
View file @
e9731720
...
@@ -185,8 +185,10 @@ int main(int, char**) {
...
@@ -185,8 +185,10 @@ int main(int, char**) {
std
::
vector
<
std
::
string
>
names
=
{
"Plato"
,
"Hume"
,
"Kant"
,
std
::
vector
<
std
::
string
>
names
=
{
"Plato"
,
"Hume"
,
"Kant"
,
"Nietzsche"
,
"Descartes"
};
"Nietzsche"
,
"Descartes"
};
for
(
size_t
i
=
0
;
i
<
5
;
++
i
)
{
for
(
size_t
i
=
0
;
i
<
5
;
++
i
)
{
spawn
(
new
philosopher
(
names
[
i
],
chopsticks
[
i
],
spawn_in_group
(
dinner_club
,
chopsticks
[(
i
+
1
)
%
5
])
)
->
join
(
dinner_club
);
new
philosopher
(
names
[
i
],
chopsticks
[
i
],
chopsticks
[(
i
+
1
)
%
5
]));
}
}
// tell philosophers to start thinking
// tell philosophers to start thinking
send
(
dinner_club
,
atom
(
"think"
));
send
(
dinner_club
,
atom
(
"think"
));
...
...
src/actor.cpp
View file @
e9731720
...
@@ -73,20 +73,6 @@ actor::actor(const process_information_ptr& pptr)
...
@@ -73,20 +73,6 @@ actor::actor(const process_information_ptr& pptr)
}
}
}
}
actor
::~
actor
()
{
}
void
actor
::
join
(
group_ptr
&
what
)
{
if
(
!
what
)
return
;
attach
(
what
->
subscribe
(
this
));
}
void
actor
::
leave
(
const
group_ptr
&
what
)
{
if
(
!
what
)
return
;
attachable
::
token
group_token
(
typeid
(
group
::
unsubscriber
),
what
.
get
());
detach
(
group_token
);
}
void
actor
::
link_to
(
intrusive_ptr
<
actor
>&&
other
)
{
void
actor
::
link_to
(
intrusive_ptr
<
actor
>&&
other
)
{
intrusive_ptr
<
actor
>
tmp
(
std
::
move
(
other
));
intrusive_ptr
<
actor
>
tmp
(
std
::
move
(
other
));
link_to
(
tmp
);
link_to
(
tmp
);
...
...
src/context_switching_actor.cpp
View file @
e9731720
...
@@ -84,6 +84,10 @@ detail::recursive_queue_node* context_switching_actor::receive_node() {
...
@@ -84,6 +84,10 @@ detail::recursive_queue_node* context_switching_actor::receive_node() {
return
e
;
return
e
;
}
}
scheduled_actor_type
context_switching_actor
::
impl_type
()
{
return
context_switching_impl
;
}
resume_result
context_switching_actor
::
resume
(
util
::
fiber
*
from
)
{
resume_result
context_switching_actor
::
resume
(
util
::
fiber
*
from
)
{
using
namespace
detail
;
using
namespace
detail
;
scoped_self_setter
sss
{
this
};
scoped_self_setter
sss
{
this
};
...
...
src/event_based_actor.cpp
View file @
e9731720
...
@@ -121,4 +121,8 @@ void event_based_actor::unbecome() {
...
@@ -121,4 +121,8 @@ void event_based_actor::unbecome() {
m_bhvr_stack
.
pop_back
();
m_bhvr_stack
.
pop_back
();
}
}
scheduled_actor_type
event_based_actor
::
impl_type
()
{
return
event_based_impl
;
}
}
// namespace cppa
}
// namespace cppa
src/local_actor.cpp
View file @
e9731720
...
@@ -84,4 +84,15 @@ void local_actor::on_exit() { }
...
@@ -84,4 +84,15 @@ void local_actor::on_exit() { }
void
local_actor
::
init
()
{
}
void
local_actor
::
init
()
{
}
void
local_actor
::
join
(
const
group_ptr
&
what
)
{
if
(
!
what
)
return
;
attach
(
what
->
subscribe
(
this
));
}
void
local_actor
::
leave
(
const
group_ptr
&
what
)
{
if
(
!
what
)
return
;
attachable
::
token
group_token
(
typeid
(
group
::
unsubscriber
),
what
.
get
());
detach
(
group_token
);
}
}
// namespace cppa
}
// namespace cppa
src/mock_scheduler.cpp
deleted
100644 → 0
View file @
3f66a8d1
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011, 2012 *
* Dominik Charousset <dominik.charousset@haw-hamburg.de> *
* *
* This file is part of libcppa. *
* libcppa is free software: you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation, either version 3 of the License *
* or (at your option) any later version. *
* *
* libcppa is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
\******************************************************************************/
#include "cppa/config.hpp"
#include <thread>
#include <atomic>
#include <iostream>
#include "cppa/self.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/scheduler.hpp"
#include "cppa/attachable.hpp"
#include "cppa/local_actor.hpp"
#include "cppa/scheduled_actor.hpp"
#include "cppa/thread_mapped_actor.hpp"
#include "cppa/event_based_actor.hpp"
#include "cppa/detail/actor_count.hpp"
#include "cppa/detail/mock_scheduler.hpp"
#include "cppa/detail/to_uniform_name.hpp"
using
std
::
cout
;
using
std
::
cerr
;
using
std
::
endl
;
namespace
cppa
{
namespace
detail
{
typedef
intrusive_ptr
<
thread_mapped_actor
>
thread_mapped_actor_ptr
;
namespace
{
void
run_actor
(
thread_mapped_actor_ptr
m_self
)
{
self
.
set
(
m_self
.
get
());
try
{
m_self
->
init
();
m_self
->
initialized
(
true
);
m_self
->
run
();
m_self
->
on_exit
();
}
catch
(...)
{
}
self
.
set
(
nullptr
);
std
::
atomic_thread_fence
(
std
::
memory_order_seq_cst
);
dec_actor_count
();
}
void
run_hidden_actor
(
local_actor_ptr
m_self
,
std
::
function
<
void
()
>
what
)
{
self
.
set
(
m_self
.
get
());
try
{
what
();
}
catch
(...)
{
}
self
.
set
(
nullptr
);
}
}
// namespace <anonymous>
std
::
thread
mock_scheduler
::
spawn_hidden_impl
(
std
::
function
<
void
()
>
what
,
local_actor_ptr
ctx
)
{
return
std
::
thread
{
run_hidden_actor
,
std
::
move
(
ctx
),
std
::
move
(
what
)};
}
actor_ptr
mock_scheduler
::
spawn_impl
(
std
::
function
<
void
()
>
what
)
{
inc_actor_count
();
std
::
atomic_thread_fence
(
std
::
memory_order_seq_cst
);
thread_mapped_actor_ptr
ctx
{
new
thread_mapped_actor
(
std
::
move
(
what
))};
std
::
thread
{
run_actor
,
ctx
}.
detach
();
return
std
::
move
(
ctx
);
}
actor_ptr
mock_scheduler
::
spawn
(
scheduled_actor
*
)
{
cerr
<<
"mock_scheduler::spawn(scheduled_actor*)"
<<
endl
;
abort
();
return
nullptr
;
}
actor_ptr
mock_scheduler
::
spawn
(
std
::
function
<
void
()
>
what
,
scheduling_hint
)
{
return
spawn_impl
(
what
);
}
void
mock_scheduler
::
enqueue
(
scheduled_actor
*
)
{
cerr
<<
"mock_scheduler::enqueue(scheduled_actor)"
<<
endl
;
abort
();
}
}
}
// namespace detail
src/network_manager.cpp
View file @
e9731720
...
@@ -38,11 +38,12 @@
...
@@ -38,11 +38,12 @@
#include <sys/time.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/types.h>
#include "cppa/self.hpp"
#include "cppa/scheduler.hpp"
#include "cppa/thread_mapped_actor.hpp"
#include "cppa/thread_mapped_actor.hpp"
#include "cppa/detail/mailman.hpp"
#include "cppa/detail/mailman.hpp"
#include "cppa/detail/post_office.hpp"
#include "cppa/detail/post_office.hpp"
#include "cppa/detail/mock_scheduler.hpp"
#include "cppa/detail/network_manager.hpp"
#include "cppa/detail/network_manager.hpp"
namespace
{
namespace
{
...
@@ -64,12 +65,22 @@ struct network_manager_impl : network_manager {
...
@@ -64,12 +65,22 @@ struct network_manager_impl : network_manager {
if
(
pipe
(
pipe_fd
)
!=
0
)
{
if
(
pipe
(
pipe_fd
)
!=
0
)
{
CPPA_CRITICAL
(
"cannot create pipe"
);
CPPA_CRITICAL
(
"cannot create pipe"
);
}
}
// create actors
m_post_office
.
reset
(
new
thread_mapped_actor
);
m_post_office
.
reset
(
new
thread_mapped_actor
);
m_post_office_thread
=
mock_scheduler
::
spawn_hidden_impl
(
std
::
bind
(
post_office_loop
,
pipe_fd
[
0
]),
m_post_office
);
m_mailman
.
reset
(
new
thread_mapped_actor
);
m_mailman
.
reset
(
new
thread_mapped_actor
);
m_mailman_thread
=
mock_scheduler
::
spawn_hidden_impl
(
mailman_loop
,
m_mailman
);
// store some data in local variables for lambdas
int
pipe_fd0
=
pipe_fd
[
0
];
auto
po_ptr
=
m_post_office
;
auto
mm_ptr
=
m_mailman
;
// start threads
m_post_office_thread
=
std
::
thread
([
pipe_fd0
,
po_ptr
]()
{
scoped_self_setter
sss
{
po_ptr
.
get
()};
post_office_loop
(
pipe_fd0
);
});
m_mailman_thread
=
std
::
thread
([
mm_ptr
]()
{
scoped_self_setter
sss
{
mm_ptr
.
get
()};
mailman_loop
();
});
}
}
void
stop
()
{
// override
void
stop
()
{
// override
...
...
src/scheduled_actor.cpp
View file @
e9731720
...
@@ -36,7 +36,7 @@ namespace cppa {
...
@@ -36,7 +36,7 @@ namespace cppa {
scheduled_actor
::
scheduled_actor
(
bool
enable_chained_send
)
scheduled_actor
::
scheduled_actor
(
bool
enable_chained_send
)
:
local_actor
(
enable_chained_send
),
next
(
nullptr
),
m_scheduler
(
nullptr
)
{
}
:
local_actor
(
enable_chained_send
),
next
(
nullptr
),
m_scheduler
(
nullptr
)
{
}
scheduled_actor
*
scheduled_actor
::
attach_to_scheduler
(
scheduler
*
sched
)
{
void
scheduled_actor
::
attach_to_scheduler
(
scheduler
*
sched
)
{
CPPA_REQUIRE
(
sched
!=
nullptr
);
CPPA_REQUIRE
(
sched
!=
nullptr
);
// init is called by the spawning actor, manipulate self to
// init is called by the spawning actor, manipulate self to
// point to this actor
// point to this actor
...
@@ -47,7 +47,6 @@ scheduled_actor* scheduled_actor::attach_to_scheduler(scheduler* sched) {
...
@@ -47,7 +47,6 @@ scheduled_actor* scheduled_actor::attach_to_scheduler(scheduler* sched) {
// make sure scheduler is not set until init() is done
// make sure scheduler is not set until init() is done
std
::
atomic_thread_fence
(
std
::
memory_order_seq_cst
);
std
::
atomic_thread_fence
(
std
::
memory_order_seq_cst
);
m_scheduler
=
sched
;
m_scheduler
=
sched
;
return
this
;
}
}
bool
scheduled_actor
::
initialized
()
{
bool
scheduled_actor
::
initialized
()
{
...
...
src/scheduled_actor_dummy.cpp
View file @
e9731720
...
@@ -32,15 +32,20 @@
...
@@ -32,15 +32,20 @@
namespace
cppa
{
namespace
detail
{
namespace
cppa
{
namespace
detail
{
resume_result
scheduled_actor_dummy
::
resume
(
util
::
fiber
*
)
{
return
resume_result
::
actor_blocked
;
}
void
scheduled_actor_dummy
::
quit
(
std
::
uint32_t
)
{
}
void
scheduled_actor_dummy
::
quit
(
std
::
uint32_t
)
{
}
void
scheduled_actor_dummy
::
dequeue
(
behavior
&
)
{
}
void
scheduled_actor_dummy
::
dequeue
(
behavior
&
)
{
}
void
scheduled_actor_dummy
::
dequeue
(
partial_function
&
)
{
}
void
scheduled_actor_dummy
::
dequeue
(
partial_function
&
)
{
}
void
scheduled_actor_dummy
::
link_to
(
intrusive_ptr
<
actor
>&
)
{
}
void
scheduled_actor_dummy
::
link_to
(
intrusive_ptr
<
actor
>&
)
{
}
void
scheduled_actor_dummy
::
unlink_from
(
intrusive_ptr
<
actor
>&
)
{
}
void
scheduled_actor_dummy
::
unlink_from
(
intrusive_ptr
<
actor
>&
)
{
}
void
scheduled_actor_dummy
::
detach
(
const
attachable
::
token
&
)
{
}
bool
scheduled_actor_dummy
::
attach
(
attachable
*
)
{
return
false
;
}
void
scheduled_actor_dummy
::
unbecome
()
{
}
void
scheduled_actor_dummy
::
do_become
(
behavior
*
,
bool
,
bool
)
{
}
bool
scheduled_actor_dummy
::
has_behavior
()
{
return
false
;
}
resume_result
scheduled_actor_dummy
::
resume
(
util
::
fiber
*
)
{
return
resume_result
::
actor_blocked
;
}
bool
scheduled_actor_dummy
::
establish_backlink
(
intrusive_ptr
<
actor
>&
)
{
bool
scheduled_actor_dummy
::
establish_backlink
(
intrusive_ptr
<
actor
>&
)
{
return
false
;
return
false
;
...
@@ -50,10 +55,8 @@ bool scheduled_actor_dummy::remove_backlink(intrusive_ptr<actor>&) {
...
@@ -50,10 +55,8 @@ bool scheduled_actor_dummy::remove_backlink(intrusive_ptr<actor>&) {
return
false
;
return
false
;
}
}
void
scheduled_actor_dummy
::
detach
(
const
attachable
::
token
&
)
{
}
scheduled_actor_type
scheduled_actor_dummy
::
impl_type
()
{
bool
scheduled_actor_dummy
::
attach
(
attachable
*
)
{
return
false
;
}
return
event_based_impl
;
void
scheduled_actor_dummy
::
unbecome
()
{
}
}
void
scheduled_actor_dummy
::
do_become
(
behavior
*
,
bool
,
bool
)
{
}
bool
scheduled_actor_dummy
::
has_behavior
()
{
return
false
;
}
}
}
// namespace cppa::detail
}
}
// namespace cppa::detail
src/scheduler.cpp
View file @
e9731720
...
@@ -42,7 +42,6 @@
...
@@ -42,7 +42,6 @@
#include "cppa/thread_mapped_actor.hpp"
#include "cppa/thread_mapped_actor.hpp"
#include "cppa/detail/actor_count.hpp"
#include "cppa/detail/actor_count.hpp"
#include "cppa/detail/mock_scheduler.hpp"
#include "cppa/detail/singleton_manager.hpp"
#include "cppa/detail/singleton_manager.hpp"
#include "cppa/detail/thread_pool_scheduler.hpp"
#include "cppa/detail/thread_pool_scheduler.hpp"
...
...
src/thread_pool_scheduler.cpp
View file @
e9731720
...
@@ -35,9 +35,9 @@
...
@@ -35,9 +35,9 @@
#include <iostream>
#include <iostream>
#include "cppa/event_based_actor.hpp"
#include "cppa/event_based_actor.hpp"
#include "cppa/thread_mapped_actor.hpp"
#include "cppa/detail/actor_count.hpp"
#include "cppa/detail/actor_count.hpp"
#include "cppa/detail/mock_scheduler.hpp"
#include "cppa/context_switching_actor.hpp"
#include "cppa/context_switching_actor.hpp"
#include "cppa/detail/thread_pool_scheduler.hpp"
#include "cppa/detail/thread_pool_scheduler.hpp"
...
@@ -195,12 +195,35 @@ void thread_pool_scheduler::enqueue(scheduled_actor* what) {
...
@@ -195,12 +195,35 @@ void thread_pool_scheduler::enqueue(scheduled_actor* what) {
m_queue
.
push_back
(
what
);
m_queue
.
push_back
(
what
);
}
}
actor_ptr
thread_pool_scheduler
::
spawn_impl
(
scheduled_actor_ptr
what
,
actor_ptr
thread_pool_scheduler
::
spawn_as_thread
(
void_function
fun
,
bool
push_to_queue
)
{
init_callback
cb
,
bool
hidden
)
{
if
(
!
hidden
)
inc_actor_count
();
thread_mapped_actor_ptr
ptr
{
new
thread_mapped_actor
(
std
::
move
(
fun
))};
ptr
->
init
();
ptr
->
initialized
(
true
);
cb
(
ptr
.
get
());
std
::
thread
([
hidden
,
ptr
]()
{
scoped_self_setter
sss
{
ptr
.
get
()};
try
{
ptr
->
run
();
ptr
->
on_exit
();
}
catch
(...)
{
}
std
::
atomic_thread_fence
(
std
::
memory_order_seq_cst
);
if
(
!
hidden
)
dec_actor_count
();
}).
detach
();
return
ptr
;
}
actor_ptr
thread_pool_scheduler
::
spawn_impl
(
scheduled_actor_ptr
what
)
{
if
(
what
->
has_behavior
())
{
if
(
what
->
has_behavior
())
{
inc_actor_count
();
inc_actor_count
();
what
->
ref
();
what
->
ref
();
if
(
push_to_queue
)
m_queue
.
push_back
(
what
.
get
());
// event-based actors are not pushed to the job queue on startup
if
(
what
->
impl_type
()
==
context_switching_impl
)
{
m_queue
.
push_back
(
what
.
get
());
}
}
}
else
{
else
{
what
->
on_exit
();
what
->
on_exit
();
...
@@ -208,29 +231,53 @@ actor_ptr thread_pool_scheduler::spawn_impl(scheduled_actor_ptr what,
...
@@ -208,29 +231,53 @@ actor_ptr thread_pool_scheduler::spawn_impl(scheduled_actor_ptr what,
return
std
::
move
(
what
);
return
std
::
move
(
what
);
}
}
actor_ptr
thread_pool_scheduler
::
spawn
(
scheduled_actor
*
ptr
)
{
actor_ptr
thread_pool_scheduler
::
spawn
(
scheduled_actor
*
raw
)
{
// do NOT push event-based actors to the queue on startup
scheduled_actor_ptr
ptr
{
raw
};
scheduled_actor_ptr
what
{
ptr
};
ptr
->
attach_to_scheduler
(
this
);
what
->
attach_to_scheduler
(
this
);
return
spawn_impl
(
std
::
move
(
ptr
));
return
spawn_impl
(
std
::
move
(
what
),
false
);
}
actor_ptr
thread_pool_scheduler
::
spawn
(
scheduled_actor
*
raw
,
init_callback
cb
)
{
scheduled_actor_ptr
ptr
{
raw
};
ptr
->
attach_to_scheduler
(
this
);
cb
(
ptr
.
get
());
return
spawn_impl
(
std
::
move
(
ptr
));
}
}
#ifndef CPPA_DISABLE_CONTEXT_SWITCHING
#ifndef CPPA_DISABLE_CONTEXT_SWITCHING
actor_ptr
thread_pool_scheduler
::
spawn
(
std
::
function
<
void
()
>
bhvr
,
actor_ptr
thread_pool_scheduler
::
spawn
(
void_function
fun
,
scheduling_hint
sh
)
{
scheduling_hint
hint
)
{
if
(
sh
==
scheduled
)
{
if
(
hint
==
scheduled
)
{
scheduled_actor_ptr
ptr
{
new
context_switching_actor
(
std
::
move
(
fun
))};
scheduled_actor_ptr
ptr
{
new
context_switching_actor
(
std
::
move
(
bhvr
))};
ptr
->
attach_to_scheduler
(
this
);
ptr
->
attach_to_scheduler
(
this
);
return
spawn_impl
(
std
::
move
(
ptr
));
return
spawn_impl
(
std
::
move
(
ptr
));
}
}
else
{
else
{
return
mock_scheduler
::
spawn_impl
(
std
::
move
(
bhvr
));
return
spawn_as_thread
(
std
::
move
(
fun
),
[](
local_actor
*
)
{
},
sh
==
detached_and_hidden
);
}
}
actor_ptr
thread_pool_scheduler
::
spawn
(
void_function
fun
,
scheduling_hint
sh
,
init_callback
init_cb
)
{
if
(
sh
==
scheduled
)
{
scheduled_actor_ptr
ptr
{
new
context_switching_actor
(
std
::
move
(
fun
))};
ptr
->
attach_to_scheduler
(
this
);
init_cb
(
ptr
.
get
());
return
spawn_impl
(
std
::
move
(
ptr
));
}
else
{
return
spawn_as_thread
(
std
::
move
(
fun
),
std
::
move
(
init_cb
),
sh
==
detached_and_hidden
);
}
}
}
}
#else
#else
actor_ptr
thread_pool_scheduler
::
spawn
(
std
::
function
<
void
()
>
what
,
actor_ptr
thread_pool_scheduler
::
spawn
(
void_function
what
,
scheduling_hint
)
{
scheduling_hint
)
{
return
spawn_as_thread
(
std
::
move
(
what
),
[](
local_actor
*
)
{
});
return
mock_scheduler
::
spawn_impl
(
std
::
move
(
what
));
}
actor_ptr
thread_pool_scheduler
::
spawn
(
void_function
what
,
scheduling_hint
,
init_callback
init_cb
)
{
return
spawn_as_thread
(
std
::
move
(
what
),
std
::
move
(
init_cb
));
}
}
#endif
#endif
...
...
unit_testing/main.cpp
View file @
e9731720
...
@@ -23,7 +23,6 @@
...
@@ -23,7 +23,6 @@
#include "cppa/detail/demangle.hpp"
#include "cppa/detail/demangle.hpp"
#include "cppa/uniform_type_info.hpp"
#include "cppa/uniform_type_info.hpp"
#include "cppa/process_information.hpp"
#include "cppa/process_information.hpp"
#include "cppa/detail/mock_scheduler.hpp"
#include "cppa/detail/thread_pool_scheduler.hpp"
#include "cppa/detail/thread_pool_scheduler.hpp"
#define CPPA_TEST_CATCH_BLOCK() \
#define CPPA_TEST_CATCH_BLOCK() \
...
@@ -151,10 +150,6 @@ int main(int argc, char** argv) {
...
@@ -151,10 +150,6 @@ int main(int argc, char** argv) {
cout
<<
"using thread_pool_scheduler"
<<
endl
;
cout
<<
"using thread_pool_scheduler"
<<
endl
;
set_scheduler
(
new
cppa
::
detail
::
thread_pool_scheduler
);
set_scheduler
(
new
cppa
::
detail
::
thread_pool_scheduler
);
}
}
else
if
(
sched
==
"mock_scheduler"
)
{
cout
<<
"using mock_scheduler"
<<
endl
;
set_scheduler
(
new
cppa
::
detail
::
mock_scheduler
);
}
else
{
else
{
cerr
<<
"unknown scheduler: "
<<
sched
<<
endl
;
cerr
<<
"unknown scheduler: "
<<
sched
<<
endl
;
exit
(
1
);
exit
(
1
);
...
...
unit_testing/test__local_group.cpp
View file @
e9731720
...
@@ -28,12 +28,11 @@ size_t test__local_group() {
...
@@ -28,12 +28,11 @@ size_t test__local_group() {
actor_ptr
master
=
self
;
actor_ptr
master
=
self
;
for
(
int
i
=
0
;
i
<
5
;
++
i
)
{
for
(
int
i
=
0
;
i
<
5
;
++
i
)
{
// spawn five workers and let them join local/foo
// spawn five workers and let them join local/foo
auto
w
=
spawn
([
&
master
]()
{
spawn_in_group
(
foo_group
,
[
master
]()
{
receive
(
on
<
int
>
()
>>
[
&
master
](
int
v
)
{
receive
(
on
<
int
>
()
>>
[
master
](
int
v
)
{
send
(
master
,
v
);
send
(
master
,
v
);
});
});
});
});
w
->
join
(
foo_group
);
}
}
send
(
foo_group
,
2
);
send
(
foo_group
,
2
);
int
result
=
0
;
int
result
=
0
;
...
...
unit_testing/test__spawn.cpp
View file @
e9731720
...
@@ -302,6 +302,107 @@ std::string behavior_test(actor_ptr et) {
...
@@ -302,6 +302,107 @@ std::string behavior_test(actor_ptr et) {
return
result
;
return
result
;
}
}
#ifdef __clang__
class
fixed_stack
:
public
sb_actor
<
fixed_stack
>
{
friend
class
sb_actor
<
fixed_stack
>
;
static
constexpr
size_t
max_size
=
10
;
std
::
vector
<
int
>
data
;
behavior
full
=
(
on
(
atom
(
"push"
),
arg_match
)
>>
[
=
](
int
)
{
},
on
(
atom
(
"pop"
))
>>
[
=
]()
{
reply
(
atom
(
"ok"
),
data
.
back
());
data
.
pop_back
();
become
(
&
filled
);
}
);
behavior
filled
=
(
on
(
atom
(
"push"
),
arg_match
)
>>
[
=
](
int
what
)
{
data
.
push_back
(
what
);
if
(
data
.
size
()
==
max_size
)
become
(
&
full
);
},
on
(
atom
(
"pop"
))
>>
[
=
]()
{
reply
(
atom
(
"ok"
),
data
.
back
());
data
.
pop_back
();
if
(
data
.
empty
())
become
(
&
empty
);
}
);
behavior
empty
=
(
on
(
atom
(
"push"
),
arg_match
)
>>
[
=
](
int
what
)
{
data
.
push_back
(
what
);
become
(
&
filled
);
},
on
(
atom
(
"pop"
))
>>
[
=
]()
{
reply
(
atom
(
"failure"
));
}
);
behavior
&
init_state
=
empty
;
};
#else
class
fixed_stack
:
public
sb_actor
<
fixed_stack
>
{
friend
class
sb_actor
<
fixed_stack
>
;
static
constexpr
size_t
max_size
=
10
;
std
::
vector
<
int
>
data
;
behavior
full
;
behavior
filled
;
behavior
empty
;
behavior
&
init_state
;
public:
fixed_stack
()
:
init_state
(
empty
)
{
full
=
(
on
(
atom
(
"push"
),
arg_match
)
>>
[
=
](
int
)
{
},
on
(
atom
(
"pop"
))
>>
[
=
]()
{
reply
(
atom
(
"ok"
),
data
.
back
());
data
.
pop_back
();
become
(
&
filled
);
}
);
filled
=
(
on
(
atom
(
"push"
),
arg_match
)
>>
[
=
](
int
what
)
{
data
.
push_back
(
what
);
if
(
data
.
size
()
==
max_size
)
become
(
&
full
);
},
on
(
atom
(
"pop"
))
>>
[
=
]()
{
reply
(
atom
(
"ok"
),
data
.
back
());
data
.
pop_back
();
if
(
data
.
empty
())
become
(
&
empty
);
}
);
empty
=
(
on
(
atom
(
"push"
),
arg_match
)
>>
[
=
](
int
what
)
{
data
.
push_back
(
what
);
become
(
&
filled
);
},
on
(
atom
(
"pop"
))
>>
[
=
]()
{
reply
(
atom
(
"failure"
));
}
);
}
};
#endif
size_t
test__spawn
()
{
size_t
test__spawn
()
{
using
std
::
string
;
using
std
::
string
;
CPPA_TEST
(
test__spawn
);
CPPA_TEST
(
test__spawn
);
...
@@ -401,6 +502,36 @@ size_t test__spawn() {
...
@@ -401,6 +502,36 @@ size_t test__spawn() {
await_all_others_done
();
await_all_others_done
();
CPPA_IF_VERBOSE
(
cout
<<
"ok"
<<
endl
);
CPPA_IF_VERBOSE
(
cout
<<
"ok"
<<
endl
);
CPPA_IF_VERBOSE
(
cout
<<
"test fixed_stack ... "
<<
std
::
flush
);
auto
st
=
spawn
(
new
fixed_stack
);
// push 20 values
for
(
int
i
=
0
;
i
<
20
;
++
i
)
send
(
st
,
atom
(
"push"
),
i
);
// pop 20 times
for
(
int
i
=
0
;
i
<
20
;
++
i
)
send
(
st
,
atom
(
"pop"
));
// expect 10 failure messages
{
int
i
=
0
;
receive_for
(
i
,
10
)
(
on
(
atom
(
"failure"
))
>>
[]()
{
}
);
}
// expect 10 {'ok', value} messages
{
std
::
vector
<
int
>
values
;
int
i
=
0
;
receive_for
(
i
,
10
)
(
on
(
atom
(
"ok"
),
arg_match
)
>>
[
&
](
int
value
)
{
values
.
push_back
(
value
);
}
);
std
::
vector
<
int
>
expected
{
9
,
8
,
7
,
6
,
5
,
4
,
3
,
2
,
1
,
0
};
CPPA_CHECK
(
values
==
expected
);
}
// terminate st
send
(
st
,
atom
(
"EXIT"
),
exit_reason
::
user_defined
);
await_all_others_done
();
CPPA_IF_VERBOSE
(
cout
<<
"ok"
<<
endl
);
int
zombie_init_called
=
0
;
int
zombie_init_called
=
0
;
int
zombie_on_exit_called
=
0
;
int
zombie_on_exit_called
=
0
;
factory
::
event_based
([
&
]()
{
factory
::
event_based
([
&
]()
{
...
@@ -434,6 +565,32 @@ size_t test__spawn() {
...
@@ -434,6 +565,32 @@ size_t test__spawn() {
CPPA_CHECK_EQUAL
(
3
,
zombie_init_called
);
CPPA_CHECK_EQUAL
(
3
,
zombie_init_called
);
CPPA_CHECK_EQUAL
(
3
,
zombie_on_exit_called
);
CPPA_CHECK_EQUAL
(
3
,
zombie_on_exit_called
);
auto
f
=
factory
::
event_based
([](
std
::
string
*
name
)
{
self
->
become
(
on
(
atom
(
"get_name"
))
>>
[
name
]()
{
reply
(
atom
(
"name"
),
*
name
);
}
);
});
auto
a1
=
f
.
spawn
(
"alice"
);
auto
a2
=
f
.
spawn
(
"bob"
);
send
(
a1
,
atom
(
"get_name"
));
receive
(
on
(
atom
(
"name"
),
arg_match
)
>>
[
&
](
const
std
::
string
&
name
)
{
CPPA_CHECK_EQUAL
(
"alice"
,
name
);
}
);
send
(
a2
,
atom
(
"get_name"
));
receive
(
on
(
atom
(
"name"
),
arg_match
)
>>
[
&
](
const
std
::
string
&
name
)
{
CPPA_CHECK_EQUAL
(
"bob"
,
name
);
}
);
auto
kill_msg
=
make_any_tuple
(
atom
(
"EXIT"
),
exit_reason
::
user_defined
);
a1
<<
kill_msg
;
a2
<<
kill_msg
;
await_all_others_done
();
CPPA_CHECK_EQUAL
(
behavior_test
<
testee_actor
>
(
spawn
(
testee_actor
{})),
"wait4int"
);
CPPA_CHECK_EQUAL
(
behavior_test
<
testee_actor
>
(
spawn
(
testee_actor
{})),
"wait4int"
);
CPPA_CHECK_EQUAL
(
behavior_test
<
event_testee
>
(
spawn
(
new
event_testee
)),
"wait4int"
);
CPPA_CHECK_EQUAL
(
behavior_test
<
event_testee
>
(
spawn
(
new
event_testee
)),
"wait4int"
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment