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
d4365f40
Commit
d4365f40
authored
Oct 02, 2013
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
allow actors to respond by returning values
parent
e4b22d2e
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
52 additions
and
42 deletions
+52
-42
cppa/detail/behavior_impl.hpp
cppa/detail/behavior_impl.hpp
+3
-0
cppa/detail/receive_policy.hpp
cppa/detail/receive_policy.hpp
+17
-10
unit_testing/test_spawn.cpp
unit_testing/test_spawn.cpp
+28
-28
unit_testing/test_sync_send.cpp
unit_testing/test_sync_send.cpp
+4
-4
No files found.
cppa/detail/behavior_impl.hpp
View file @
d4365f40
...
@@ -55,6 +55,9 @@ struct optional_any_tuple_visitor {
...
@@ -55,6 +55,9 @@ struct optional_any_tuple_visitor {
inline
result_type
operator
()(
cow_tuple
<
Ts
...
>&
value
)
const
{
inline
result_type
operator
()(
cow_tuple
<
Ts
...
>&
value
)
const
{
return
any_tuple
{
std
::
move
(
value
)};
return
any_tuple
{
std
::
move
(
value
)};
}
}
inline
result_type
operator
()(
any_tuple
&
value
)
const
{
return
std
::
move
(
value
);
}
};
};
template
<
typename
...
Ts
>
template
<
typename
...
Ts
>
...
...
cppa/detail/receive_policy.hpp
View file @
d4365f40
...
@@ -406,18 +406,25 @@ class receive_policy {
...
@@ -406,18 +406,25 @@ class receive_policy {
case
ordinary_message
:
{
case
ordinary_message
:
{
if
(
!
awaited_response
.
valid
())
{
if
(
!
awaited_response
.
valid
())
{
auto
previous_node
=
hm_begin
(
client
,
node
,
policy
);
auto
previous_node
=
hm_begin
(
client
,
node
,
policy
);
if
(
fun
(
node
->
msg
))
{
auto
res
=
fun
(
node
->
msg
);
// make sure synchronous request
if
(
res
)
{
// always receive a response
auto
mid
=
node
->
mid
;
auto
id
=
node
->
mid
;
auto
sender
=
node
->
sender
;
auto
sender
=
node
->
sender
;
if
(
id
.
valid
()
&&
!
id
.
is_answered
()
&&
sender
)
{
message_header
hdr
{
client
,
sender
,
mid
.
response_id
()};
if
(
res
->
empty
())
{
// make sure synchronous requests
// always receive a response
if
(
mid
.
valid
()
&&
!
mid
.
is_answered
()
&&
sender
)
{
CPPA_LOGMF
(
CPPA_WARNING
,
client
,
CPPA_LOGMF
(
CPPA_WARNING
,
client
,
"actor did not reply to a "
"actor did not reply to a "
"synchronous request message"
);
"synchronous request message"
);
sender
->
enqueue
({
client
,
sender
,
id
.
response_id
()}
,
sender
->
enqueue
(
std
::
move
(
hdr
)
,
make_any_tuple
(
atom
(
"VOID"
)));
make_any_tuple
(
atom
(
"VOID"
)));
}
}
}
else
{
// respond by using the result of 'fun'
sender
->
enqueue
(
std
::
move
(
hdr
),
std
::
move
(
*
res
));
}
hm_cleanup
(
client
,
previous_node
,
policy
);
hm_cleanup
(
client
,
previous_node
,
policy
);
return
hm_msg_handled
;
return
hm_msg_handled
;
}
}
...
...
unit_testing/test_spawn.cpp
View file @
d4365f40
...
@@ -34,29 +34,29 @@ class event_testee : public sb_actor<event_testee> {
...
@@ -34,29 +34,29 @@ class event_testee : public sb_actor<event_testee> {
event_testee
()
{
event_testee
()
{
wait4string
=
(
wait4string
=
(
on
<
string
>
()
>>
[
=
]
()
{
on
<
string
>
()
>>
[
=
]
{
become
(
wait4int
);
become
(
wait4int
);
},
},
on
<
atom
(
"get_state"
)
>
()
>>
[
=
]
()
{
on
<
atom
(
"get_state"
)
>
()
>>
[
=
]
{
re
ply
(
"wait4string"
)
;
re
turn
"wait4string"
;
}
}
);
);
wait4float
=
(
wait4float
=
(
on
<
float
>
()
>>
[
=
]
()
{
on
<
float
>
()
>>
[
=
]
{
become
(
wait4string
);
become
(
wait4string
);
},
},
on
<
atom
(
"get_state"
)
>
()
>>
[
=
]
()
{
on
<
atom
(
"get_state"
)
>
()
>>
[
=
]
{
re
ply
(
"wait4float"
)
;
re
turn
"wait4float"
;
}
}
);
);
wait4int
=
(
wait4int
=
(
on
<
int
>
()
>>
[
=
]
()
{
on
<
int
>
()
>>
[
=
]
{
become
(
wait4float
);
become
(
wait4float
);
},
},
on
<
atom
(
"get_state"
)
>
()
>>
[
=
]
()
{
on
<
atom
(
"get_state"
)
>
()
>>
[
=
]
{
re
ply
(
"wait4int"
)
;
re
turn
"wait4int"
;
}
}
);
);
}
}
...
@@ -86,10 +86,10 @@ struct chopstick : public sb_actor<chopstick> {
...
@@ -86,10 +86,10 @@ struct chopstick : public sb_actor<chopstick> {
behavior
taken_by
(
actor_ptr
whom
)
{
behavior
taken_by
(
actor_ptr
whom
)
{
return
(
return
(
on
<
atom
(
"take"
)
>
()
>>
[
=
]
()
{
on
<
atom
(
"take"
)
>
()
>>
[
=
]
{
re
ply
(
atom
(
"busy"
)
);
re
turn
atom
(
"busy"
);
},
},
on
(
atom
(
"put"
),
whom
)
>>
[
=
]
()
{
on
(
atom
(
"put"
),
whom
)
>>
[
=
]
{
become
(
available
);
become
(
available
);
},
},
on
(
atom
(
"break"
))
>>
[
=
]()
{
on
(
atom
(
"break"
))
>>
[
=
]()
{
...
@@ -104,11 +104,11 @@ struct chopstick : public sb_actor<chopstick> {
...
@@ -104,11 +104,11 @@ struct chopstick : public sb_actor<chopstick> {
chopstick
()
{
chopstick
()
{
available
=
(
available
=
(
on
(
atom
(
"take"
),
arg_match
)
>>
[
=
](
actor_ptr
whom
)
{
on
(
atom
(
"take"
),
arg_match
)
>>
[
=
](
actor_ptr
whom
)
->
atom_value
{
become
(
taken_by
(
whom
));
become
(
taken_by
(
whom
));
re
ply
(
atom
(
"taken"
)
);
re
turn
atom
(
"taken"
);
},
},
on
(
atom
(
"break"
))
>>
[
=
]
()
{
on
(
atom
(
"break"
))
>>
[
=
]
{
quit
();
quit
();
}
}
);
);
...
@@ -125,7 +125,7 @@ class testee_actor {
...
@@ -125,7 +125,7 @@ class testee_actor {
string_received
=
true
;
string_received
=
true
;
},
},
on
<
atom
(
"get_state"
)
>
()
>>
[
&
]
{
on
<
atom
(
"get_state"
)
>
()
>>
[
&
]
{
re
ply
(
"wait4string"
)
;
re
turn
"wait4string"
;
}
}
)
)
.
until
(
gref
(
string_received
));
.
until
(
gref
(
string_received
));
...
@@ -138,7 +138,7 @@ class testee_actor {
...
@@ -138,7 +138,7 @@ class testee_actor {
float_received
=
true
;
float_received
=
true
;
},
},
on
<
atom
(
"get_state"
)
>
()
>>
[
&
]
{
on
<
atom
(
"get_state"
)
>
()
>>
[
&
]
{
re
ply
(
"wait4float"
)
;
re
turn
"wait4float"
;
}
}
)
)
.
until
(
gref
(
float_received
));
.
until
(
gref
(
float_received
));
...
@@ -153,7 +153,7 @@ class testee_actor {
...
@@ -153,7 +153,7 @@ class testee_actor {
wait4float
();
wait4float
();
},
},
on
<
atom
(
"get_state"
)
>
()
>>
[
&
]
{
on
<
atom
(
"get_state"
)
>
()
>>
[
&
]
{
re
ply
(
"wait4int"
)
;
re
turn
"wait4int"
;
}
}
);
);
}
}
...
@@ -253,8 +253,8 @@ class fixed_stack : public sb_actor<fixed_stack> {
...
@@ -253,8 +253,8 @@ class fixed_stack : public sb_actor<fixed_stack> {
data
.
push_back
(
what
);
data
.
push_back
(
what
);
become
(
filled
);
become
(
filled
);
},
},
on
(
atom
(
"pop"
))
>>
[
=
]
()
{
on
(
atom
(
"pop"
))
>>
[
=
]
{
re
ply
(
atom
(
"failure"
)
);
re
turn
atom
(
"failure"
);
}
}
);
);
...
@@ -276,7 +276,7 @@ struct simple_mirror : sb_actor<simple_mirror> {
...
@@ -276,7 +276,7 @@ struct simple_mirror : sb_actor<simple_mirror> {
behavior
init_state
=
(
behavior
init_state
=
(
others
()
>>
[]
{
others
()
>>
[]
{
re
ply_tuple
(
self
->
last_dequeued
()
);
re
turn
self
->
last_dequeued
(
);
}
}
);
);
...
@@ -556,8 +556,8 @@ int main() {
...
@@ -556,8 +556,8 @@ int main() {
auto
factory
=
factory
::
event_based
([
&
](
int
*
i
,
float
*
,
string
*
)
{
auto
factory
=
factory
::
event_based
([
&
](
int
*
i
,
float
*
,
string
*
)
{
become
(
become
(
on
(
atom
(
"get_int"
))
>>
[
i
]
()
{
on
(
atom
(
"get_int"
))
>>
[
i
]
{
re
ply
(
*
i
)
;
re
turn
*
i
;
},
},
on
(
atom
(
"set_int"
),
arg_match
)
>>
[
i
](
int
new_value
)
{
on
(
atom
(
"set_int"
),
arg_match
)
>>
[
i
](
int
new_value
)
{
*
i
=
new_value
;
*
i
=
new_value
;
...
@@ -618,7 +618,7 @@ int main() {
...
@@ -618,7 +618,7 @@ int main() {
auto
sync_testee1
=
spawn
<
blocking_api
>
([]
{
auto
sync_testee1
=
spawn
<
blocking_api
>
([]
{
receive
(
receive
(
on
(
atom
(
"get"
))
>>
[]
{
on
(
atom
(
"get"
))
>>
[]
{
re
ply
(
42
,
2
);
re
turn
make_cow_tuple
(
42
,
2
);
}
}
);
);
});
});
...
@@ -681,11 +681,11 @@ int main() {
...
@@ -681,11 +681,11 @@ int main() {
self
->
monitor
(
sync_testee
);
self
->
monitor
(
sync_testee
);
send
(
sync_testee
,
"hi"
);
send
(
sync_testee
,
"hi"
);
receive
(
receive
(
on
(
"whassup?"
)
>>
[
&
]
{
on
(
"whassup?"
)
>>
[
&
]
()
->
std
::
string
{
CPPA_CHECK
(
true
);
CPPA_CHECK
(
true
);
// this is NOT a reply, it's just an asynchronous message
// this is NOT a reply, it's just an asynchronous message
send
(
self
->
last_sender
(),
"a lot!"
);
send
(
self
->
last_sender
(),
"a lot!"
);
re
ply
(
"nothing"
)
;
re
turn
"nothing"
;
}
}
);
);
receive
(
receive
(
...
@@ -788,8 +788,8 @@ int main() {
...
@@ -788,8 +788,8 @@ int main() {
auto
f
=
factory
::
event_based
([](
string
*
name
)
{
auto
f
=
factory
::
event_based
([](
string
*
name
)
{
become
(
become
(
on
(
atom
(
"get_name"
))
>>
[
name
]
()
{
on
(
atom
(
"get_name"
))
>>
[
name
]
{
re
ply
(
atom
(
"name"
),
*
name
);
re
turn
make_cow_tuple
(
atom
(
"name"
),
*
name
);
}
}
);
);
});
});
...
...
unit_testing/test_sync_send.cpp
View file @
d4365f40
...
@@ -7,15 +7,15 @@ using namespace cppa::placeholders;
...
@@ -7,15 +7,15 @@ using namespace cppa::placeholders;
struct
sync_mirror
:
sb_actor
<
sync_mirror
>
{
struct
sync_mirror
:
sb_actor
<
sync_mirror
>
{
behavior
init_state
=
(
behavior
init_state
=
(
others
()
>>
[]
{
re
ply_tuple
(
self
->
last_dequeued
()
);
}
others
()
>>
[]
{
re
turn
self
->
last_dequeued
(
);
}
);
);
};
};
// replies to 'f' with 0.0f and to 'i' with 0
// replies to 'f' with 0.0f and to 'i' with 0
struct
float_or_int
:
sb_actor
<
float_or_int
>
{
struct
float_or_int
:
sb_actor
<
float_or_int
>
{
behavior
init_state
=
(
behavior
init_state
=
(
on
(
atom
(
"f"
))
>>
[]
{
re
ply
(
0.0
f
)
;
},
on
(
atom
(
"f"
))
>>
[]
{
re
turn
0.0
f
;
},
on
(
atom
(
"i"
))
>>
[]
{
re
ply
(
0
)
;
}
on
(
atom
(
"i"
))
>>
[]
{
re
turn
0
;
}
);
);
};
};
...
@@ -273,7 +273,7 @@ int main() {
...
@@ -273,7 +273,7 @@ int main() {
spawn
<
monitored
+
blocking_api
>
([]
{
// client
spawn
<
monitored
+
blocking_api
>
([]
{
// client
auto
s
=
spawn
<
server
,
linked
>
();
// server
auto
s
=
spawn
<
server
,
linked
>
();
// server
auto
w
=
spawn
<
linked
>
([]
{
// worker
auto
w
=
spawn
<
linked
>
([]
{
// worker
become
(
on
(
atom
(
"request"
))
>>
[]{
re
ply
(
atom
(
"response"
)
);
});
become
(
on
(
atom
(
"request"
))
>>
[]{
re
turn
atom
(
"response"
);
});
});
});
// first 'idle', then 'request'
// first 'idle', then 'request'
send_as
(
w
,
s
,
atom
(
"idle"
));
send_as
(
w
,
s
,
atom
(
"idle"
));
...
...
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