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
ce955a9c
Commit
ce955a9c
authored
Apr 21, 2012
by
neverlord
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
nestable receive via mixin rather than policy
parent
8e7a9375
Changes
17
Show whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
258 additions
and
223 deletions
+258
-223
cppa.files
cppa.files
+2
-1
cppa/abstract_event_based_actor.hpp
cppa/abstract_event_based_actor.hpp
+1
-1
cppa/behavior.hpp
cppa/behavior.hpp
+15
-0
cppa/detail/abstract_scheduled_actor.hpp
cppa/detail/abstract_scheduled_actor.hpp
+3
-9
cppa/detail/converted_thread_context.hpp
cppa/detail/converted_thread_context.hpp
+14
-41
cppa/detail/filter_result.hpp
cppa/detail/filter_result.hpp
+46
-0
cppa/detail/nestable_receive_actor.hpp
cppa/detail/nestable_receive_actor.hpp
+91
-62
cppa/detail/recursive_queue_node.hpp
cppa/detail/recursive_queue_node.hpp
+4
-22
cppa/detail/yielding_actor.hpp
cppa/detail/yielding_actor.hpp
+17
-48
cppa/intrusive/single_reader_queue.hpp
cppa/intrusive/single_reader_queue.hpp
+2
-2
cppa/scheduled_actor.hpp
cppa/scheduled_actor.hpp
+1
-1
src/abstract_event_based_actor.cpp
src/abstract_event_based_actor.cpp
+7
-6
src/converted_thread_context.cpp
src/converted_thread_context.cpp
+39
-12
src/scheduled_actor.cpp
src/scheduled_actor.cpp
+2
-2
src/scheduler.cpp
src/scheduler.cpp
+3
-2
src/yielding_actor.cpp
src/yielding_actor.cpp
+10
-13
unit_testing/main.cpp
unit_testing/main.cpp
+1
-1
No files found.
cppa.files
View file @
ce955a9c
...
@@ -267,4 +267,5 @@ cppa/match_expr.hpp
...
@@ -267,4 +267,5 @@ cppa/match_expr.hpp
cppa/detail/pseudo_tuple.hpp
cppa/detail/pseudo_tuple.hpp
cppa/detail/recursive_queue_node.hpp
cppa/detail/recursive_queue_node.hpp
cppa/detail/scheduled_actor_dummy.hpp
cppa/detail/scheduled_actor_dummy.hpp
cppa/detail/nestable_invoke_policy.hpp
cppa/detail/nestable_receive_actor.hpp
cppa/detail/filter_result.hpp
cppa/abstract_event_based_actor.hpp
View file @
ce955a9c
...
@@ -81,7 +81,7 @@ class abstract_event_based_actor : public detail::abstract_scheduled_actor
...
@@ -81,7 +81,7 @@ class abstract_event_based_actor : public detail::abstract_scheduled_actor
cache_msg
cache_msg
};
};
auto
handle_message
(
mailbox_element
&
iter
)
->
handle_message_result
;
auto
handle_message
(
mailbox_element
&
node
)
->
handle_message_result
;
abstract_event_based_actor
();
abstract_event_based_actor
();
...
...
cppa/behavior.hpp
View file @
ce955a9c
...
@@ -97,6 +97,21 @@ class behavior
...
@@ -97,6 +97,21 @@ class behavior
return
m_fun
;
return
m_fun
;
}
}
inline
bool
operator
()(
any_tuple
&
value
)
{
return
m_fun
(
value
);
}
inline
bool
operator
()(
any_tuple
const
&
value
)
{
return
m_fun
(
value
);
}
inline
bool
operator
()(
any_tuple
&&
value
)
{
return
m_fun
(
std
::
move
(
value
));
}
private:
private:
// terminates recursion
// terminates recursion
...
...
cppa/detail/abstract_scheduled_actor.hpp
View file @
ce955a9c
...
@@ -42,6 +42,7 @@
...
@@ -42,6 +42,7 @@
#include "cppa/scheduled_actor.hpp"
#include "cppa/scheduled_actor.hpp"
#include "cppa/util/fiber.hpp"
#include "cppa/util/fiber.hpp"
#include "cppa/detail/filter_result.hpp"
#include "cppa/detail/recursive_queue_node.hpp"
#include "cppa/detail/recursive_queue_node.hpp"
#include "cppa/intrusive/single_reader_queue.hpp"
#include "cppa/intrusive/single_reader_queue.hpp"
...
@@ -58,14 +59,6 @@ class abstract_scheduled_actor : public abstract_actor<scheduled_actor>
...
@@ -58,14 +59,6 @@ class abstract_scheduled_actor : public abstract_actor<scheduled_actor>
std
::
atomic
<
int
>
m_state
;
std
::
atomic
<
int
>
m_state
;
enum
filter_result
{
normal_exit_signal
,
expired_timeout_message
,
timeout_message
,
ordinary_message
};
filter_result
filter_msg
(
any_tuple
const
&
msg
)
filter_result
filter_msg
(
any_tuple
const
&
msg
)
{
{
auto
&
arr
=
detail
::
static_types_array
<
atom_value
,
std
::
uint32_t
>::
arr
;
auto
&
arr
=
detail
::
static_types_array
<
atom_value
,
std
::
uint32_t
>::
arr
;
...
@@ -130,7 +123,7 @@ class abstract_scheduled_actor : public abstract_actor<scheduled_actor>
...
@@ -130,7 +123,7 @@ class abstract_scheduled_actor : public abstract_actor<scheduled_actor>
static
constexpr
int
about_to_block
=
0x04
;
static
constexpr
int
about_to_block
=
0x04
;
abstract_scheduled_actor
(
int
state
=
done
)
abstract_scheduled_actor
(
int
state
=
done
)
:
m_state
(
state
)
:
super
(
true
),
m_state
(
state
)
,
m_has_pending_timeout_request
(
false
)
,
m_has_pending_timeout_request
(
false
)
,
m_active_timeout_id
(
0
)
,
m_active_timeout_id
(
0
)
{
{
...
@@ -171,6 +164,7 @@ class abstract_scheduled_actor : public abstract_actor<scheduled_actor>
...
@@ -171,6 +164,7 @@ class abstract_scheduled_actor : public abstract_actor<scheduled_actor>
bool
enqueue_node
(
typename
super
::
mailbox_element
*
node
,
bool
enqueue_node
(
typename
super
::
mailbox_element
*
node
,
int
target_state
=
ready
)
int
target_state
=
ready
)
{
{
CPPA_REQUIRE
(
node
->
marked
==
false
);
if
(
this
->
m_mailbox
.
_push_back
(
node
))
if
(
this
->
m_mailbox
.
_push_back
(
node
))
{
{
for
(;;)
for
(;;)
...
...
cppa/detail/converted_thread_context.hpp
View file @
ce955a9c
...
@@ -49,47 +49,21 @@
...
@@ -49,47 +49,21 @@
#include "cppa/exit_reason.hpp"
#include "cppa/exit_reason.hpp"
#include "cppa/abstract_actor.hpp"
#include "cppa/abstract_actor.hpp"
#include "cppa/intrusive/singly_linked_list.hpp"
#include "cppa/intrusive/singly_linked_list.hpp"
#include "cppa/detail/nestable_
invoke_policy
.hpp"
#include "cppa/detail/nestable_
receive_actor
.hpp"
namespace
cppa
{
namespace
detail
{
namespace
cppa
{
namespace
detail
{
/**
/**
* @brief Represents a thread that was converted to an Actor.
* @brief Represents a thread that was converted to an Actor.
*/
*/
class
converted_thread_context
:
public
abstract_actor
<
local_actor
>
class
converted_thread_context
:
public
nestable_receive_actor
<
converted_thread_context
,
abstract_actor
<
local_actor
>
>
{
{
typedef
abstract_actor
<
local_actor
>
super
;
typedef
nestable_receive_actor
<
converted_thread_context
,
abstract_actor
<
local_actor
>
>
struct
filter_policy
;
super
;
friend
struct
filter_policy
;
struct
filter_policy
{
converted_thread_context
*
m_parent
;
inline
filter_policy
(
converted_thread_context
*
ptr
)
:
m_parent
(
ptr
)
{
}
inline
bool
operator
()(
any_tuple
const
&
msg
)
{
if
(
m_parent
->
m_trap_exit
==
false
&&
matches
(
msg
,
m_parent
->
m_exit_msg_pattern
))
{
auto
reason
=
msg
.
get_as
<
std
::
uint32_t
>
(
1
);
if
(
reason
!=
exit_reason
::
normal
)
{
m_parent
->
quit
(
reason
);
}
return
true
;
}
return
false
;
}
};
public:
public:
...
@@ -106,18 +80,17 @@ class converted_thread_context : public abstract_actor<local_actor>
...
@@ -106,18 +80,17 @@ class converted_thread_context : public abstract_actor<local_actor>
void
dequeue
(
partial_function
&
rules
);
//override
void
dequeue
(
partial_function
&
rules
);
//override
inline
decltype
(
m_mailbox
)
&
mailbox
()
inline
void
push_timeout
()
{
}
{
return
m_mailbox
;
}
private:
inline
void
pop_timeout
()
{
}
filter_result
filter_msg
(
any_tuple
const
&
msg
);
// a list is safe to use in a nested receive
inline
decltype
(
m_mailbox
)
&
mailbox
()
{
return
m_mailbox
;
}
typedef
std
::
unique_ptr
<
recursive_queue_node
>
queue_node_ptr
;
private:
pattern
<
atom_value
,
std
::
uint32_t
>
m_exit_msg_pattern
;
pattern
<
atom_value
,
std
::
uint32_t
>
m_exit_msg_pattern
;
nestable_invoke_policy
<
filter_policy
>
m_invoke
;
};
};
...
...
cppa/detail/filter_result.hpp
0 → 100644
View file @
ce955a9c
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \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 FILTER_RESULT_HPP
#define FILTER_RESULT_HPP
namespace
cppa
{
namespace
detail
{
enum
filter_result
{
normal_exit_signal
,
expired_timeout_message
,
timeout_message
,
ordinary_message
};
}
}
// namespace cppa::detail
#endif // FILTER_RESULT_HPP
cppa/detail/nestable_
invoke_policy
.hpp
→
cppa/detail/nestable_
receive_actor
.hpp
View file @
ce955a9c
...
@@ -28,82 +28,88 @@
...
@@ -28,82 +28,88 @@
\******************************************************************************/
\******************************************************************************/
#ifndef NESTABLE_
INVOKE_POLICY
_HPP
#ifndef NESTABLE_
RECEIVE_ACTOR
_HPP
#define NESTABLE_
INVOKE_POLICY
_HPP
#define NESTABLE_
RECEIVE_ACTOR
_HPP
#include <list>
#include <memory>
#include <memory>
#include "cppa/config.hpp"
#include "cppa/behavior.hpp"
#include "cppa/behavior.hpp"
#include "cppa/local_actor.hpp"
#include "cppa/partial_function.hpp"
#include "cppa/partial_function.hpp"
#include "cppa/detail/filter_result.hpp"
#include "cppa/detail/recursive_queue_node.hpp"
#include "cppa/detail/recursive_queue_node.hpp"
namespace
cppa
{
namespace
detail
{
namespace
cppa
{
namespace
detail
{
template
<
class
FilterPolicy
>
template
<
class
Derived
,
class
Base
>
class
nestable_
invoke_policy
class
nestable_
receive_actor
:
public
Base
{
{
p
ublic
:
p
rotected
:
typedef
std
::
unique_ptr
<
recursive_queue_node
>
queue_node_ptr
;
enum
handle_message_result
template
<
typename
...
Args
>
nestable_invoke_policy
(
local_actor
*
parent
,
Args
&&
...
args
)
:
m_last_dequeued
(
parent
->
last_dequeued
())
,
m_last_sender
(
parent
->
last_sender
())
,
m_filter_policy
(
std
::
forward
<
Args
>
(
args
)...)
{
{
}
hm_timeout_msg
,
hm_skip_msg
,
hm_drop_msg
,
hm_cache_msg
,
hm_success
};
template
<
typename
...
Args
>
template
<
class
FunOrBehavior
>
bool
invoke_from_cache
(
partial_function
&
fun
,
Args
...
args
)
bool
invoke_from_cache
(
FunOrBehavior
&
fun
)
{
{
auto
i
=
m_cache
.
begin
();
auto
i
=
m_cache
.
begin
();
auto
e
=
m_cache
.
end
();
auto
e
=
m_cache
.
end
();
while
(
i
!=
e
)
while
(
i
!=
e
)
{
{
switch
(
handle_message
(
*
(
*
i
),
fun
,
args
...))
switch
(
this
->
handle_message
(
*
(
*
i
),
fun
))
{
case
hm_drop_msg
:
{
{
i
=
m_cache
.
erase
(
i
);
break
;
}
case
hm_success
:
case
hm_success
:
{
{
this
->
release_node
(
i
->
release
());
m_cache
.
erase
(
i
);
m_cache
.
erase
(
i
);
return
true
;
return
true
;
}
}
case
hm_drop_msg
:
{
this
->
release_node
(
i
->
release
());
i
=
m_cache
.
erase
(
i
);
break
;
}
case
hm_skip_msg
:
case
hm_skip_msg
:
case
hm_cache_msg
:
case
hm_cache_msg
:
{
{
++
i
;
++
i
;
break
;
break
;
}
}
default:
CPPA_CRITICAL
(
"illegal result of handle_message"
);
default:
{
CPPA_CRITICAL
(
"illegal result of handle_message"
);
}
}
}
}
}
return
false
;
return
false
;
}
}
template
<
typename
...
Args
>
template
<
class
FunOrBehavior
>
bool
invoke
(
queue_node_ptr
&
ptr
,
partial_function
&
fun
,
Args
...
args
)
bool
invoke
(
recursive_queue_node
*
node
,
FunOrBehavior
&
fun
)
{
{
switch
(
handle_message
(
*
ptr
,
fun
,
args
...
))
switch
(
this
->
handle_message
(
*
node
,
fun
))
{
{
case
hm_
drop_msg
:
case
hm_
success
:
{
{
break
;
this
->
release_node
(
node
);
return
true
;
}
}
case
hm_
success
:
case
hm_
drop_msg
:
{
{
return
true
;
// done
this
->
release_node
(
node
);
break
;
}
}
case
hm_cache_msg
:
case
hm_cache_msg
:
{
{
m_cache
.
push_back
(
std
::
move
(
ptr
)
);
m_cache
.
emplace_back
(
node
);
break
;
break
;
}
}
case
hm_skip_msg
:
case
hm_skip_msg
:
...
@@ -120,54 +126,77 @@ class nestable_invoke_policy
...
@@ -120,54 +126,77 @@ class nestable_invoke_policy
private:
private:
enum
handle_message_result
std
::
list
<
std
::
unique_ptr
<
recursive_queue_node
>
>
m_cache
;
inline
Derived
*
dthis
()
{
{
hm_timeout_msg
,
return
static_cast
<
Derived
*>
(
this
);
hm_skip_msg
,
}
hm_drop_msg
,
hm_cache_msg
,
hm_success
};
any_tuple
&
m_last_dequeued
;
inline
Derived
const
*
dthis
()
const
actor_ptr
&
m_last_sender
;
{
FilterPolicy
m_filter_policy
;
return
static_cast
<
Derived
const
*>
(
this
);
std
::
list
<
queue_node_ptr
>
m_cache
;
}
void
handle_timeout
(
behavior
&
bhvr
)
{
bhvr
.
handle_timeout
();
}
template
<
typename
...
Args
>
void
handle_timeout
(
partial_function
&
)
{
CPPA_CRITICAL
(
"handle_timeout(partial_function&)"
);
}
template
<
class
FunOrBehavior
>
handle_message_result
handle_message
(
recursive_queue_node
&
node
,
handle_message_result
handle_message
(
recursive_queue_node
&
node
,
partial_function
&
fun
,
FunOrBehavior
&
fun
)
Args
...
args
)
{
{
if
(
node
.
marked
)
if
(
node
.
marked
)
{
{
return
hm_skip_msg
;
return
hm_skip_msg
;
}
}
if
(
m_filter_policy
(
node
.
msg
,
args
...))
switch
(
dthis
()
->
filter_msg
(
node
.
msg
))
{
case
normal_exit_signal
:
case
expired_timeout_message
:
{
{
return
hm_drop_msg
;
return
hm_drop_msg
;
}
}
std
::
swap
(
m_last_dequeued
,
node
.
msg
);
case
timeout_message
:
std
::
swap
(
m_last_sender
,
node
.
sender
);
{
{
typename
recursive_queue_node
::
guard
qguard
{
&
node
};
handle_timeout
(
fun
);
if
(
fun
(
m_last_dequeued
))
{
// client calls erase(iter)
qguard
.
release
();
m_last_dequeued
.
reset
();
m_last_sender
.
reset
();
return
hm_success
;
return
hm_success
;
}
}
case
ordinary_message
:
{
break
;
}
default:
{
CPPA_CRITICAL
(
"illegal result of filter_msg"
);
}
}
std
::
swap
(
this
->
m_last_dequeued
,
node
.
msg
);
std
::
swap
(
this
->
m_last_sender
,
node
.
sender
);
dthis
()
->
push_timeout
();
node
.
marked
=
true
;
if
(
fun
(
this
->
m_last_dequeued
))
{
this
->
m_last_dequeued
.
reset
();
this
->
m_last_sender
.
reset
();
return
hm_success
;
}
}
// no match (restore members)
// no match (restore members)
std
::
swap
(
m_last_dequeued
,
node
.
msg
);
std
::
swap
(
this
->
m_last_dequeued
,
node
.
msg
);
std
::
swap
(
m_last_sender
,
node
.
sender
);
std
::
swap
(
this
->
m_last_sender
,
node
.
sender
);
dthis
()
->
pop_timeout
();
node
.
marked
=
false
;
return
hm_cache_msg
;
return
hm_cache_msg
;
}
}
};
};
}
}
}
}
// namespace cppa::detail
#endif // NESTABLE_
INVOKE_POLICY
_HPP
#endif // NESTABLE_
RECEIVE_ACTOR
_HPP
cppa/detail/recursive_queue_node.hpp
View file @
ce955a9c
...
@@ -43,13 +43,11 @@ struct recursive_queue_node
...
@@ -43,13 +43,11 @@ struct recursive_queue_node
actor_ptr
sender
;
actor_ptr
sender
;
any_tuple
msg
;
any_tuple
msg
;
inline
recursive_queue_node
()
inline
recursive_queue_node
()
:
next
(
nullptr
),
marked
(
false
)
:
next
(
nullptr
)
,
marked
(
false
)
{
{
}
}
inline
recursive_queue_node
(
actor
*
from
,
any_tuple
content
)
inline
recursive_queue_node
(
actor
*
from
,
any_tuple
&&
content
)
:
next
(
nullptr
)
:
next
(
nullptr
)
,
marked
(
false
)
,
marked
(
false
)
,
sender
(
from
)
,
sender
(
from
)
...
@@ -57,27 +55,11 @@ struct recursive_queue_node
...
@@ -57,27 +55,11 @@ struct recursive_queue_node
{
{
}
}
recursive_queue_node
(
recursive_queue_node
&&
)
=
delete
;
recursive_queue_node
(
recursive_queue_node
const
&
)
=
delete
;
recursive_queue_node
(
recursive_queue_node
const
&
)
=
delete
;
recursive_queue_node
&
operator
=
(
recursive_queue_node
&&
)
=
delete
;
recursive_queue_node
&
operator
=
(
recursive_queue_node
const
&
)
=
delete
;
recursive_queue_node
&
operator
=
(
recursive_queue_node
const
&
)
=
delete
;
struct
guard
{
recursive_queue_node
*
m_node
;
inline
guard
(
recursive_queue_node
*
ptr
)
:
m_node
(
ptr
)
{
ptr
->
marked
=
true
;
}
inline
void
release
()
{
m_node
=
nullptr
;
}
inline
~
guard
()
{
if
(
m_node
)
m_node
->
marked
=
false
;
}
};
};
};
}
}
// namespace cppa::detail
}
}
// namespace cppa::detail
...
...
cppa/detail/yielding_actor.hpp
View file @
ce955a9c
...
@@ -41,15 +41,19 @@
...
@@ -41,15 +41,19 @@
#include "cppa/pattern.hpp"
#include "cppa/pattern.hpp"
#include "cppa/detail/yield_interface.hpp"
#include "cppa/detail/yield_interface.hpp"
#include "cppa/detail/nestable_
invoke_policy
.hpp"
#include "cppa/detail/nestable_
receive_actor
.hpp"
#include "cppa/detail/abstract_scheduled_actor.hpp"
#include "cppa/detail/abstract_scheduled_actor.hpp"
namespace
cppa
{
namespace
detail
{
namespace
cppa
{
namespace
detail
{
class
yielding_actor
:
public
abstract_scheduled_actor
class
yielding_actor
:
public
nestable_receive_actor
<
yielding_actor
,
abstract_scheduled_actor
>
{
{
typedef
abstract_scheduled_actor
super
;
typedef
nestable_receive_actor
<
yielding_actor
,
abstract_scheduled_actor
>
super
;
public:
public:
...
@@ -61,6 +65,16 @@ class yielding_actor : public abstract_scheduled_actor
...
@@ -61,6 +65,16 @@ class yielding_actor : public abstract_scheduled_actor
void
resume
(
util
::
fiber
*
from
,
scheduler
::
callback
*
callback
);
//override
void
resume
(
util
::
fiber
*
from
,
scheduler
::
callback
*
callback
);
//override
inline
void
push_timeout
()
{
++
m_active_timeout_id
;
}
inline
void
pop_timeout
()
{
--
m_active_timeout_id
;
}
private:
private:
typedef
std
::
unique_ptr
<
recursive_queue_node
>
queue_node_ptr
;
typedef
std
::
unique_ptr
<
recursive_queue_node
>
queue_node_ptr
;
...
@@ -69,53 +83,8 @@ class yielding_actor : public abstract_scheduled_actor
...
@@ -69,53 +83,8 @@ class yielding_actor : public abstract_scheduled_actor
void
yield_until_not_empty
();
void
yield_until_not_empty
();
struct
filter_policy
;
friend
struct
filter_policy
;
struct
filter_policy
{
yielding_actor
*
m_parent
;
inline
filter_policy
(
yielding_actor
*
parent
)
:
m_parent
(
parent
)
{
}
inline
bool
operator
()(
any_tuple
const
&
msg
)
{
return
m_parent
->
filter_msg
(
msg
)
!=
ordinary_message
;
}
inline
bool
operator
()(
any_tuple
const
&
msg
,
behavior
*
bhvr
,
bool
*
timeout_occured
)
{
switch
(
m_parent
->
filter_msg
(
msg
))
{
case
timeout_message
:
{
bhvr
->
handle_timeout
();
*
timeout_occured
=
true
;
return
true
;
}
case
normal_exit_signal
:
case
expired_timeout_message
:
{
return
true
;
}
case
ordinary_message
:
{
return
false
;
}
default:
CPPA_CRITICAL
(
"illegal result of filter_msg"
);
}
return
false
;
}
};
util
::
fiber
m_fiber
;
util
::
fiber
m_fiber
;
std
::
function
<
void
()
>
m_behavior
;
std
::
function
<
void
()
>
m_behavior
;
nestable_invoke_policy
<
filter_policy
>
m_invoke
;
};
};
...
...
cppa/intrusive/single_reader_queue.hpp
View file @
ce955a9c
...
@@ -131,7 +131,7 @@ class single_reader_queue
...
@@ -131,7 +131,7 @@ class single_reader_queue
*/
*/
inline
bool
empty
()
const
inline
bool
empty
()
const
{
{
return
!
m_head
&&
m_stack
.
load
()
==
nullptr
;
return
m_head
==
nullptr
&&
m_stack
.
load
()
==
nullptr
;
}
}
/**
/**
...
@@ -170,7 +170,7 @@ class single_reader_queue
...
@@ -170,7 +170,7 @@ class single_reader_queue
if
(
empty
())
if
(
empty
())
{
{
lock_type
guard
(
m_mtx
);
lock_type
guard
(
m_mtx
);
while
(
!
(
m_stack
.
load
())
)
while
(
m_stack
.
load
()
==
nullptr
)
{
{
if
(
detail
::
wait_until
(
guard
,
m_cv
,
timeout
)
==
false
)
if
(
detail
::
wait_until
(
guard
,
m_cv
,
timeout
)
==
false
)
{
{
...
...
cppa/scheduled_actor.hpp
View file @
ce955a9c
...
@@ -54,7 +54,7 @@ class scheduled_actor : public local_actor
...
@@ -54,7 +54,7 @@ class scheduled_actor : public local_actor
public:
public:
scheduled_actor
();
scheduled_actor
(
bool
enable_pending_enqueue
=
false
);
scheduled_actor
*
next
;
// intrusive next pointer
scheduled_actor
*
next
;
// intrusive next pointer
...
...
src/abstract_event_based_actor.cpp
View file @
ce955a9c
...
@@ -32,9 +32,11 @@
...
@@ -32,9 +32,11 @@
#include "cppa/to_string.hpp"
#include "cppa/to_string.hpp"
#include "cppa/self.hpp"
#include "cppa/self.hpp"
#include "cppa/detail/invokable.hpp"
#include "cppa/abstract_event_based_actor.hpp"
#include "cppa/abstract_event_based_actor.hpp"
#include "cppa/detail/invokable.hpp"
#include "cppa/detail/filter_result.hpp"
namespace
cppa
{
namespace
cppa
{
abstract_event_based_actor
::
abstract_event_based_actor
()
abstract_event_based_actor
::
abstract_event_based_actor
()
...
@@ -55,15 +57,16 @@ void abstract_event_based_actor::dequeue(partial_function&)
...
@@ -55,15 +57,16 @@ void abstract_event_based_actor::dequeue(partial_function&)
auto
abstract_event_based_actor
::
handle_message
(
mailbox_element
&
node
)
->
handle_message_result
auto
abstract_event_based_actor
::
handle_message
(
mailbox_element
&
node
)
->
handle_message_result
{
{
CPPA_REQUIRE
(
node
.
marked
==
false
);
CPPA_REQUIRE
(
m_loop_stack
.
empty
()
==
false
);
CPPA_REQUIRE
(
m_loop_stack
.
empty
()
==
false
);
auto
&
bhvr
=
*
(
m_loop_stack
.
back
());
auto
&
bhvr
=
*
(
m_loop_stack
.
back
());
switch
(
filter_msg
(
node
.
msg
))
switch
(
filter_msg
(
node
.
msg
))
{
{
case
normal_exit_signal
:
case
detail
:
:
normal_exit_signal
:
case
expired_timeout_message
:
case
detail
:
:
expired_timeout_message
:
return
drop_msg
;
return
drop_msg
;
case
timeout_message
:
case
detail
:
:
timeout_message
:
m_has_pending_timeout_request
=
false
;
m_has_pending_timeout_request
=
false
;
CPPA_REQUIRE
(
bhvr
.
timeout
().
valid
());
CPPA_REQUIRE
(
bhvr
.
timeout
().
valid
());
bhvr
.
handle_timeout
();
bhvr
.
handle_timeout
();
...
@@ -79,8 +82,6 @@ auto abstract_event_based_actor::handle_message(mailbox_element& node) -> handle
...
@@ -79,8 +82,6 @@ auto abstract_event_based_actor::handle_message(mailbox_element& node) -> handle
}
}
std
::
swap
(
m_last_dequeued
,
node
.
msg
);
std
::
swap
(
m_last_dequeued
,
node
.
msg
);
std
::
swap
(
m_last_sender
,
node
.
sender
);
std
::
swap
(
m_last_sender
,
node
.
sender
);
//m_last_dequeued = node.msg;
//m_last_sender = node.sender;
if
((
bhvr
.
get_partial_function
())(
m_last_dequeued
))
if
((
bhvr
.
get_partial_function
())(
m_last_dequeued
))
{
{
m_last_dequeued
.
reset
();
m_last_dequeued
.
reset
();
...
...
src/converted_thread_context.cpp
View file @
ce955a9c
...
@@ -33,6 +33,7 @@
...
@@ -33,6 +33,7 @@
#include <algorithm>
#include <algorithm>
#include "cppa/self.hpp"
#include "cppa/self.hpp"
#include "cppa/to_string.hpp"
#include "cppa/exception.hpp"
#include "cppa/exception.hpp"
#include "cppa/detail/matches.hpp"
#include "cppa/detail/matches.hpp"
#include "cppa/detail/invokable.hpp"
#include "cppa/detail/invokable.hpp"
...
@@ -41,7 +42,7 @@
...
@@ -41,7 +42,7 @@
namespace
cppa
{
namespace
detail
{
namespace
cppa
{
namespace
detail
{
converted_thread_context
::
converted_thread_context
()
converted_thread_context
::
converted_thread_context
()
:
m_exit_msg_pattern
(
atom
(
":Exit"
))
,
m_invoke
(
this
,
this
)
:
m_exit_msg_pattern
(
atom
(
":Exit"
))
{
{
}
}
...
@@ -61,17 +62,24 @@ void converted_thread_context::cleanup(std::uint32_t reason)
...
@@ -61,17 +62,24 @@ void converted_thread_context::cleanup(std::uint32_t reason)
void
converted_thread_context
::
enqueue
(
actor
*
sender
,
any_tuple
msg
)
void
converted_thread_context
::
enqueue
(
actor
*
sender
,
any_tuple
msg
)
{
{
# ifdef CPPA_DEBUG
auto
node
=
fetch_node
(
sender
,
std
::
move
(
msg
));
CPPA_REQUIRE
(
node
->
marked
==
false
);
m_mailbox
.
push_back
(
node
);
# else
m_mailbox
.
push_back
(
fetch_node
(
sender
,
std
::
move
(
msg
)));
m_mailbox
.
push_back
(
fetch_node
(
sender
,
std
::
move
(
msg
)));
# endif
}
}
void
converted_thread_context
::
dequeue
(
partial_function
&
fun
)
// override
void
converted_thread_context
::
dequeue
(
partial_function
&
fun
)
// override
{
{
if
(
m_invoke
.
invoke_from_cache
(
fun
)
==
false
)
if
(
invoke_from_cache
(
fun
)
==
false
)
{
{
queue_node_ptr
e
{
m_mailbox
.
pop
()};
recursive_queue_node
*
e
=
m_mailbox
.
pop
();
while
(
m_invoke
.
invoke
(
e
,
fun
)
==
false
)
CPPA_REQUIRE
(
e
->
marked
==
false
);
while
(
invoke
(
e
,
fun
)
==
false
)
{
{
e
.
reset
(
m_mailbox
.
pop
()
);
e
=
m_mailbox
.
pop
(
);
}
}
}
}
}
}
...
@@ -81,21 +89,40 @@ void converted_thread_context::dequeue(behavior& bhvr) // override
...
@@ -81,21 +89,40 @@ void converted_thread_context::dequeue(behavior& bhvr) // override
auto
&
fun
=
bhvr
.
get_partial_function
();
auto
&
fun
=
bhvr
.
get_partial_function
();
if
(
bhvr
.
timeout
().
valid
()
==
false
)
if
(
bhvr
.
timeout
().
valid
()
==
false
)
{
{
dequeue
(
fun
);
// suppress virtual function call
return
;
converted_thread_context
::
dequeue
(
fun
)
;
}
}
if
(
m_invoke
.
invoke_from_cache
(
fun
)
==
false
)
else
if
(
invoke_from_cache
(
fun
)
==
false
)
{
{
auto
timeout
=
now
();
auto
timeout
=
now
();
timeout
+=
bhvr
.
timeout
();
timeout
+=
bhvr
.
timeout
();
queue_node_ptr
e
{
m_mailbox
.
try_pop
(
timeout
)}
;
recursive_queue_node
*
e
=
m_mailbox
.
try_pop
(
timeout
)
;
while
(
e
)
while
(
e
!=
nullptr
)
{
{
if
(
m_invoke
.
invoke
(
e
,
fun
))
return
;
if
(
e
->
marked
)
else
e
.
reset
(
m_mailbox
.
try_pop
(
timeout
));
{
std
::
cout
<<
"ooops: "
<<
to_string
(
e
->
msg
)
<<
std
::
endl
;
}
CPPA_REQUIRE
(
e
->
marked
==
false
);
if
(
invoke
(
e
,
fun
))
return
;
e
=
m_mailbox
.
try_pop
(
timeout
);
}
}
bhvr
.
handle_timeout
();
bhvr
.
handle_timeout
();
}
}
}
}
filter_result
converted_thread_context
::
filter_msg
(
any_tuple
const
&
msg
)
{
if
(
m_trap_exit
==
false
&&
matches
(
msg
,
m_exit_msg_pattern
))
{
auto
reason
=
msg
.
get_as
<
std
::
uint32_t
>
(
1
);
if
(
reason
!=
exit_reason
::
normal
)
{
quit
(
reason
);
}
return
normal_exit_signal
;
}
return
ordinary_message
;
}
}
}
// namespace cppa::detail
}
}
// namespace cppa::detail
src/scheduled_actor.cpp
View file @
ce955a9c
...
@@ -32,8 +32,8 @@
...
@@ -32,8 +32,8 @@
namespace
cppa
{
namespace
cppa
{
scheduled_actor
::
scheduled_actor
(
)
:
local_actor
(
tr
ue
)
scheduled_actor
::
scheduled_actor
(
bool
enable_pending_enque
ue
)
,
next
(
nullptr
),
m_scheduler
(
nullptr
)
:
local_actor
(
enable_pending_enqueue
)
,
next
(
nullptr
),
m_scheduler
(
nullptr
)
{
{
}
}
...
...
src/scheduler.cpp
View file @
ce955a9c
...
@@ -110,7 +110,7 @@ void scheduler_helper::time_emitter(scheduler_helper::ptr_type m_self)
...
@@ -110,7 +110,7 @@ void scheduler_helper::time_emitter(scheduler_helper::ptr_type m_self)
decltype
(
detail
::
now
())
now
;
decltype
(
detail
::
now
())
now
;
bool
done
=
false
;
bool
done
=
false
;
// message handling rules
// message handling rules
auto
handle_msg
=
auto
mfun
=
(
(
on
<
util
::
duration
,
actor_ptr
,
anything
>
()
>>
[
&
](
const
util
::
duration
&
d
,
on
<
util
::
duration
,
actor_ptr
,
anything
>
()
>>
[
&
](
const
util
::
duration
&
d
,
const
actor_ptr
&
)
const
actor_ptr
&
)
...
@@ -152,6 +152,7 @@ void scheduler_helper::time_emitter(scheduler_helper::ptr_type m_self)
...
@@ -152,6 +152,7 @@ void scheduler_helper::time_emitter(scheduler_helper::ptr_type m_self)
while
(
it
!=
messages
.
end
()
&&
(
it
->
first
)
<=
now
)
while
(
it
!=
messages
.
end
()
&&
(
it
->
first
)
<=
now
)
{
{
queue_node_ptr
ptr
{
std
::
move
(
it
->
second
)};
queue_node_ptr
ptr
{
std
::
move
(
it
->
second
)};
CPPA_REQUIRE
(
ptr
->
marked
==
false
);
auto
whom
=
const_cast
<
actor_ptr
*>
(
auto
whom
=
const_cast
<
actor_ptr
*>
(
reinterpret_cast
<
actor_ptr
const
*>
(
reinterpret_cast
<
actor_ptr
const
*>
(
ptr
->
msg
.
at
(
1
)));
ptr
->
msg
.
at
(
1
)));
...
@@ -171,7 +172,7 @@ void scheduler_helper::time_emitter(scheduler_helper::ptr_type m_self)
...
@@ -171,7 +172,7 @@ void scheduler_helper::time_emitter(scheduler_helper::ptr_type m_self)
}
}
}
}
}
}
handle_msg
(
msg_ptr
->
msg
);
mfun
(
msg_ptr
->
msg
);
}
}
}
}
...
...
src/yielding_actor.cpp
View file @
ce955a9c
...
@@ -42,7 +42,6 @@ namespace cppa { namespace detail {
...
@@ -42,7 +42,6 @@ namespace cppa { namespace detail {
yielding_actor
::
yielding_actor
(
std
::
function
<
void
()
>
fun
)
yielding_actor
::
yielding_actor
(
std
::
function
<
void
()
>
fun
)
:
m_fiber
(
&
yielding_actor
::
run
,
this
)
:
m_fiber
(
&
yielding_actor
::
run
,
this
)
,
m_behavior
(
fun
)
,
m_behavior
(
fun
)
,
m_invoke
(
this
,
this
)
{
{
}
}
...
@@ -89,19 +88,19 @@ void yielding_actor::yield_until_not_empty()
...
@@ -89,19 +88,19 @@ void yielding_actor::yield_until_not_empty()
void
yielding_actor
::
dequeue
(
partial_function
&
fun
)
void
yielding_actor
::
dequeue
(
partial_function
&
fun
)
{
{
if
(
m_invoke
.
invoke_from_cache
(
fun
)
==
false
)
if
(
invoke_from_cache
(
fun
)
==
false
)
{
{
queue_node_ptr
e
;
recursive_queue_node
*
e
=
nullptr
;
do
do
{
{
e
.
reset
(
m_mailbox
.
try_pop
()
);
e
=
m_mailbox
.
try_pop
(
);
while
(
!
e
)
while
(
!
e
)
{
{
yield_until_not_empty
();
yield_until_not_empty
();
e
.
reset
(
m_mailbox
.
try_pop
()
);
e
=
m_mailbox
.
try_pop
(
);
}
}
}
}
while
(
!
m_invoke
.
invoke
(
e
,
fun
)
);
while
(
invoke
(
e
,
fun
)
==
false
);
}
}
}
}
...
@@ -113,22 +112,20 @@ void yielding_actor::dequeue(behavior& bhvr)
...
@@ -113,22 +112,20 @@ void yielding_actor::dequeue(behavior& bhvr)
// suppress virtual function call
// suppress virtual function call
yielding_actor
::
dequeue
(
fun
);
yielding_actor
::
dequeue
(
fun
);
}
}
else
if
(
m_invoke
.
invoke_from_cache
(
fun
)
==
false
)
else
if
(
invoke_from_cache
(
bhvr
)
==
false
)
{
{
request_timeout
(
bhvr
.
timeout
());
request_timeout
(
bhvr
.
timeout
());
bool
timeout_occured
=
false
;
recursive_queue_node
*
e
=
nullptr
;
queue_node_ptr
e
;
do
do
{
{
e
.
reset
(
m_mailbox
.
try_pop
()
);
e
=
m_mailbox
.
try_pop
(
);
while
(
!
e
)
while
(
!
e
)
{
{
yield_until_not_empty
();
yield_until_not_empty
();
e
.
reset
(
m_mailbox
.
try_pop
()
);
e
=
m_mailbox
.
try_pop
(
);
}
}
}
}
while
(
!
m_invoke
.
invoke
(
e
,
fun
,
&
bhvr
,
&
timeout_occured
)
while
(
invoke
(
e
,
bhvr
)
==
false
);
&&
!
timeout_occured
);
}
}
}
}
...
...
unit_testing/main.cpp
View file @
ce955a9c
...
@@ -198,10 +198,10 @@ int main(int argc, char** argv)
...
@@ -198,10 +198,10 @@ int main(int argc, char** argv)
RUN_TEST
(
test__fixed_vector
);
RUN_TEST
(
test__fixed_vector
);
RUN_TEST
(
test__tuple
);
RUN_TEST
(
test__tuple
);
RUN_TEST
(
test__serialization
);
RUN_TEST
(
test__serialization
);
RUN_TEST
(
test__local_group
);
RUN_TEST
(
test__atom
);
RUN_TEST
(
test__atom
);
RUN_TEST
(
test__yield_interface
);
RUN_TEST
(
test__yield_interface
);
RUN_TEST
(
test__spawn
);
RUN_TEST
(
test__spawn
);
RUN_TEST
(
test__local_group
);
RUN_TEST_A3
(
test__remote_actor
,
argv
[
0
],
false
,
args
);
RUN_TEST_A3
(
test__remote_actor
,
argv
[
0
],
false
,
args
);
cout
<<
endl
cout
<<
endl
<<
"error(s) in all tests: "
<<
errors
<<
"error(s) in all tests: "
<<
errors
...
...
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