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
b88aaefe
Commit
b88aaefe
authored
Jun 07, 2011
by
neverlord
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
:Attach for proxies
parent
5fce51f5
Changes
15
Show whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
320 additions
and
111 deletions
+320
-111
cppa.creator.user
cppa.creator.user
+1
-1
cppa/actor_proxy.hpp
cppa/actor_proxy.hpp
+11
-6
cppa/cppa.hpp
cppa/cppa.hpp
+8
-0
cppa/detail/actor_proxy_cache.hpp
cppa/detail/actor_proxy_cache.hpp
+1
-0
cppa/detail/atom_val.hpp
cppa/detail/atom_val.hpp
+2
-2
cppa/match.hpp
cppa/match.hpp
+15
-1
src/actor_proxy.cpp
src/actor_proxy.cpp
+35
-3
src/actor_proxy_cache.cpp
src/actor_proxy_cache.cpp
+14
-3
src/cppa.cpp
src/cppa.cpp
+51
-0
src/unicast_network.cpp
src/unicast_network.cpp
+96
-34
src/uniform_type_info.cpp
src/uniform_type_info.cpp
+4
-2
unit_testing/ping_pong.cpp
unit_testing/ping_pong.cpp
+22
-10
unit_testing/test__atom.cpp
unit_testing/test__atom.cpp
+29
-10
unit_testing/test__remote_actor.cpp
unit_testing/test__remote_actor.cpp
+1
-1
unit_testing/test__spawn.cpp
unit_testing/test__spawn.cpp
+30
-38
No files found.
cppa.creator.user
View file @
b88aaefe
...
@@ -135,7 +135,7 @@
...
@@ -135,7 +135,7 @@
</data>
</data>
<data>
<data>
<variable>
ProjectExplorer.Project.Updater.EnvironmentId
</variable>
<variable>
ProjectExplorer.Project.Updater.EnvironmentId
</variable>
<value
type=
"QString"
>
{
07fcd197-092d-45a0-8500-3be614e6ae31
}
</value>
<value
type=
"QString"
>
{
23902c37-f07e-47cd-bb19-c366b9f708db
}
</value>
</data>
</data>
<data>
<data>
<variable>
ProjectExplorer.Project.Updater.FileVersion
</variable>
<variable>
ProjectExplorer.Project.Updater.FileVersion
</variable>
...
...
cppa/actor_proxy.hpp
View file @
b88aaefe
...
@@ -17,12 +17,6 @@ namespace cppa {
...
@@ -17,12 +17,6 @@ namespace cppa {
class
actor_proxy
:
public
actor
class
actor_proxy
:
public
actor
{
{
process_information_ptr
m_parent
;
std
::
atomic
<
std
::
uint32_t
>
m_exit_reason
;
std
::
mutex
m_mtx
;
std
::
vector
<
unique_attachable_ptr
>
m_attachables
;
public:
public:
actor_proxy
(
std
::
uint32_t
mid
,
process_information_ptr
&&
parent
);
actor_proxy
(
std
::
uint32_t
mid
,
process_information_ptr
&&
parent
);
...
@@ -48,6 +42,17 @@ class actor_proxy : public actor
...
@@ -48,6 +42,17 @@ class actor_proxy : public actor
process_information_ptr
parent_process_ptr
()
const
;
process_information_ptr
parent_process_ptr
()
const
;
private:
// implemented in unicast_network.cpp
static
void
forward_message
(
const
process_information_ptr
&
,
const
message
&
);
process_information_ptr
m_parent
;
std
::
atomic
<
std
::
uint32_t
>
m_exit_reason
;
std
::
mutex
m_mtx
;
std
::
vector
<
unique_attachable_ptr
>
m_attachables
;
};
};
typedef
intrusive_ptr
<
actor_proxy
>
actor_proxy_ptr
;
typedef
intrusive_ptr
<
actor_proxy
>
actor_proxy_ptr
;
...
...
cppa/cppa.hpp
View file @
b88aaefe
...
@@ -71,6 +71,14 @@ inline void link(actor_ptr&& other)
...
@@ -71,6 +71,14 @@ inline void link(actor_ptr&& other)
self
()
->
link_to
(
other
);
self
()
->
link_to
(
other
);
}
}
void
monitor
(
actor_ptr
&
whom
);
void
monitor
(
actor_ptr
&&
whom
);
void
demonitor
(
actor_ptr
&
whom
);
void
demonitor
(
actor_ptr
&&
whom
);
inline
void
trap_exit
(
bool
new_value
)
inline
void
trap_exit
(
bool
new_value
)
{
{
self
()
->
trap_exit
(
new_value
);
self
()
->
trap_exit
(
new_value
);
...
...
cppa/detail/actor_proxy_cache.hpp
View file @
b88aaefe
...
@@ -22,6 +22,7 @@ class actor_proxy_cache
...
@@ -22,6 +22,7 @@ class actor_proxy_cache
std
::
map
<
key_tuple
,
actor_proxy_ptr
>
m_proxies
;
std
::
map
<
key_tuple
,
actor_proxy_ptr
>
m_proxies
;
process_information_ptr
get_pinfo
(
const
key_tuple
&
key
);
process_information_ptr
get_pinfo
(
const
key_tuple
&
key
);
void
add
(
const
actor_proxy_ptr
&
pptr
,
const
key_tuple
&
key
);
public:
public:
...
...
cppa/detail/atom_val.hpp
View file @
b88aaefe
...
@@ -29,7 +29,7 @@ inline constexpr std::uint64_t next_interim(std::uint64_t tmp, size_t char_code)
...
@@ -29,7 +29,7 @@ inline constexpr std::uint64_t next_interim(std::uint64_t tmp, size_t char_code)
constexpr
std
::
uint64_t
atom_val
(
const
char
*
str
,
std
::
uint64_t
interim
=
0
)
constexpr
std
::
uint64_t
atom_val
(
const
char
*
str
,
std
::
uint64_t
interim
=
0
)
{
{
return
(
*
str
==
'\0'
)
?
interim
return
(
*
str
<=
0
)
?
interim
:
atom_val
(
str
+
1
,
next_interim
(
interim
,
*
str
));
:
atom_val
(
str
+
1
,
next_interim
(
interim
,
*
str
));
}
}
...
...
cppa/match.hpp
View file @
b88aaefe
...
@@ -70,11 +70,25 @@ bool match(const any_tuple& what, const ValuesTuple& vals)
...
@@ -70,11 +70,25 @@ bool match(const any_tuple& what, const ValuesTuple& vals)
}
}
template
<
atom_value
A0
,
typename
...
MatchRules
>
template
<
atom_value
A0
,
typename
...
MatchRules
>
bool
match
(
const
any_tuple
&
what
)
inline
bool
match
(
const
any_tuple
&
what
)
{
{
return
match
<
atom_value
,
MatchRules
...
>
(
what
,
make_tdata
(
A0
));
return
match
<
atom_value
,
MatchRules
...
>
(
what
,
make_tdata
(
A0
));
}
}
template
<
atom_value
A0
,
atom_value
A1
,
typename
...
MatchRules
>
inline
bool
match
(
const
any_tuple
&
what
)
{
return
match
<
atom_value
,
atom_value
,
MatchRules
...
>
(
what
,
make_tdata
(
A0
,
A1
));
}
template
<
atom_value
A0
,
atom_value
A1
,
atom_value
A2
,
typename
...
MatchRules
>
bool
match
(
const
any_tuple
&
what
)
{
auto
vals
=
make_tdata
(
A0
,
A1
,
A2
);
return
match
<
atom_value
,
atom_value
,
atom_value
,
MatchRules
...
>
(
what
,
vals
);
}
}
// namespace cppa
}
// namespace cppa
#endif // MATCH_HPP
#endif // MATCH_HPP
src/actor_proxy.cpp
View file @
b88aaefe
#include "cppa/atom.hpp"
#include "cppa/message.hpp"
#include "cppa/actor_proxy.hpp"
#include "cppa/actor_proxy.hpp"
#include "cppa/exit_reason.hpp"
#include "cppa/exit_reason.hpp"
#include "cppa/detail/actor_impl_util.hpp"
#include "cppa/detail/actor_impl_util.hpp"
using
cppa
::
exit_reason
::
not_exited
;
using
cppa
::
exit_reason
::
not_exited
;
namespace
{
typedef
std
::
lock_guard
<
std
::
mutex
>
guard_type
;
}
namespace
{
constexpr
auto
s_kp
=
cppa
::
atom
(
":KillProxy"
);
typedef
std
::
lock_guard
<
std
::
mutex
>
guard_type
;
}
// namespace <anonymous>
namespace
cppa
{
namespace
cppa
{
...
@@ -20,8 +27,33 @@ actor_proxy::actor_proxy(std::uint32_t mid, process_information_ptr&& pptr)
...
@@ -20,8 +27,33 @@ actor_proxy::actor_proxy(std::uint32_t mid, process_information_ptr&& pptr)
if
(
!
m_parent
)
throw
std
::
runtime_error
(
"parent == nullptr"
);
if
(
!
m_parent
)
throw
std
::
runtime_error
(
"parent == nullptr"
);
}
}
// implemented in unicast_network.cpp
void
actor_proxy
::
enqueue
(
const
message
&
msg
)
// void actor_proxy::enqueue(const message& msg);
{
const
any_tuple
&
content
=
msg
.
content
();
if
(
content
.
size
()
==
2
&&
content
.
utype_info_at
(
0
)
==
typeid
(
atom_value
)
&&
*
reinterpret_cast
<
const
atom_value
*>
(
content
.
at
(
0
))
==
s_kp
&&
content
.
utype_info_at
(
1
)
==
typeid
(
std
::
uint32_t
))
{
decltype
(
m_attachables
)
mattachables
;
auto
r
=
*
reinterpret_cast
<
const
std
::
uint32_t
*>
(
content
.
at
(
1
));
// lifetime scope of guard
{
guard_type
guard
(
m_mtx
);
m_exit_reason
=
r
;
mattachables
=
std
::
move
(
m_attachables
);
m_attachables
.
clear
();
}
for
(
auto
i
=
mattachables
.
begin
();
i
!=
mattachables
.
end
();
++
i
)
{
(
*
i
)
->
detach
(
r
);
}
}
else
{
forward_message
(
m_parent
,
msg
);
}
}
bool
actor_proxy
::
attach
(
attachable
*
ptr
)
bool
actor_proxy
::
attach
(
attachable
*
ptr
)
{
{
...
...
src/actor_proxy_cache.cpp
View file @
b88aaefe
#include <boost/thread.hpp>
#include <boost/thread.hpp>
#include "cppa/atom.hpp"
#include "cppa/message.hpp"
#include "cppa/detail/actor_proxy_cache.hpp"
#include "cppa/detail/actor_proxy_cache.hpp"
namespace
{
namespace
{
...
@@ -31,15 +33,24 @@ actor_proxy_ptr actor_proxy_cache::get(const key_tuple& key)
...
@@ -31,15 +33,24 @@ actor_proxy_ptr actor_proxy_cache::get(const key_tuple& key)
{
{
return
i
->
second
;
return
i
->
second
;
}
}
return
new
actor_proxy
(
std
::
get
<
0
>
(
key
),
get_pinfo
(
key
));
actor_proxy_ptr
result
(
new
actor_proxy
(
std
::
get
<
0
>
(
key
),
get_pinfo
(
key
)));
result
->
enqueue
(
message
(
result
,
nullptr
,
make_tuple
(
atom
(
":Monitor"
),
result
)));
add
(
result
);
return
result
;
}
void
actor_proxy_cache
::
add
(
const
actor_proxy_ptr
&
pptr
,
const
key_tuple
&
key
)
{
m_pinfos
.
insert
(
std
::
make_pair
(
key
,
pptr
->
parent_process_ptr
()));
m_proxies
.
insert
(
std
::
make_pair
(
key
,
pptr
));
}
}
void
actor_proxy_cache
::
add
(
const
actor_proxy_ptr
&
pptr
)
void
actor_proxy_cache
::
add
(
const
actor_proxy_ptr
&
pptr
)
{
{
auto
pinfo
=
pptr
->
parent_process_ptr
();
auto
pinfo
=
pptr
->
parent_process_ptr
();
key_tuple
key
(
pptr
->
id
(),
pinfo
->
process_id
,
pinfo
->
node_id
);
key_tuple
key
(
pptr
->
id
(),
pinfo
->
process_id
,
pinfo
->
node_id
);
m_pinfos
.
insert
(
std
::
make_pair
(
key
,
pinfo
));
add
(
pptr
,
key
);
m_proxies
.
insert
(
std
::
make_pair
(
key
,
pptr
));
}
}
actor_proxy_cache
&
get_actor_proxy_cache
()
actor_proxy_cache
&
get_actor_proxy_cache
()
...
...
src/cppa.cpp
View file @
b88aaefe
#include "cppa/cppa.hpp"
#include "cppa/cppa.hpp"
namespace
{
class
observer
:
public
cppa
::
attachable
{
cppa
::
actor_ptr
m_client
;
public:
observer
(
cppa
::
actor_ptr
&&
client
)
:
m_client
(
std
::
move
(
client
))
{
}
void
detach
(
std
::
uint32_t
reason
)
{
cppa
::
send
(
m_client
,
cppa
::
atom
(
":Down"
),
reason
);
}
bool
matches
(
const
cppa
::
attachable
::
token
&
match_token
)
{
if
(
match_token
.
subtype
==
typeid
(
observer
))
{
auto
ptr
=
reinterpret_cast
<
const
cppa
::
context
*>
(
match_token
.
ptr
);
return
m_client
==
ptr
;
}
return
false
;
}
};
}
// namespace <anonymous>
namespace
cppa
{
namespace
cppa
{
context
*
operator
<<
(
context
*
whom
,
const
any_tuple
&
what
)
context
*
operator
<<
(
context
*
whom
,
const
any_tuple
&
what
)
...
@@ -15,4 +45,25 @@ context* operator<<(context* whom, any_tuple&& what)
...
@@ -15,4 +45,25 @@ context* operator<<(context* whom, any_tuple&& what)
return
whom
;
return
whom
;
}
}
void
monitor
(
actor_ptr
&
whom
)
{
if
(
whom
)
whom
->
attach
(
new
observer
(
self
()));
}
void
monitor
(
actor_ptr
&&
whom
)
{
monitor
(
static_cast
<
actor_ptr
&>
(
whom
));
}
void
demonitor
(
actor_ptr
&
whom
)
{
attachable
::
token
mtoken
(
typeid
(
observer
),
self
());
if
(
whom
)
whom
->
detach
(
mtoken
);
}
void
demonitor
(
actor_ptr
&&
whom
)
{
demonitor
(
static_cast
<
actor_ptr
&>
(
whom
));
}
}
// namespace cppa
}
// namespace cppa
src/unicast_network.cpp
View file @
b88aaefe
...
@@ -47,10 +47,14 @@ namespace {
...
@@ -47,10 +47,14 @@ namespace {
struct
mailman_send_job
struct
mailman_send_job
{
{
actor_proxy_ptr
client
;
process_information_ptr
target_peer
;
message
original_message
;
message
original_message
;
mailman_send_job
(
actor_proxy_ptr
apptr
,
message
omsg
)
mailman_send_job
(
actor_proxy_ptr
apptr
,
message
msg
)
:
client
(
apptr
),
original_message
(
omsg
)
:
target_peer
(
apptr
->
parent_process_ptr
()),
original_message
(
msg
)
{
}
mailman_send_job
(
process_information_ptr
peer
,
message
msg
)
:
target_peer
(
peer
),
original_message
(
msg
)
{
{
}
}
};
};
...
@@ -96,7 +100,13 @@ class mailman_job
...
@@ -96,7 +100,13 @@ class mailman_job
public:
public:
mailman_job
(
actor_proxy_ptr
apptr
,
message
omsg
)
mailman_job
(
process_information_ptr
piptr
,
const
message
&
omsg
)
:
next
(
0
),
m_type
(
send_job_type
)
{
new
(
&
m_send_job
)
mailman_send_job
(
piptr
,
omsg
);
}
mailman_job
(
actor_proxy_ptr
apptr
,
const
message
&
omsg
)
:
next
(
0
),
m_type
(
send_job_type
)
:
next
(
0
),
m_type
(
send_job_type
)
{
{
new
(
&
m_send_job
)
mailman_send_job
(
apptr
,
omsg
);
new
(
&
m_send_job
)
mailman_send_job
(
apptr
,
omsg
);
...
@@ -189,7 +199,7 @@ s_mailman_manager;
...
@@ -189,7 +199,7 @@ s_mailman_manager;
util
::
single_reader_queue
<
mailman_job
>&
s_mailman_queue
()
util
::
single_reader_queue
<
mailman_job
>&
s_mailman_queue
()
{
{
return
*
s_mailman_manager
.
m_queue
;
return
*
(
s_mailman_manager
.
m_queue
)
;
}
}
// a map that manages links between local actors and remote actors (proxies)
// a map that manages links between local actors and remote actors (proxies)
...
@@ -204,7 +214,8 @@ void fake_exits_from_disconnected_links(link_map& links)
...
@@ -204,7 +214,8 @@ void fake_exits_from_disconnected_links(link_map& links)
for
(
auto
&
rem_actor
:
remote_actors
)
for
(
auto
&
rem_actor
:
remote_actors
)
{
{
message
msg
(
rem_actor
,
local_actor
,
message
msg
(
rem_actor
,
local_actor
,
atom
(
":Exit"
),
exit_reason
::
remote_link_unreachable
);
atom
(
":KillProxy"
),
exit_reason
::
remote_link_unreachable
);
local_actor
->
enqueue
(
msg
);
local_actor
->
enqueue
(
msg
);
}
}
}
}
...
@@ -232,6 +243,26 @@ void remove_link(link_map& links,
...
@@ -232,6 +243,26 @@ void remove_link(link_map& links,
}
}
}
}
class
remote_observer
:
public
attachable
{
process_information_ptr
peer
;
public:
remote_observer
(
const
process_information_ptr
&
piptr
)
:
peer
(
piptr
)
{
}
void
detach
(
std
::
uint32_t
reason
)
{
actor_ptr
self_ptr
=
self
();
message
msg
(
self_ptr
,
self_ptr
,
make_tuple
(
atom
(
":KillProxy"
),
reason
));
s_mailman_queue
().
push_back
(
new
mailman_job
(
peer
,
msg
));
}
};
// handles *all* outgoing messages
// handles *all* outgoing messages
void
mailman_loop
()
void
mailman_loop
()
{
{
...
@@ -267,7 +298,7 @@ void mailman_loop()
...
@@ -267,7 +298,7 @@ void mailman_loop()
}
}
*/
*/
// forward message to receiver peer
// forward message to receiver peer
auto
peer_element
=
peers
.
find
(
sjob
.
client
->
parent_process
(
));
auto
peer_element
=
peers
.
find
(
*
(
sjob
.
target_peer
));
if
(
peer_element
!=
peers
.
end
())
if
(
peer_element
!=
peers
.
end
())
{
{
auto
peer
=
peer_element
->
second
;
auto
peer
=
peer_element
->
second
;
...
@@ -275,7 +306,7 @@ void mailman_loop()
...
@@ -275,7 +306,7 @@ void mailman_loop()
{
{
bs
<<
out_msg
;
bs
<<
out_msg
;
auto
size32
=
static_cast
<
std
::
uint32_t
>
(
bs
.
size
());
auto
size32
=
static_cast
<
std
::
uint32_t
>
(
bs
.
size
());
//
cout << "--> " << to_string(out_msg) << endl;
cout
<<
"--> "
<<
to_string
(
out_msg
)
<<
endl
;
auto
sent
=
::
send
(
peer
,
&
size32
,
sizeof
(
size32
),
flags
);
auto
sent
=
::
send
(
peer
,
&
size32
,
sizeof
(
size32
),
flags
);
if
(
sent
!=
-
1
)
if
(
sent
!=
-
1
)
{
{
...
@@ -284,7 +315,7 @@ void mailman_loop()
...
@@ -284,7 +315,7 @@ void mailman_loop()
if
(
sent
==
-
1
)
if
(
sent
==
-
1
)
{
{
// peer unreachable
// peer unreachable
peers
.
erase
(
sjob
.
client
->
parent_process
(
));
peers
.
erase
(
*
(
sjob
.
target_peer
));
}
}
}
}
catch
(...)
catch
(...)
...
@@ -343,21 +374,31 @@ void read_from_socket(native_socket_t sfd, void* buf, size_t buf_size)
...
@@ -343,21 +374,31 @@ void read_from_socket(native_socket_t sfd, void* buf, size_t buf_size)
while
(
urres
<
left
);
while
(
urres
<
left
);
}
}
// handles *one* socket
template
<
typename
T
>
void
post_office_loop
(
native_socket_t
socket_fd
,
const
actor_proxy_ptr
&
aptr
)
T
&
operator
<<
(
T
&
o
,
const
process_information
&
pinfo
)
{
return
(
o
<<
pinfo
.
process_id
<<
"@"
<<
pinfo
.
node_id_as_string
());
}
// handles *one* socket / peer
void
post_office_loop
(
native_socket_t
socket_fd
,
process_information_ptr
peer
,
actor_proxy_ptr
aptr
)
{
{
//cout << "--> post_office_loop" << endl;
cout
<<
"--> post_office_loop; self() = "
<<
process_information
::
get
()
<<
", peer = "
<<
*
peer
<<
endl
;
if
(
aptr
)
detail
::
get_actor_proxy_cache
().
add
(
aptr
);
if
(
aptr
)
detail
::
get_actor_proxy_cache
().
add
(
aptr
);
auto
meta_msg
=
uniform_typeid
<
message
>
();
if
(
!
meta_msg
)
{
throw
std
::
logic_error
(
"meta_msg == nullptr"
);
}
message
msg
;
message
msg
;
std
::
uint32_t
rsize
;
std
::
uint32_t
rsize
;
char
*
buf
=
nullptr
;
char
*
buf
=
nullptr
;
size_t
buf_size
=
0
;
size_t
buf_size
=
0
;
size_t
buf_allocated
=
0
;
size_t
buf_allocated
=
0
;
auto
meta_msg
=
uniform_typeid
<
message
>
();
const
std
::
type_info
&
atom_tinfo
=
typeid
(
atom_value
);
auto
&
pinfo
=
process_information
::
get
();
try
try
{
{
for
(;;)
for
(;;)
...
@@ -376,24 +417,43 @@ void post_office_loop(native_socket_t socket_fd, const actor_proxy_ptr& aptr)
...
@@ -376,24 +417,43 @@ void post_office_loop(native_socket_t socket_fd, const actor_proxy_ptr& aptr)
buf
=
new
char
[
buf_allocated
];
buf
=
new
char
[
buf_allocated
];
}
}
buf_size
=
rsize
;
buf_size
=
rsize
;
cout
<<
"["
<<
pinfo
<<
"] "
<<
"received "
<<
rsize
<<
" bytes"
<<
endl
;
read_from_socket
(
socket_fd
,
buf
,
buf_size
);
read_from_socket
(
socket_fd
,
buf
,
buf_size
);
binary_deserializer
bd
(
buf
,
buf_size
);
binary_deserializer
bd
(
buf
,
buf_size
);
meta_msg
->
deserialize
(
&
msg
,
&
bd
);
meta_msg
->
deserialize
(
&
msg
,
&
bd
);
//cout << "<-- " << to_string(msg) << endl;
cout
<<
"<-- "
<<
to_string
(
msg
)
<<
endl
;
if
(
msg
.
content
().
size
()
==
1
&&
msg
.
content
().
utype_info_at
(
0
)
==
atom_tinfo
&&
*
reinterpret_cast
<
const
atom_value
*>
(
msg
.
content
().
at
(
0
))
==
atom
(
":Monitor"
))
{
actor_ptr
sender
=
msg
.
sender
();
if
(
sender
->
parent_process
()
==
pinfo
)
{
cout
<<
pinfo
.
process_id
<<
"@"
<<
pinfo
.
node_id_as_string
()
<<
" :Monitor; actor id = "
<<
sender
->
id
()
<<
endl
;
// local actor?
// this message was send from a proxy
sender
->
attach
(
new
remote_observer
(
peer
));
}
// don't "deliver" message
continue
;
}
auto
r
=
msg
.
receiver
();
auto
r
=
msg
.
receiver
();
if
(
r
)
r
->
enqueue
(
msg
);
if
(
r
)
r
->
enqueue
(
msg
);
}
}
}
}
catch
(
std
::
ios_base
::
failure
&
e
)
catch
(
std
::
ios_base
::
failure
&
e
)
{
{
//
cout << "std::ios_base::failure: " << e.what() << endl;
cout
<<
"std::ios_base::failure: "
<<
e
.
what
()
<<
endl
;
}
}
catch
(
std
::
exception
&
e
)
catch
(
std
::
exception
&
e
)
{
{
//cout << detail::to_uniform_name(typeid(e)) << ": "
cout
<<
"["
<<
process_information
::
get
()
<<
"] "
// << e.what() << endl;
<<
detail
::
to_uniform_name
(
typeid
(
e
))
<<
": "
<<
e
.
what
()
<<
endl
;
}
}
//
cout << "<-- post_office_loop" << endl;
cout
<<
"<-- post_office_loop"
<<
endl
;
}
}
struct
mm_worker
struct
mm_worker
...
@@ -402,9 +462,10 @@ struct mm_worker
...
@@ -402,9 +462,10 @@ struct mm_worker
native_socket_t
m_sockfd
;
native_socket_t
m_sockfd
;
boost
::
thread
m_thread
;
boost
::
thread
m_thread
;
mm_worker
(
native_socket_t
sockfd
)
:
m_sockfd
(
sockfd
)
mm_worker
(
native_socket_t
sockfd
,
process_information_ptr
peer
)
,
m_thread
(
post_office_loop
,
:
m_sockfd
(
sockfd
)
,
m_thread
(
post_office_loop
,
sockfd
,
sockfd
,
peer
,
actor_proxy_ptr
())
actor_proxy_ptr
())
{
{
}
}
...
@@ -469,16 +530,16 @@ void middle_man_loop(native_socket_t server_socket_fd,
...
@@ -469,16 +530,16 @@ void middle_man_loop(native_socket_t server_socket_fd,
::
send
(
sockfd
,
&
id
,
sizeof
(
id
),
0
);
::
send
(
sockfd
,
&
id
,
sizeof
(
id
),
0
);
::
send
(
sockfd
,
&
(
pinf
.
process_id
),
sizeof
(
pinf
.
process_id
),
0
);
::
send
(
sockfd
,
&
(
pinf
.
process_id
),
sizeof
(
pinf
.
process_id
),
0
);
::
send
(
sockfd
,
pinf
.
node_id
.
data
(),
pinf
.
node_id
.
size
(),
0
);
::
send
(
sockfd
,
pinf
.
node_id
.
data
(),
pinf
.
node_id
.
size
(),
0
);
auto
peer_pinf
=
new
process_information
;
process_information_ptr
peer
(
new
process_information
)
;
read_from_socket
(
sockfd
,
read_from_socket
(
sockfd
,
&
(
peer
_pinf
->
process_id
),
&
(
peer
->
process_id
),
sizeof
(
std
::
uint32_t
));
sizeof
(
std
::
uint32_t
));
read_from_socket
(
sockfd
,
read_from_socket
(
sockfd
,
peer
_pinf
->
node_id
.
data
(),
peer
->
node_id
.
data
(),
process_information
::
node_id_size
);
process_information
::
node_id_size
);
s_mailman_queue
().
push_back
(
new
mailman_job
(
sockfd
,
peer
_pinf
));
s_mailman_queue
().
push_back
(
new
mailman_job
(
sockfd
,
peer
));
// todo: check if connected peer is compatible
// todo: check if connected peer is compatible
children
.
push_back
(
child_ptr
(
new
mm_worker
(
sockfd
)));
children
.
push_back
(
child_ptr
(
new
mm_worker
(
sockfd
,
peer
)));
//cout << "client connection done" << endl;
//cout << "client connection done" << endl;
}
}
}
}
...
@@ -493,9 +554,10 @@ void middle_man_loop(native_socket_t server_socket_fd,
...
@@ -493,9 +554,10 @@ void middle_man_loop(native_socket_t server_socket_fd,
}
// namespace <anonmyous>
}
// namespace <anonmyous>
void
actor_proxy
::
enqueue
(
const
message
&
msg
)
void
actor_proxy
::
forward_message
(
const
process_information_ptr
&
piptr
,
const
message
&
msg
)
{
{
s_mailman_queue
().
push_back
(
new
mailman_job
(
this
,
msg
));
s_mailman_queue
().
push_back
(
new
mailman_job
(
piptr
,
msg
));
}
}
void
publish
(
actor_ptr
&
whom
,
std
::
uint16_t
port
)
void
publish
(
actor_ptr
&
whom
,
std
::
uint16_t
port
)
...
@@ -570,7 +632,7 @@ actor_ptr remote_actor(const char* host, std::uint16_t port)
...
@@ -570,7 +632,7 @@ actor_ptr remote_actor(const char* host, std::uint16_t port)
process_information_ptr
pinfptr
(
peer_pinf
);
process_information_ptr
pinfptr
(
peer_pinf
);
actor_proxy_ptr
result
(
new
actor_proxy
(
remote_actor_id
,
pinfptr
));
actor_proxy_ptr
result
(
new
actor_proxy
(
remote_actor_id
,
pinfptr
));
s_mailman_queue
().
push_back
(
new
mailman_job
(
sockfd
,
pinfptr
));
s_mailman_queue
().
push_back
(
new
mailman_job
(
sockfd
,
pinfptr
));
boost
::
thread
(
post_office_loop
,
sockfd
,
result
).
detach
();
boost
::
thread
(
post_office_loop
,
sockfd
,
peer_pinf
,
result
).
detach
();
return
result
;
return
result
;
}
}
...
...
src/uniform_type_info.cpp
View file @
b88aaefe
...
@@ -708,8 +708,10 @@ uniform_type_info::by_type_info(const std::type_info& tinf)
...
@@ -708,8 +708,10 @@ uniform_type_info::by_type_info(const std::type_info& tinf)
auto
result
=
detail
::
s_uniform_type_info_map
().
by_raw_name
(
raw_name
(
tinf
));
auto
result
=
detail
::
s_uniform_type_info_map
().
by_raw_name
(
raw_name
(
tinf
));
if
(
!
result
)
if
(
!
result
)
{
{
throw
std
::
runtime_error
(
std
::
string
(
raw_name
(
tinf
))
std
::
string
error
=
"uniform_type_info::by_type_info(): "
;
+
" is an unknown typeid name"
);
error
+=
detail
::
to_uniform_name
(
tinf
);
error
+=
" is an unknown typeid name"
;
throw
std
::
runtime_error
(
error
);
}
}
return
result
;
return
result
;
}
}
...
...
unit_testing/ping_pong.cpp
View file @
b88aaefe
...
@@ -11,12 +11,21 @@ void pong(actor_ptr ping_actor)
...
@@ -11,12 +11,21 @@ void pong(actor_ptr ping_actor)
link
(
ping_actor
);
link
(
ping_actor
);
bool
done
=
false
;
bool
done
=
false
;
// kickoff
// kickoff
ping_actor
<<
make_tuple
(
0
);
// or: send(ping_actor, 0);
ping_actor
<<
make_tuple
(
atom
(
"Pong"
),
0
);
// or: send(ping_actor, 0);
// invoke rules
// invoke rules
auto
rules
=
(
on
<
std
::
int32_t
>
(
9
)
>>
[
&
]()
{
done
=
true
;
},
auto
pattern
=
on
<
std
::
int32_t
>
()
>>
[](
int
v
)
{
reply
(
v
+
1
);
});
(
on
<
atom
(
"Ping"
),
std
::
int32_t
>
(
9
)
>>
[
&
]()
{
done
=
true
;
},
on
<
atom
(
"Ping"
),
std
::
int32_t
>
()
>>
[](
int
v
)
{
reply
(
atom
(
"Pong"
),
v
+
1
);
}
);
// loop
// loop
while
(
!
done
)
receive
(
rules
);
while
(
!
done
)
receive
(
pattern
);
// terminate with non-normal exit reason
// terminate with non-normal exit reason
// to force ping actor to quit
// to force ping actor to quit
quit
(
exit_reason
::
user_defined
);
quit
(
exit_reason
::
user_defined
);
...
@@ -26,13 +35,16 @@ void ping()
...
@@ -26,13 +35,16 @@ void ping()
{
{
s_pongs
=
0
;
s_pongs
=
0
;
// invoke rule
// invoke rule
auto
rule
=
(
on
<
std
::
int32_t
>
()
>>
[](
std
::
int32_t
v
)
auto
pattern
=
(
on
<
atom
(
"Pong"
),
std
::
int32_t
>
()
>>
[](
std
::
int32_t
v
)
{
{
++
s_pongs
;
++
s_pongs
;
reply
(
v
+
1
);
reply
(
atom
(
"Ping"
),
v
+
1
);
});
}
);
// loop
// loop
for
(;;)
receive
(
rule
);
for
(;;)
receive
(
pattern
);
}
}
int
pongs
()
int
pongs
()
...
...
unit_testing/test__atom.cpp
View file @
b88aaefe
...
@@ -10,6 +10,7 @@
...
@@ -10,6 +10,7 @@
using
std
::
cout
;
using
std
::
cout
;
using
std
::
endl
;
using
std
::
endl
;
using
std
::
string
;
using
namespace
cppa
;
using
namespace
cppa
;
using
namespace
cppa
::
util
;
using
namespace
cppa
::
util
;
...
@@ -28,17 +29,35 @@ void foo()
...
@@ -28,17 +29,35 @@ void foo()
size_t
test__atom
()
size_t
test__atom
()
{
{
bool
matched_pattern
[
3
]
=
{
false
,
false
,
false
};
CPPA_TEST
(
test__atom
);
CPPA_TEST
(
test__atom
);
CPPA_CHECK_EQUAL
(
to_string
(
s_foo
),
"FooBar"
);
CPPA_CHECK_EQUAL
(
to_string
(
s_foo
),
"FooBar"
);
self
()
<<
make_tuple
(
atom
(
"foo"
),
static_cast
<
std
::
uint32_t
>
(
42
))
self
()
<<
make_tuple
(
atom
(
"foo"
),
static_cast
<
std
::
uint32_t
>
(
42
));
<<
make_tuple
(
atom
(
":Attach"
),
atom
(
":Baz"
),
"cstring"
)
<<
make_tuple
(
atom
(
"b"
),
atom
(
"a"
),
atom
(
"c"
),
23.
f
)
receive
(
on
<
atom
(
"foo"
),
std
::
uint32_t
>
()
>>
[
&
](
std
::
uint32_t
value
)
{
<<
make_tuple
(
atom
(
"a"
),
atom
(
"b"
),
atom
(
"c"
),
23.
f
);
auto
pattern
=
(
on
<
atom
(
"foo"
),
std
::
uint32_t
>
()
>>
[
&
](
std
::
uint32_t
value
)
{
matched_pattern
[
0
]
=
true
;
CPPA_CHECK_EQUAL
(
value
,
42
);
CPPA_CHECK_EQUAL
(
value
,
42
);
});
},
on
<
atom
(
":Attach"
),
atom
(
":Baz"
),
string
>
()
>>
[
&
](
const
string
&
str
)
{
matched_pattern
[
1
]
=
true
;
CPPA_CHECK_EQUAL
(
str
,
"cstring"
);
},
on
<
atom
(
"a"
),
atom
(
"b"
),
atom
(
"c"
),
float
>
()
>>
[
&
](
float
value
)
{
matched_pattern
[
2
]
=
true
;
CPPA_CHECK_EQUAL
(
value
,
23.
f
);
}
);
for
(
auto
i
=
0
;
i
<
3
;
++
i
)
receive
(
pattern
);
CPPA_CHECK
(
matched_pattern
[
0
]
&&
matched_pattern
[
1
]
&&
matched_pattern
[
2
]);
message
msg
=
receive
();
CPPA_CHECK
((
match
<
atom
(
"b"
),
atom
(
"a"
),
atom
(
"c"
),
float
>
(
msg
.
content
())));
CPPA_CHECK
(
try_receive
(
msg
)
==
false
);
return
CPPA_TEST_RESULT
;
return
CPPA_TEST_RESULT
;
}
}
unit_testing/test__remote_actor.cpp
View file @
b88aaefe
...
@@ -56,7 +56,7 @@ size_t test__remote_actor(const char* app_path, bool is_client,
...
@@ -56,7 +56,7 @@ size_t test__remote_actor(const char* app_path, bool is_client,
std
::
string
cmd
;
std
::
string
cmd
;
{
{
std
::
ostringstream
oss
;
std
::
ostringstream
oss
;
oss
<<
app_path
<<
" test__remote_actor "
<<
port
<<
" &>/dev/null"
;
oss
<<
app_path
<<
" test__remote_actor "
<<
port
;
//
<< " &>/dev/null";
cmd
=
oss
.
str
();
cmd
=
oss
.
str
();
}
}
// execute client_part() in a separate process,
// execute client_part() in a separate process,
...
...
unit_testing/test__spawn.cpp
View file @
b88aaefe
...
@@ -8,7 +8,9 @@
...
@@ -8,7 +8,9 @@
#include "cppa/cppa.hpp"
#include "cppa/cppa.hpp"
#include "cppa/actor.hpp"
#include "cppa/actor.hpp"
#include "cppa/to_string.hpp"
#include "cppa/to_string.hpp"
#include "cppa/exit_reason.hpp"
using
std
::
cerr
;
using
std
::
cout
;
using
std
::
cout
;
using
std
::
endl
;
using
std
::
endl
;
...
@@ -17,46 +19,36 @@ using namespace cppa;
...
@@ -17,46 +19,36 @@ using namespace cppa;
size_t
test__spawn
()
size_t
test__spawn
()
{
{
CPPA_TEST
(
test__spawn
);
CPPA_TEST
(
test__spawn
);
spawn
(
pong
,
spawn
(
ping
));
auto
report_unexpected
=
[
&
]
()
await_all_others_done
();
CPPA_CHECK_EQUAL
(
pongs
(),
5
);
/*
actor_ptr self_ptr = self();
{
{
spawn(echo, self_ptr, 1)
;
cerr
<<
"unexpected message: "
<<
to_string
(
last_received
())
<<
endl
;
spawn(pong) << make_tuple(23.f) << make_tuple(2
);
CPPA_CHECK
(
false
);
//send(sl, 23.f)
;
}
;
//send(sl, 2
);
auto
pong_actor
=
spawn
(
pong
,
spawn
(
ping
)
);
bool received_pong = false
;
monitor
(
pong_actor
)
;
bool received_echo = false;
auto
pattern
=
auto rules = (on<int>(42) >> [&]() { received_pong = true; },
(
on<int>(1) >> [&]() { received_echo = true; });
on
<
atom
(
":Down"
),
std
::
uint32_t
>
()
>>
[
&
]
(
std
::
uint32_t
reason
)
receive(rules);
{
receive(rules
);
CPPA_CHECK_EQUAL
(
reason
,
exit_reason
::
user_defined
);
CPPA_CHECK(received_pong
);
CPPA_CHECK_EQUAL
(
last_received
().
sender
(),
pong_actor
);
CPPA_CHECK(received_echo);
},
}
others
()
>>
[
&
]
()
{
{
auto sl = spawn([]() {
report_unexpected
();
receive(on<int>() >> [](int value) {
reply((value * 20) + 2);
});
});
spawn([](actor_ptr whom, int what) { send(whom, what); },
self_ptr,
1);
send(sl, 23.f);
send(sl, 2);
bool received_pong = false;
bool received_echo = false;
auto rules = (on<int>(42) >> [&]() { received_pong = true; },
on<int>(1) >> [&]() { received_echo = true; });
receive(rules);
receive(rules);
CPPA_CHECK(received_pong);
CPPA_CHECK(received_echo);
}
}
);
// wait for :Down message of pong
receive
(
pattern
);
// wait for termination of all spawned actors
await_all_others_done
();
await_all_others_done
();
*/
// mailbox has to be empty
message
msg
;
while
(
try_receive
(
msg
))
{
report_unexpected
();
}
// verify pong messages
CPPA_CHECK_EQUAL
(
pongs
(),
5
);
return
CPPA_TEST_RESULT
;
return
CPPA_TEST_RESULT
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment