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
0c774e3e
Commit
0c774e3e
authored
Oct 14, 2013
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
added priorities to delayed / timed messages
parent
31bcfc16
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
101 additions
and
167 deletions
+101
-167
cppa/local_actor.hpp
cppa/local_actor.hpp
+1
-1
cppa/scheduler.hpp
cppa/scheduler.hpp
+10
-19
cppa/send.hpp
cppa/send.hpp
+51
-92
cppa/util/duration.hpp
cppa/util/duration.hpp
+1
-0
manual/StronglyTypedActors.tex
manual/StronglyTypedActors.tex
+1
-1
src/local_actor.cpp
src/local_actor.cpp
+3
-3
src/scheduler.cpp
src/scheduler.cpp
+13
-34
src/send.cpp
src/send.cpp
+20
-17
unit_testing/test_typed_spawn.cpp
unit_testing/test_typed_spawn.cpp
+1
-0
No files found.
cppa/local_actor.hpp
View file @
0c774e3e
...
@@ -314,7 +314,7 @@ class local_actor : public extend<actor>::with<memory_cached> {
...
@@ -314,7 +314,7 @@ class local_actor : public extend<actor>::with<memory_cached> {
void
reply_message
(
any_tuple
&&
what
);
void
reply_message
(
any_tuple
&&
what
);
void
forward_message
(
const
actor_ptr
&
new_receiver
);
void
forward_message
(
const
actor_ptr
&
new_receiver
,
message_priority
prio
);
inline
const
actor_ptr
&
chained_actor
();
inline
const
actor_ptr
&
chained_actor
();
...
...
cppa/scheduler.hpp
View file @
0c774e3e
...
@@ -108,35 +108,26 @@ class scheduler {
...
@@ -108,35 +108,26 @@ class scheduler {
virtual
attachable
*
register_hidden_context
();
virtual
attachable
*
register_hidden_context
();
template
<
typename
Duration
,
typename
...
Data
>
template
<
typename
Duration
,
typename
...
Data
>
void
delayed_send
(
const
channel_ptr
&
to
,
void
delayed_send
(
message_header
hdr
,
const
Duration
&
rel_time
,
const
Duration
&
rel_time
,
any_tuple
data
)
{
any_tuple
data
)
{
auto
tup
=
make_any_tuple
(
atom
(
"SEND"
),
auto
tup
=
make_any_tuple
(
atom
(
"SEND"
),
util
::
duration
{
rel_time
},
util
::
duration
{
rel_time
},
to
,
std
::
move
(
hdr
)
,
std
::
move
(
data
));
std
::
move
(
data
));
auto
dsh
=
delayed_send_helper
();
delayed_send_helper
()
->
enqueue
(
nullptr
,
std
::
move
(
tup
));
dsh
->
enqueue
({
self
,
dsh
},
std
::
move
(
tup
));
}
}
template
<
typename
Duration
,
typename
...
Data
>
template
<
typename
Duration
,
typename
...
Data
>
void
delayed_reply
(
const
actor_ptr
&
to
,
void
delayed_reply
(
message_header
hdr
,
const
Duration
&
rel_time
,
const
Duration
&
rel_time
,
message_id
id
,
any_tuple
data
)
{
any_tuple
data
)
{
CPPA_REQUIRE
(
!
id
.
valid
()
||
id
.
is_response
());
CPPA_REQUIRE
(
hdr
.
id
.
valid
()
&&
hdr
.
id
.
is_response
());
if
(
id
.
valid
())
{
auto
tup
=
make_any_tuple
(
atom
(
"SEND"
),
auto
tup
=
make_any_tuple
(
atom
(
"REPLY"
),
util
::
duration
{
rel_time
},
util
::
duration
{
rel_time
},
std
::
move
(
hdr
),
to
,
std
::
move
(
data
));
id
,
delayed_send_helper
()
->
enqueue
(
nullptr
,
std
::
move
(
tup
));
std
::
move
(
data
));
auto
dsh
=
delayed_send_helper
();
dsh
->
enqueue
({
self
,
dsh
},
std
::
move
(
tup
));
}
else
{
this
->
delayed_send
(
to
,
rel_time
,
std
::
move
(
data
));
}
}
}
/**
/**
...
...
cppa/send.hpp
View file @
0c774e3e
...
@@ -51,27 +51,30 @@ namespace cppa {
...
@@ -51,27 +51,30 @@ namespace cppa {
/**
/**
* @brief Stores sender, receiver, and message priority.
* @brief Stores sender, receiver, and message priority.
*/
*/
template
<
typename
T
=
channel_ptr
>
struct
destination_header
{
struct
destination_header
{
channel_ptr
receiver
;
T
receiver
;
message_priority
priority
;
message_priority
priority
;
inline
destination_header
(
const
self_type
&
s
)
template
<
typename
U
>
:
receiver
(
s
),
priority
(
message_priority
::
normal
)
{
}
destination_header
(
U
&&
dest
,
message_priority
mp
=
message_priority
::
normal
)
template
<
typename
T
>
:
receiver
(
std
::
forward
<
U
>
(
dest
)),
priority
(
mp
)
{
}
inline
destination_header
(
T
dest
)
destination_header
(
destination_header
&&
)
=
default
;
:
receiver
(
std
::
move
(
dest
)),
priority
(
message_priority
::
normal
)
{
}
destination_header
(
const
destination_header
&
)
=
default
;
inline
destination_header
(
channel_ptr
dest
,
message_priority
prio
)
destination_header
&
operator
=
(
destination_header
&&
)
=
default
;
:
receiver
(
std
::
move
(
dest
)),
priority
(
prio
)
{
}
destination_header
&
operator
=
(
const
destination_header
&
)
=
default
;
inline
destination_header
(
destination_header
&&
hdr
)
:
receiver
(
std
::
move
(
hdr
.
receiver
)),
priority
(
hdr
.
priority
)
{
}
};
};
using
channel_destination
=
destination_header
<
channel_ptr
>
;
using
actor_destination
=
destination_header
<
actor_ptr
>
;
/**
/**
* @brief Sends @p what to the receiver specified in @p hdr.
* @brief Sends @p what to the receiver specified in @p hdr.
*/
*/
inline
void
send_tuple
(
destination_header
hdr
,
any_tuple
what
)
{
inline
void
send_tuple
(
channel_destination
dest
,
any_tuple
what
)
{
if
(
hdr
.
receiver
==
nullptr
)
return
;
if
(
dest
.
receiver
==
nullptr
)
return
;
auto
s
=
self
.
get
();
auto
s
=
self
.
get
();
message_header
fhdr
{
s
,
std
::
move
(
hdr
.
receiver
),
hdr
.
priority
};
message_header
fhdr
{
s
,
std
::
move
(
dest
.
receiver
),
dest
.
priority
};
if
(
fhdr
.
receiver
!=
s
&&
s
->
chaining_enabled
())
{
if
(
fhdr
.
receiver
!=
s
&&
s
->
chaining_enabled
())
{
if
(
fhdr
.
receiver
->
chained_enqueue
(
fhdr
,
std
::
move
(
what
)))
{
if
(
fhdr
.
receiver
->
chained_enqueue
(
fhdr
,
std
::
move
(
what
)))
{
// only actors implement chained_enqueue to return true
// only actors implement chained_enqueue to return true
...
@@ -85,7 +88,7 @@ inline void send_tuple(destination_header hdr, any_tuple what) {
...
@@ -85,7 +88,7 @@ inline void send_tuple(destination_header hdr, any_tuple what) {
* @brief Sends @p what to the receiver specified in @p hdr.
* @brief Sends @p what to the receiver specified in @p hdr.
*/
*/
template
<
typename
...
Signatures
,
typename
...
Ts
>
template
<
typename
...
Signatures
,
typename
...
Ts
>
void
send
(
const
typed_actor_ptr
<
Signatures
...
>&
whom
,
Ts
&&
...
what
)
{
void
send
(
const
typed_actor_ptr
<
Signatures
...
>&
dest
,
Ts
&&
...
what
)
{
static
constexpr
int
input_pos
=
util
::
tl_find_if
<
static
constexpr
int
input_pos
=
util
::
tl_find_if
<
util
::
type_list
<
Signatures
...
>
,
util
::
type_list
<
Signatures
...
>
,
detail
::
input_is
<
util
::
type_list
<
detail
::
input_is
<
util
::
type_list
<
...
@@ -97,7 +100,7 @@ void send(const typed_actor_ptr<Signatures...>& whom, Ts&&... what) {
...
@@ -97,7 +100,7 @@ void send(const typed_actor_ptr<Signatures...>& whom, Ts&&... what) {
>>::
template
eval
>>::
template
eval
>
::
value
;
>
::
value
;
static_assert
(
input_pos
>=
0
,
"typed actor does not support given input"
);
static_assert
(
input_pos
>=
0
,
"typed actor does not support given input"
);
send
(
whom
.
type_erased
(),
std
::
forward
<
Ts
>
(
what
)...);
send
(
dest
.
/*receiver.*/
type_erased
(),
std
::
forward
<
Ts
>
(
what
)...);
}
}
/**
/**
...
@@ -105,17 +108,17 @@ void send(const typed_actor_ptr<Signatures...>& whom, Ts&&... what) {
...
@@ -105,17 +108,17 @@ void send(const typed_actor_ptr<Signatures...>& whom, Ts&&... what) {
* @pre <tt>sizeof...(Ts) > 0</tt>
* @pre <tt>sizeof...(Ts) > 0</tt>
*/
*/
template
<
typename
...
Ts
>
template
<
typename
...
Ts
>
inline
void
send
(
destination_header
hdr
,
Ts
&&
...
what
)
{
inline
void
send
(
channel_destination
dest
,
Ts
&&
...
what
)
{
static_assert
(
sizeof
...(
Ts
)
>
0
,
"no message to send"
);
static_assert
(
sizeof
...(
Ts
)
>
0
,
"no message to send"
);
send_tuple
(
std
::
move
(
hdr
),
make_any_tuple
(
std
::
forward
<
Ts
>
(
what
)...));
send_tuple
(
std
::
move
(
dest
),
make_any_tuple
(
std
::
forward
<
Ts
>
(
what
)...));
}
}
/**
/**
* @brief Sends @p what to @p whom, but sets the sender information to @p from.
* @brief Sends @p what to @p whom, but sets the sender information to @p from.
*/
*/
inline
void
send_tuple_as
(
actor_ptr
from
,
channel_
ptr
whom
,
any_tuple
what
)
{
inline
void
send_tuple_as
(
actor_ptr
from
,
channel_
destination
dest
,
any_tuple
what
)
{
message_header
hdr
{
std
::
move
(
from
),
std
::
move
(
whom
)
};
message_header
mhdr
{
std
::
move
(
from
),
std
::
move
(
dest
.
receiver
),
dest
.
priority
};
hdr
.
deliver
(
std
::
move
(
what
));
m
hdr
.
deliver
(
std
::
move
(
what
));
}
}
/**
/**
...
@@ -127,8 +130,8 @@ inline void send_tuple_as(actor_ptr from, channel_ptr whom, any_tuple what) {
...
@@ -127,8 +130,8 @@ inline void send_tuple_as(actor_ptr from, channel_ptr whom, any_tuple what) {
* @pre <tt>sizeof...(Ts) > 0</tt>
* @pre <tt>sizeof...(Ts) > 0</tt>
*/
*/
template
<
typename
...
Ts
>
template
<
typename
...
Ts
>
inline
void
send_as
(
actor_ptr
from
,
channel_
ptr
whom
,
Ts
&&
...
what
)
{
inline
void
send_as
(
actor_ptr
from
,
channel_
destination
dest
,
Ts
&&
...
what
)
{
send_tuple_as
(
std
::
move
(
from
),
std
::
move
(
whom
),
send_tuple_as
(
std
::
move
(
from
),
std
::
move
(
dest
),
make_any_tuple
(
std
::
forward
<
Ts
>
(
what
)...));
make_any_tuple
(
std
::
forward
<
Ts
>
(
what
)...));
}
}
...
@@ -141,7 +144,7 @@ inline void send_as(actor_ptr from, channel_ptr whom, Ts&&... what) {
...
@@ -141,7 +144,7 @@ inline void send_as(actor_ptr from, channel_ptr whom, Ts&&... what) {
* message cannot be received by another actor.
* message cannot be received by another actor.
* @throws std::invalid_argument if <tt>whom == nullptr</tt>
* @throws std::invalid_argument if <tt>whom == nullptr</tt>
*/
*/
message_future
sync_send_tuple
(
actor_
ptr
whom
,
any_tuple
what
);
message_future
sync_send_tuple
(
actor_
destination
dest
,
any_tuple
what
);
/**
/**
* @brief Sends <tt>{what...}</tt> as a synchronous message to @p whom.
* @brief Sends <tt>{what...}</tt> as a synchronous message to @p whom.
...
@@ -154,9 +157,9 @@ message_future sync_send_tuple(actor_ptr whom, any_tuple what);
...
@@ -154,9 +157,9 @@ message_future sync_send_tuple(actor_ptr whom, any_tuple what);
* @throws std::invalid_argument if <tt>whom == nullptr</tt>
* @throws std::invalid_argument if <tt>whom == nullptr</tt>
*/
*/
template
<
typename
...
Ts
>
template
<
typename
...
Ts
>
inline
message_future
sync_send
(
actor_
ptr
whom
,
Ts
&&
...
what
)
{
inline
message_future
sync_send
(
actor_
destination
dest
,
Ts
&&
...
what
)
{
static_assert
(
sizeof
...(
Ts
)
>
0
,
"no message to send"
);
static_assert
(
sizeof
...(
Ts
)
>
0
,
"no message to send"
);
return
sync_send_tuple
(
std
::
move
(
whom
),
return
sync_send_tuple
(
std
::
move
(
dest
),
make_any_tuple
(
std
::
forward
<
Ts
>
(
what
)...));
make_any_tuple
(
std
::
forward
<
Ts
>
(
what
)...));
}
}
...
@@ -192,26 +195,12 @@ sync_send(const typed_actor_ptr<Signatures...>& whom, Ts&&... what) {
...
@@ -192,26 +195,12 @@ sync_send(const typed_actor_ptr<Signatures...>& whom, Ts&&... what) {
* @param whom Receiver of the message.
* @param whom Receiver of the message.
* @param rtime Relative time duration to delay the message in
* @param rtime Relative time duration to delay the message in
* microseconds, milliseconds, seconds or minutes.
* microseconds, milliseconds, seconds or minutes.
* @param
what
Message content as a tuple.
* @param
data
Message content as a tuple.
*/
*/
void
delayed_send_tuple
(
c
onst
channel_ptr
&
to
,
void
delayed_send_tuple
(
c
hannel_destination
dest
,
const
util
::
duration
&
r
el_
time
,
const
util
::
duration
&
rtime
,
any_tuple
data
);
any_tuple
data
);
/**
* @brief Sends a message to @p whom that is delayed by @p rel_time.
* @param whom Receiver of the message.
* @param rtime Relative time duration to delay the message in
* microseconds, milliseconds, seconds or minutes.
* @param what Message content as a tuple.
*/
template
<
class
Rep
,
class
Period
,
typename
...
Ts
>
inline
void
delayed_send_tuple
(
const
channel_ptr
&
whom
,
const
std
::
chrono
::
duration
<
Rep
,
Period
>&
rtime
,
any_tuple
what
)
{
delayed_send_tuple
(
whom
,
util
::
duration
{
rtime
},
std
::
move
(
what
));
}
/**
/**
* @brief Sends a reply message that is delayed by @p rel_time.
* @brief Sends a reply message that is delayed by @p rel_time.
* @param rtime Relative time duration to delay the message in
* @param rtime Relative time duration to delay the message in
...
@@ -223,18 +212,6 @@ void delayed_reply_tuple(const util::duration& rel_time,
...
@@ -223,18 +212,6 @@ void delayed_reply_tuple(const util::duration& rel_time,
message_id
mid
,
message_id
mid
,
any_tuple
data
);
any_tuple
data
);
/**
* @brief Sends a reply message that is delayed by @p rel_time.
* @param rtime Relative time duration to delay the message in
* microseconds, milliseconds, seconds or minutes.
* @param what Message content as a tuple.
* @see delayed_send()
*/
void
delayed_reply_tuple
(
const
util
::
duration
&
rel_time
,
actor_ptr
whom
,
message_id
mid
,
any_tuple
data
);
/**
/**
* @brief Sends a reply message that is delayed by @p rel_time.
* @brief Sends a reply message that is delayed by @p rel_time.
* @param rtime Relative time duration to delay the message in
* @param rtime Relative time duration to delay the message in
...
@@ -244,39 +221,22 @@ void delayed_reply_tuple(const util::duration& rel_time,
...
@@ -244,39 +221,22 @@ void delayed_reply_tuple(const util::duration& rel_time,
*/
*/
void
delayed_reply_tuple
(
const
util
::
duration
&
rel_time
,
any_tuple
data
);
void
delayed_reply_tuple
(
const
util
::
duration
&
rel_time
,
any_tuple
data
);
/**
* @brief Sends a reply message that is delayed by @p rel_time.
* @param rtime Relative time duration to delay the message in
* microseconds, milliseconds, seconds or minutes.
* @param what Message content as a tuple.
* @see delayed_send()
*/
template
<
class
Rep
,
class
Period
,
typename
...
Ts
>
inline
void
delayed_reply_tuple
(
const
std
::
chrono
::
duration
<
Rep
,
Period
>&
rtime
,
any_tuple
what
)
{
delayed_reply_tuple
(
util
::
duration
{
rtime
},
std
::
move
(
what
));
}
/**
/**
* @brief Sends @p what as a synchronous message to @p whom with a timeout.
* @brief Sends @p what as a synchronous message to @p whom with a timeout.
*
*
* The calling actor receives a 'TIMEOUT' message as response after
* The calling actor receives a 'TIMEOUT' message as response after
* given timeout exceeded and no response messages was received.
* given timeout exceeded and no response messages was received.
* @param
whom Receiver of the message
.
* @param
dest Receiver and optional priority flag
.
* @param what Message content as tuple.
* @param what Message content as tuple.
* @returns A handle identifying a future to the response of @p whom.
* @returns A handle identifying a future to the response of @p whom.
* @warning The returned handle is actor specific and the response to the sent
* @warning The returned handle is actor specific and the response to the sent
* message cannot be received by another actor.
* message cannot be received by another actor.
* @throws std::invalid_argument if <tt>whom == nullptr</tt>
* @throws std::invalid_argument if <tt>whom == nullptr</tt>
*/
*/
template
<
class
Rep
,
class
Period
,
typename
...
Ts
>
message_future
timed_sync_send_tuple
(
actor_destination
dest
,
message_future
timed_sync_send_tuple
(
actor_ptr
whom
,
const
util
::
duration
&
rtime
,
const
std
::
chrono
::
duration
<
Rep
,
Period
>&
rel_time
,
any_tuple
what
);
any_tuple
what
)
{
auto
mf
=
sync_send_tuple
(
std
::
move
(
whom
),
std
::
move
(
what
));
auto
tmp
=
make_any_tuple
(
atom
(
"TIMEOUT"
));
delayed_reply_tuple
(
util
::
duration
{
rel_time
},
self
,
mf
.
id
(),
std
::
move
(
tmp
));
return
mf
;
}
/**
/**
* @brief Sends <tt>{what...}</tt> as a synchronous message to @p whom
* @brief Sends <tt>{what...}</tt> as a synchronous message to @p whom
...
@@ -292,13 +252,13 @@ message_future timed_sync_send_tuple(actor_ptr whom,
...
@@ -292,13 +252,13 @@ message_future timed_sync_send_tuple(actor_ptr whom,
* @pre <tt>sizeof...(Ts) > 0</tt>
* @pre <tt>sizeof...(Ts) > 0</tt>
* @throws std::invalid_argument if <tt>whom == nullptr</tt>
* @throws std::invalid_argument if <tt>whom == nullptr</tt>
*/
*/
template
<
class
Rep
,
class
Period
,
typename
...
Ts
>
template
<
typename
...
Ts
>
message_future
timed_sync_send
(
actor_
ptr
whom
,
message_future
timed_sync_send
(
actor_
destination
whom
,
const
std
::
chrono
::
duration
<
Rep
,
Period
>&
rel_
time
,
const
util
::
duration
&
r
time
,
Ts
&&
...
what
)
{
Ts
&&
...
what
)
{
static_assert
(
sizeof
...(
Ts
)
>
0
,
"no message to send"
);
static_assert
(
sizeof
...(
Ts
)
>
0
,
"no message to send"
);
return
timed_sync_send_tuple
(
std
::
move
(
whom
),
return
timed_sync_send_tuple
(
std
::
move
(
whom
),
r
el_
time
,
rtime
,
make_any_tuple
(
std
::
forward
<
Ts
>
(
what
)...));
make_any_tuple
(
std
::
forward
<
Ts
>
(
what
)...));
}
}
...
@@ -341,8 +301,8 @@ inline void reply_tuple_to(const response_handle& handle, any_tuple what) {
...
@@ -341,8 +301,8 @@ inline void reply_tuple_to(const response_handle& handle, any_tuple what) {
/**
/**
* @brief Forwards the last received message to @p whom.
* @brief Forwards the last received message to @p whom.
*/
*/
inline
void
forward_to
(
const
actor_ptr
&
whom
)
{
inline
void
forward_to
(
actor_destination
dest
)
{
self
->
forward_message
(
whom
);
self
->
forward_message
(
dest
.
receiver
,
dest
.
priority
);
}
}
/**
/**
...
@@ -352,13 +312,13 @@ inline void forward_to(const actor_ptr& whom) {
...
@@ -352,13 +312,13 @@ inline void forward_to(const actor_ptr& whom) {
* microseconds, milliseconds, seconds or minutes.
* microseconds, milliseconds, seconds or minutes.
* @param what Message elements.
* @param what Message elements.
*/
*/
template
<
class
Rep
,
class
Period
,
typename
...
Ts
>
template
<
typename
...
Ts
>
inline
void
delayed_send
(
c
onst
channel_ptr
&
whom
,
inline
void
delayed_send
(
c
hannel_destination
dest
,
const
std
::
chrono
::
duration
<
Rep
,
Period
>
&
rtime
,
const
util
::
duration
&
rtime
,
Ts
&&
...
what
)
{
Ts
&&
...
what
)
{
static_assert
(
sizeof
...(
Ts
)
>
0
,
"no message to send"
);
static_assert
(
sizeof
...(
Ts
)
>
0
,
"no message to send"
);
if
(
whom
)
{
if
(
dest
.
receiver
)
{
delayed_send_tuple
(
whom
,
delayed_send_tuple
(
std
::
move
(
dest
)
,
rtime
,
rtime
,
make_any_tuple
(
std
::
forward
<
Ts
>
(
what
)...));
make_any_tuple
(
std
::
forward
<
Ts
>
(
what
)...));
}
}
...
@@ -371,9 +331,8 @@ inline void delayed_send(const channel_ptr& whom,
...
@@ -371,9 +331,8 @@ inline void delayed_send(const channel_ptr& whom,
* @param what Message elements.
* @param what Message elements.
* @see delayed_send()
* @see delayed_send()
*/
*/
template
<
class
Rep
,
class
Period
,
typename
...
Ts
>
template
<
typename
...
Ts
>
inline
void
delayed_reply
(
const
std
::
chrono
::
duration
<
Rep
,
Period
>&
rtime
,
inline
void
delayed_reply
(
const
util
::
duration
&
rtime
,
Ts
&&
...
what
)
{
Ts
&&
...
what
)
{
delayed_reply_tuple
(
rtime
,
make_any_tuple
(
std
::
forward
<
Ts
>
(
what
)...));
delayed_reply_tuple
(
rtime
,
make_any_tuple
(
std
::
forward
<
Ts
>
(
what
)...));
}
}
...
@@ -384,9 +343,9 @@ inline void delayed_reply(const std::chrono::duration<Rep, Period>& rtime,
...
@@ -384,9 +343,9 @@ inline void delayed_reply(const std::chrono::duration<Rep, Period>& rtime,
* <tt>send(whom, atom("EXIT"), reason)</tt>.
* <tt>send(whom, atom("EXIT"), reason)</tt>.
* @pre <tt>reason != exit_reason::normal</tt>
* @pre <tt>reason != exit_reason::normal</tt>
*/
*/
inline
void
send_exit
(
actor_ptr
whom
,
std
::
uint32_t
rsn
)
{
inline
void
send_exit
(
channel_destination
dest
,
std
::
uint32_t
rsn
)
{
CPPA_REQUIRE
(
rsn
!=
exit_reason
::
normal
);
CPPA_REQUIRE
(
rsn
!=
exit_reason
::
normal
);
send
(
std
::
move
(
whom
),
atom
(
"EXIT"
),
rsn
);
send
(
std
::
move
(
dest
),
atom
(
"EXIT"
),
rsn
);
}
}
/**
/**
...
...
cppa/util/duration.hpp
View file @
0c774e3e
...
@@ -82,6 +82,7 @@ class duration {
...
@@ -82,6 +82,7 @@ class duration {
"only seconds, milliseconds or microseconds allowed"
);
"only seconds, milliseconds or microseconds allowed"
);
}
}
// convert minutes to seconds
template
<
class
Rep
>
template
<
class
Rep
>
constexpr
duration
(
std
::
chrono
::
duration
<
Rep
,
std
::
ratio
<
60
,
1
>
>
d
)
constexpr
duration
(
std
::
chrono
::
duration
<
Rep
,
std
::
ratio
<
60
,
1
>
>
d
)
:
unit
(
time_unit
::
seconds
),
count
(
d
.
count
()
*
60
)
{
}
:
unit
(
time_unit
::
seconds
),
count
(
d
.
count
()
*
60
)
{
}
...
...
manual/StronglyTypedActors.tex
View file @
0c774e3e
...
@@ -8,7 +8,7 @@ Typed actors use \lstinline^typed_actor_ptr<...>^ instead of \lstinline^actor_pt
...
@@ -8,7 +8,7 @@ Typed actors use \lstinline^typed_actor_ptr<...>^ instead of \lstinline^actor_pt
For example, an actor responding to two integers with a dobule would use the type
\lstinline
^
typed
_
actor
_
ptr<replies
_
to<int, int>::with<double>>
^
.
For example, an actor responding to two integers with a dobule would use the type
\lstinline
^
typed
_
actor
_
ptr<replies
_
to<int, int>::with<double>>
^
.
All functions for message passing, linking and monitoring are overloaded to accept both types of actors.
All functions for message passing, linking and monitoring are overloaded to accept both types of actors.
As of version 0.8, strongly typed actors cannot be published
(this is a
planned feature for future releases).
As of version 0.8, strongly typed actors cannot be published
and do not support message priorities (those are
planned feature for future releases).
\subsection
{
Spawning Typed Actors
}
\subsection
{
Spawning Typed Actors
}
\label
{
sec:strong:spawn
}
\label
{
sec:strong:spawn
}
...
...
src/local_actor.cpp
View file @
0c774e3e
...
@@ -158,10 +158,10 @@ void local_actor::reply_message(any_tuple&& what) {
...
@@ -158,10 +158,10 @@ void local_actor::reply_message(any_tuple&& what) {
}
}
}
}
void
local_actor
::
forward_message
(
const
actor_ptr
&
new_receiver
)
{
void
local_actor
::
forward_message
(
const
actor_ptr
&
dest
,
message_priority
p
)
{
if
(
new_receiver
==
nullptr
)
return
;
if
(
dest
==
nullptr
)
return
;
auto
&
id
=
m_current_node
->
mid
;
auto
&
id
=
m_current_node
->
mid
;
new_receiver
->
enqueue
({
last_sender
(),
new_receiver
,
id
},
m_current_node
->
msg
);
dest
->
enqueue
({
last_sender
(),
dest
,
id
,
p
},
m_current_node
->
msg
);
// treat this message as asynchronous message from now on
// treat this message as asynchronous message from now on
id
=
message_id
{};
id
=
message_id
{};
}
}
...
...
src/scheduler.cpp
View file @
0c774e3e
...
@@ -66,17 +66,9 @@ class delayed_msg {
...
@@ -66,17 +66,9 @@ class delayed_msg {
public:
public:
delayed_msg
(
const
channel_ptr
&
arg0
,
delayed_msg
(
message_header
&&
arg1
,
const
actor_ptr
&
arg1
,
any_tuple
&&
arg2
)
message_id
,
:
hdr
(
move
(
arg1
)),
msg
(
move
(
arg2
))
{
}
any_tuple
&&
arg3
)
:
ptr_a
(
arg0
),
from
(
arg1
),
msg
(
move
(
arg3
))
{
}
delayed_msg
(
const
actor_ptr
&
arg0
,
const
actor_ptr
&
arg1
,
message_id
arg2
,
any_tuple
&&
arg3
)
:
ptr_b
(
arg0
),
from
(
arg1
),
id
(
arg2
),
msg
(
move
(
arg3
))
{
}
delayed_msg
(
delayed_msg
&&
)
=
default
;
delayed_msg
(
delayed_msg
&&
)
=
default
;
delayed_msg
(
const
delayed_msg
&
)
=
default
;
delayed_msg
(
const
delayed_msg
&
)
=
default
;
...
@@ -84,18 +76,13 @@ class delayed_msg {
...
@@ -84,18 +76,13 @@ class delayed_msg {
delayed_msg
&
operator
=
(
const
delayed_msg
&
)
=
default
;
delayed_msg
&
operator
=
(
const
delayed_msg
&
)
=
default
;
inline
void
eval
()
{
inline
void
eval
()
{
CPPA_REQUIRE
(
ptr_a
||
ptr_b
);
hdr
.
deliver
(
std
::
move
(
msg
));
if
(
ptr_a
)
ptr_a
->
enqueue
(
from
,
move
(
msg
));
else
ptr_b
->
enqueue
({
from
,
id
},
move
(
msg
));
}
}
private:
private:
channel_ptr
ptr_a
;
message_header
hdr
;
actor_ptr
ptr_b
;
any_tuple
msg
;
actor_ptr
from
;
message_id
id
;
any_tuple
msg
;
};
};
...
@@ -140,16 +127,14 @@ class scheduler_helper {
...
@@ -140,16 +127,14 @@ class scheduler_helper {
};
};
template
<
class
Map
,
class
T
>
template
<
class
Map
>
inline
void
insert_dmsg
(
Map
&
storage
,
inline
void
insert_dmsg
(
Map
&
storage
,
const
util
::
duration
&
d
,
const
util
::
duration
&
d
,
const
T
&
to
,
message_header
&&
hdr
,
const
actor_ptr
&
sender
,
any_tuple
&&
tup
)
{
any_tuple
&&
tup
,
message_id
id
=
message_id
{})
{
auto
tout
=
hrc
::
now
();
auto
tout
=
hrc
::
now
();
tout
+=
d
;
tout
+=
d
;
delayed_msg
dmsg
{
to
,
sender
,
id
,
move
(
tup
)};
delayed_msg
dmsg
{
move
(
hdr
)
,
move
(
tup
)};
storage
.
insert
(
std
::
make_pair
(
std
::
move
(
tout
),
std
::
move
(
dmsg
)));
storage
.
insert
(
std
::
make_pair
(
std
::
move
(
tout
),
std
::
move
(
dmsg
)));
}
}
...
@@ -163,15 +148,9 @@ void scheduler_helper::timer_loop(scheduler_helper::ptr_type m_self) {
...
@@ -163,15 +148,9 @@ void scheduler_helper::timer_loop(scheduler_helper::ptr_type m_self) {
// message handling rules
// message handling rules
auto
mfun
=
(
auto
mfun
=
(
on
(
atom
(
"SEND"
),
arg_match
)
>>
[
&
](
const
util
::
duration
&
d
,
on
(
atom
(
"SEND"
),
arg_match
)
>>
[
&
](
const
util
::
duration
&
d
,
const
channel_ptr
&
pt
r
,
message_header
&
hd
r
,
any_tuple
&
tup
)
{
any_tuple
&
tup
)
{
insert_dmsg
(
messages
,
d
,
ptr
,
msg_ptr
->
sender
,
move
(
tup
));
insert_dmsg
(
messages
,
d
,
move
(
hdr
),
move
(
tup
));
},
on
(
atom
(
"REPLY"
),
arg_match
)
>>
[
&
](
const
util
::
duration
&
d
,
const
actor_ptr
&
ptr
,
message_id
id
,
any_tuple
&
tup
)
{
insert_dmsg
(
messages
,
d
,
ptr
,
msg_ptr
->
sender
,
move
(
tup
),
id
);
},
},
on
(
atom
(
"DIE"
))
>>
[
&
]
{
on
(
atom
(
"DIE"
))
>>
[
&
]
{
done
=
true
;
done
=
true
;
...
...
src/send.cpp
View file @
0c774e3e
...
@@ -34,10 +34,10 @@
...
@@ -34,10 +34,10 @@
namespace
cppa
{
namespace
cppa
{
message_future
sync_send_tuple
(
actor_
ptr
whom
,
any_tuple
what
)
{
message_future
sync_send_tuple
(
actor_
destination
dest
,
any_tuple
what
)
{
if
(
!
whom
)
throw
std
::
invalid_argument
(
"whom == nullptr"
);
if
(
!
dest
.
receiver
)
throw
std
::
invalid_argument
(
"whom == nullptr"
);
auto
req
=
self
->
new_request_id
();
auto
req
=
self
->
new_request_id
();
message_header
hdr
{
self
,
std
::
move
(
whom
),
req
};
message_header
hdr
{
self
,
std
::
move
(
dest
.
receiver
),
req
,
dest
.
priority
};
if
(
self
->
chaining_enabled
())
{
if
(
self
->
chaining_enabled
())
{
if
(
hdr
.
receiver
->
chained_enqueue
(
hdr
,
std
::
move
(
what
)))
{
if
(
hdr
.
receiver
->
chained_enqueue
(
hdr
,
std
::
move
(
what
)))
{
self
->
chained_actor
(
hdr
.
receiver
.
downcast
<
actor
>
());
self
->
chained_actor
(
hdr
.
receiver
.
downcast
<
actor
>
());
...
@@ -47,27 +47,30 @@ message_future sync_send_tuple(actor_ptr whom, any_tuple what) {
...
@@ -47,27 +47,30 @@ message_future sync_send_tuple(actor_ptr whom, any_tuple what) {
return
req
.
response_id
();
return
req
.
response_id
();
}
}
void
delayed_send_tuple
(
c
onst
channel_ptr
&
to
,
void
delayed_send_tuple
(
c
hannel_destination
dest
,
const
util
::
duration
&
r
el_
time
,
const
util
::
duration
&
rtime
,
any_tuple
data
)
{
any_tuple
data
)
{
if
(
to
)
get_scheduler
()
->
delayed_send
(
to
,
rel_time
,
std
::
move
(
data
));
if
(
dest
.
receiver
)
{
message_header
hdr
{
self
,
std
::
move
(
dest
.
receiver
),
dest
.
priority
};
get_scheduler
()
->
delayed_send
(
std
::
move
(
hdr
),
rtime
,
std
::
move
(
data
));
}
}
}
void
delayed_reply_tuple
(
const
util
::
duration
&
rel_time
,
message_future
timed_sync_send_tuple
(
actor_destination
dest
,
actor_ptr
whom
,
const
util
::
duration
&
rtime
,
message_id
mid
,
any_tuple
what
)
{
any_tuple
data
)
{
auto
mf
=
sync_send_tuple
(
std
::
move
(
dest
),
std
::
move
(
what
));
if
(
whom
)
get_scheduler
()
->
delayed_reply
(
whom
,
message_header
hdr
{
self
,
self
,
mf
.
id
()};
rel_time
,
auto
tmp
=
make_any_tuple
(
atom
(
"TIMEOUT"
));
mid
,
get_scheduler
()
->
delayed_send
(
std
::
move
(
hdr
),
rtime
,
std
::
move
(
tmp
));
std
::
move
(
data
))
;
return
mf
;
}
}
void
delayed_reply_tuple
(
const
util
::
duration
&
rtime
,
void
delayed_reply_tuple
(
const
util
::
duration
&
rel_time
,
message_id
mid
,
message_id
mid
,
any_tuple
data
)
{
any_tuple
data
)
{
delayed_reply_tuple
(
rel_time
,
self
->
last_sender
(),
mid
,
std
::
move
(
data
));
message_header
hdr
{
self
,
self
->
last_sender
(),
mid
};
get_scheduler
()
->
delayed_send
(
std
::
move
(
hdr
),
rtime
,
std
::
move
(
data
));
}
}
void
delayed_reply_tuple
(
const
util
::
duration
&
rel_time
,
any_tuple
data
)
{
void
delayed_reply_tuple
(
const
util
::
duration
&
rel_time
,
any_tuple
data
)
{
...
...
unit_testing/test_typed_spawn.cpp
View file @
0c774e3e
...
@@ -66,6 +66,7 @@ class typed_testee : public typed_actor<replies_to<my_request>::with<bool>> {
...
@@ -66,6 +66,7 @@ class typed_testee : public typed_actor<replies_to<my_request>::with<bool>> {
int
main
()
{
int
main
()
{
CPPA_TEST
(
test_typed_spawn
);
CPPA_TEST
(
test_typed_spawn
);
announce
<
my_request
>
(
&
my_request
::
a
,
&
my_request
::
b
);
announce
<
my_request
>
(
&
my_request
::
a
,
&
my_request
::
b
);
auto
sptr
=
spawn_typed_server
();
auto
sptr
=
spawn_typed_server
();
sync_send
(
sptr
,
my_request
{
2
,
2
}).
await
(
sync_send
(
sptr
,
my_request
{
2
,
2
}).
await
(
...
...
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