actor-framework / actor-framework Goto Github PK
View Code? Open in Web Editor NEWAn Open Source Implementation of the Actor Model in C++
Home Page: http://actor-framework.org/
License: BSD 3-Clause "New" or "Revised" License
An Open Source Implementation of the Actor Model in C++
Home Page: http://actor-framework.org/
License: BSD 3-Clause "New" or "Revised" License
is_iterable.hpp mentioned twice in Makefile's nobase_library_include_HEADERS, see http://glim.ru/personal/bugs/libcppa.7z
/usr/bin/install -c -m 644 cppa/util/abstract_uniform_type_info.hpp cppa/util/apply_tuple.hpp cppa/util/arg_match_t.hpp cppa/util/at.hpp cppa/util/callable_trait.hpp cppa/util/comparable.hpp cppa/util/compare_tuples.hpp cppa/util/conjunction.hpp cppa/util/disable_if.hpp cppa/util/disjunction.hpp cppa/util/duration.hpp cppa/util/element_at.hpp cppa/util/enable_if.hpp cppa/util/fiber.hpp cppa/util/fixed_vector.hpp cppa/util/if_else.hpp cppa/util/is_array_of.hpp cppa/util/is_builtin.hpp cppa/util/is_forward_iterator.hpp cppa/util/is_iterable.hpp cppa/util/is_iterable.hpp cppa/util/is_legal_tuple_type.hpp cppa/util/is_manipulator.hpp cppa/util/is_mutable_ref.hpp cppa/util/is_primitive.hpp cppa/util/producer_consumer_list.hpp cppa/util/pt_dispatch.hpp cppa/util/pt_token.hpp cppa/util/replace_type.hpp cppa/util/ripemd_160.hpp cppa/util/rm_ref.hpp cppa/util/shared_lock_guard.hpp cppa/util/shared_spinlock.hpp cppa/util/static_foreach.hpp cppa/util/tbind.hpp cppa/util/type_list.hpp cppa/util/type_pair.hpp cppa/util/upgrade_lock_guard.hpp cppa/util/void_type.hpp cppa/util/wrapped.hpp '/usr/local/include/cppa/0.1//cppa/util'
/usr/bin/install: will not overwrite just-created `/usr/local/include/cppa/0.1//cppa/util/is_iterable.hpp' with `cppa/util/is_iterable.hpp'
make[2]: *** [install-nobase_library_includeHEADERS] Error 1
P.S. Also "is_comparable.hpp" seems to be missing from /usr/local/include:
In file included from /usr/local/include/cppa/0.1/cppa/any_tuple.hpp:34:0,
from /usr/local/include/cppa/0.1/cppa/pattern.hpp:41,
from /usr/local/include/cppa/0.1/cppa/on.hpp:38,
from /usr/local/include/cppa/0.1/cppa/cppa.hpp:38,
from src/Img2.cc:76:
/usr/local/include/cppa/0.1/cppa/tuple.hpp:47:39: fatal error: cppa/util/is_comparable.hpp: No such file or directory
It seems that await_all_others_done()
does not always return when it should. In the example below, I just get the output from the terminating actor, but the application does not terminate.
#include <csignal>
#include <cppa/cppa.hpp>
using namespace cppa;
struct bro : sb_actor<bro>
{
behavior init_state = (
on(atom("shutdown")) >> [=]
{
quit();
std::cout << "yo bro?!" << std::endl;
});
};
struct program
{
program()
{
buddy = spawn<bro>();
}
void shutdown()
{
send(buddy, atom("shutdown"));
}
actor_ptr buddy;
};
program p;
static void shutdown_handler(int signo)
{
p.shutdown();
}
int main(int argc, char *argv[])
{
struct sigaction sig_handler;
sig_handler.sa_handler = shutdown_handler;
sigemptyset(&sig_handler.sa_mask);
sig_handler.sa_flags = 0;
sigaction(SIGINT, &sig_handler, NULL);
sigaction(SIGHUP, &sig_handler, NULL);
sigaction(SIGTERM, &sig_handler, NULL);
// Removed.
// program p;
await_all_others_done();
return 0;
}
My little test program (see below) gives me the following error:
panic!
/Users/mavam/code/libcppa/./cppa/event_based_actor.hpp:153: requirement failed 'bhvr.timeout().valid()'
0 libcppa.0.dylib 0x0000000107467210 _ZN4cppa17event_based_actor14handle_timeoutERNS_8behaviorE + 128
1 libcppa.0.dylib 0x0000000107466f81 _ZN4cppa6detail14receive_policy14handle_timeoutINS_17event_based_actorEEEvPT_RNS_8behaviorE + 33
2 libcppa.0.dylib 0x00000001074666ee _ZN4cppa6detail14receive_policy14handle_messageINS_17event_based_actorENS_8behaviorENSt3__117integral_constantINS0_19receive_policy_flagELS7_1EEEEENS1_21handle_message_resultEPT_PNS0_20recursive_queue_nodeERT0_N
S_12message_id_tET1_ + 190
3 libcppa.0.dylib 0x00000001074660bb _ZN4cppa6detail14receive_policy6invokeINS_17event_based_actorENS_8behaviorEEEbPT_PNS0_20recursive_queue_nodeERT0_NS_12message_id_tE + 75
4 libcppa.0.dylib 0x0000000107460af4 _ZN4cppa6detail14behavior_stack6invokeINS0_14receive_policyENS_17event_based_actorEEEbRT_PT0_PNS0_20recursive_queue_nodeE + 612
5 libcppa.0.dylib 0x00000001074600dc _ZN4cppa17event_based_actor6resumeEPNS_4util5fiberE + 668
6 libcppa.0.dylib 0x00000001074e40ca _ZN4cppa6detail21thread_pool_scheduler6workerclEv + 282
7 libcppa.0.dylib 0x00000001074e0245 _ZN4cppa6detail21thread_pool_scheduler11worker_loopEPNS1_6workerE + 21
8 libcppa.0.dylib 0x00000001074e75c3 _ZNSt3__114__thread_proxyINS_5tupleIJPFvPN4cppa6detail21thread_pool_scheduler6workerEES6_EEEEEPvSA_ + 451
9 libsystem_c.dylib 0x00007fff8b2348bf _pthread_start + 335
[1] 60732 abort ./a.out
Essentially, when the timeout kicks in, something becomes invalid. Here is the test case:
#include <cppa/cppa.hpp>
using namespace cppa;
struct trainer : sb_actor<trainer>
{
trainer(actor_ptr trainee)
: trainee(trainee)
{ }
behavior init_state = (
on(atom("train")) >> [=]
{
auto f = sync_send(trainee, 10u);
handle_response(f)(
on(atom("hard")) >> [=]
{
std::cout << "really?" << std::endl;
reply(atom("fired"));
quit();
},
after(std::chrono::milliseconds(100)) >> []
{
std::cout << "panic!" << std::endl;
});
});
actor_ptr trainee;
};
struct actress : sb_actor<actress>
{
behavior init_state = (
on_arg_match >> [](unsigned i)
{
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "I just did " << i << " flips" << std::endl;
reply(i > 2 ? atom("hard") : atom("easy"));
},
on(atom("fired")) >> [=]
{
quit();
});
};
int main()
{
auto a = spawn<actress>();
auto t = spawn<trainer>(a);
send(t, atom("train"));
await_all_others_done();
return 0;
}
I have found the hard way that libcppa calls exit
from middleman.cpp:
int sresult;
do {
sresult = select(maxfd + 1, &rdset, wrset_ptr, nullptr, nullptr);
if (sresult < 0) {
CPPA_CRITICAL("select() failed");
}
}
while (sresult == 0);
I think select errors should be handled gracefully and explained with "strerror".
(It's a blocker, I can't use libcppa as long as it calls exit instead of handling errros.
AFAIK, it is even normal for select to exit with EINTR).
When running make test
on a 64-bit Fedora Linux box with GCC 4.7, the system becomes unusable (and requires a reboot) when entering the spawn
test case. The last output is:
run test__spawn ...
How could I debug this further?
Is it possible to implement try_receive() function that would wait until either specified number of microseconds has elapsed or message has arrived?
I'm trying to implement an actor that a) sends ticks to other actors and b) waits until it's told to terminate.
try_receive with timeout would be of great help, since it would make instant termination possible -
currently actor has to wait for the next scheduled tick in order to check whether it got termination message.
In Scala actors there is the "!?" method:
def !? (msec: Long, msg: Any): Option[Any]
Sends msg to this actor and awaits reply (synchronous) within msec milliseconds.
def !?(msg: Any): Any
Sends msg to this actor and awaits reply (synchronous).
" It sends the Next message to the coordinator, but instead of returning like a normal (asynchronous) message send, it waits for a reply from the coordinator. The reply is the return value of !?. A message that was sent using !? is replied to using reply. Note that simply sending a message to sender does not work! That's because !? waits to receive a message from a private reply channel instead of the mailbox. This is necessary to distinguish "true" replies from "fake" ones resulting from old messages that happen to be in the mailbox. " (http://www.scala-lang.org/node/242)
Such operator in libcppa would be very convenient to call actors from the non-actor code.
For example: 1) we send message Q1 to an actor; 2) we wait for the reply R1, but then decide not to (timeout happens or whatever); 3) another iteration, we send message Q2 to an actor; 4) we expect reply R2 but we get R1
Unlike actor_ptr, group_ptr cannot be serialized. By implementing this feature, it would be possible to create a local group, send it to remote actors and then use such a "previously local" group like an any-source multicast group with the original host as rendezvous point / broker. Though the scaling behavior of such an ad-hoc group would be equal to n-times unicast and it would obviously suffer from a single pointer of failure, the feature would still pave the path for more advanced usage scenarios. Furthermore, identifiers of globally available multicast groups should be serializable anyway.
When a remote actor disconnects, libcppa prints on the console:
Connection reset by peer [errno = 104]
Could we get rid of this output? :-)
I see this periodically:
#3 <signal handler called>
#4 operator-> (this=0x2) at /root/work/libcppa/./cppa/intrusive_ptr.hpp:147
#5 cppa::remote_actor (peer=<error reading variable: Cannot access memory at address 0x2>) at /root/work/libcppa/src/unicast_network.cpp:78
#6 0x00007fab58663c0e in cppa::remote_actor (host=<optimized out>, port=<optimized out>) at /root/work/libcppa/src/unicast_network.cpp:104
#7 0x00007fab5b34a474 in img2::Service::scaleRpc (this=this@entry=0x7cf5a0, scaled=..., id=..., original=..., watermark=..., maxWidth=800, maxHeight=600,
version=version@entry=1) at src/service.cpp:193
scaleRpc is:
using namespace cppa; using std::chrono::seconds;
actor_ptr img2actor = remote_actor ("127.0.0.1", 1100); // Calling into "img2.scaleService".
sync_send (img2actor, atom("scale"), id, original, watermark, maxWidth, maxHeight, version) .await (
on_arg_match >> [&scaled](ScaleReply reply){
scaled = reply;
},
after (seconds (3)) >> [this]{log_error ("scaleRpc: timeout waiting for reply");}
);
I cannot get the examples to compile using Clang 3.2 (git) on Fedora Linux:
make[1]: Entering directory `/home/matthias/src/libcppa/build'
make[2]: Entering directory `/home/matthias/src/libcppa/build'
make[3]: Entering directory `/home/matthias/src/libcppa/build'
make[3]: Leaving directory `/home/matthias/src/libcppa/build'
[ 63%] Built target libcppa
make[3]: Entering directory `/home/matthias/src/libcppa/build'
make[3]: Leaving directory `/home/matthias/src/libcppa/build'
make[3]: Entering directory `/home/matthias/src/libcppa/build'
[ 64%] Building CXX object unit_testing/CMakeFiles/unit_tests.dir/ping_pong.cpp.o
/home/matthias/src/libcppa/unit_testing/ping_pong.cpp:46:24: error: no viable overloaded '='
init_state = (
~~~~~~~~~~ ^ ~
/home/matthias/src/libcppa/./cppa/behavior.hpp:61:15: note: candidate function not viable: no known conversion from 'match_expr<cppa::detail::projection_partial_function_pair<cppa::util::type_list<cppa::atom_value, int>, cppa::detail::projection<cppa::util::type_list<cppa::util::void_type, cppa::util::void_type>, const cppa::atom_value &, const int &>, cppa::tpartial_function<impl::<lambda at /home/matthias/src/libcppa/unit_testing/ping_pong.cpp:47:44>, cppa::detail::value_guard<cppa::util::type_list<cppa::atom_value> >, void, const cppa::atom_value &, int> >, cppa::detail::projection_partial_function_pair<cppa::util::type_list<cppa::anything>, cppa::detail::projection<util::empty_type_list>, cppa::tpartial_function<impl::<lambda at /home/matthias/src/libcppa/unit_testing/ping_pong.cpp:57:29>, cppa::detail::value_guard<cppa::util::type_list<> >, void, > > >' to 'cppa::behavior' for 1st argument;
behavior& operator=(behavior&&) = default;
^
/home/matthias/src/libcppa/./cppa/behavior.hpp:62:15: note: candidate function not viable: no known conversion from 'match_expr<cppa::detail::projection_partial_function_pair<cppa::util::type_list<cppa::atom_value, int>, cppa::detail::projection<cppa::util::type_list<cppa::util::void_type, cppa::util::void_type>, const cppa::atom_value &, const int &>, cppa::tpartial_function<impl::<lambda at /home/matthias/src/libcppa/unit_testing/ping_pong.cpp:47:44>, cppa::detail::value_guard<cppa::util::type_list<cppa::atom_value> >, void, const cppa::atom_value &, int> >, cppa::detail::projection_partial_function_pair<cppa::util::type_list<cppa::anything>, cppa::detail::projection<util::empty_type_list>, cppa::tpartial_function<impl::<lambda at /home/matthias/src/libcppa/unit_testing/ping_pong.cpp:57:29>, cppa::detail::value_guard<cppa::util::type_list<> >, void, > > >' to 'const cppa::behavior' for 1st argument;
behavior& operator=(const behavior&) = default;
^
/home/matthias/src/libcppa/unit_testing/ping_pong.cpp:91:24: error: no viable overloaded '='
init_state = (
~~~~~~~~~~ ^ ~
/home/matthias/src/libcppa/./cppa/behavior.hpp:61:15: note: candidate function not viable: no known conversion from 'match_expr<cppa::detail::projection_partial_function_pair<cppa::util::type_list<cppa::atom_value, int>, cppa::detail::projection<cppa::util::type_list<cppa::util::void_type, cppa::util::void_type>, const cppa::atom_value &, const int &>, cppa::tpartial_function<impl::<lambda at /home/matthias/src/libcppa/unit_testing/ping_pong.cpp:92:44>, cppa::detail::value_guard<cppa::util::type_list<cppa::atom_value> >, void, const cppa::atom_value &, int> >, cppa::detail::projection_partial_function_pair<cppa::util::type_list<cppa::anything>, cppa::detail::projection<util::empty_type_list>, cppa::tpartial_function<impl::<lambda at /home/matthias/src/libcppa/unit_testing/ping_pong.cpp:96:29>, cppa::detail::value_guard<cppa::util::type_list<> >, void, > > >' to 'cppa::behavior' for 1st argument;
behavior& operator=(behavior&&) = default;
^
/home/matthias/src/libcppa/./cppa/behavior.hpp:62:15: note: candidate function not viable: no known conversion from 'match_expr<cppa::detail::projection_partial_function_pair<cppa::util::type_list<cppa::atom_value, int>, cppa::detail::projection<cppa::util::type_list<cppa::util::void_type, cppa::util::void_type>, const cppa::atom_value &, const int &>, cppa::tpartial_function<impl::<lambda at /home/matthias/src/libcppa/unit_testing/ping_pong.cpp:92:44>, cppa::detail::value_guard<cppa::util::type_list<cppa::atom_value> >, void, const cppa::atom_value &, int> >, cppa::detail::projection_partial_function_pair<cppa::util::type_list<cppa::anything>, cppa::detail::projection<util::empty_type_list>, cppa::tpartial_function<impl::<lambda at /home/matthias/src/libcppa/unit_testing/ping_pong.cpp:96:29>, cppa::detail::value_guard<cppa::util::type_list<> >, void, > > >' to 'const cppa::behavior' for 1st argument;
behavior& operator=(const behavior&) = default;
^
2 errors generated.
make[3]: *** [unit_testing/CMakeFiles/unit_tests.dir/ping_pong.cpp.o] Error 1
make[3]: Leaving directory `/home/matthias/src/libcppa/build'
make[2]: *** [unit_testing/CMakeFiles/unit_tests.dir/all] Error 2
make[2]: Leaving directory `/home/matthias/src/libcppa/build'
make[1]: *** [all] Error 2
make[1]: Leaving directory `/home/matthias/src/libcppa/build'
make: *** [all] Error 2
^
Any ideas?
Provide unicode conversion to cppa::to_string and cppa::from_string as soon as unicode codecvt implementations are available in GCC.
Scheduled actors, both context-switching and event-based, shall not use blocking systems calls such as read/write/select. Thus, actors are of very limited use if it comes to IO, since only thread-mapped actors can do IO without starving others. We therefore need a message-based (?) asynchronous IO layer for actors.
I've got the following simple struct:
struct VertexDescriptor {
int id;
vector<vector<double>> spectra;
};
bool operator==( const VertexDescriptor& lhs, const VertexDescriptor& rhs ) {
return lhs.id == rhs.id;
}
I announce it as follows:
announce<VertexDescriptor>(&VertexDescriptor::id, &VertexDescriptor::spectra);
However, at runtime I get a runtime_error:
terminate called after throwing an instance of 'std::runtime_error'
what(): uniform_type_info::by_type_info(): std::vector<double,std::allocator> is an unknown typeid name
It seems that even though the type is announced, libcppa doesn't know about it. The only difference between this and one of the examples is that I'm using a vector of vectors of primitives. Is the announce mechanism not capable of handling this? Would one have to write their own serializer and deserializer for this case?
On Linux, remote communication does not work correctly. The server side, which publishes actors, dies with a SIGPIPE
:
#1 0x00007ffff66b3d39 in cppa::detail::ipv4_io_stream::write (this=0x7fffe8000dd0, vbuf=0x7ffff3a3c9fc, len=4) at /home/matthias/libcppa/src/ipv4_io_stream.cpp:116
#2 0x00007ffff66c1697 in cppa::detail::po_doorman::read_and_continue (this=0x7fffe8000980) at /home/matthias/libcppa/src/post_office.cpp:481
#3 0x00007ffff66bf328 in cppa::detail::post_office::operator() (this=0x7ffff3a3cc90, input_fd=8, q=...) at /home/matthias/libcppa/src/post_office.cpp:595
#4 0x00007ffff66bf5a1 in cppa::detail::post_office_loop (input_fd=8, q=...) at /home/matthias/libcppa/src/post_office.cpp:627
#5 0x00007ffff66ba14c in operator() (__closure=0x61a200) at /home/matthias/libcppa/src/network_manager.cpp:74
#6 0x00007ffff66bc392 in std::_Bind_simple<{anonymous}::network_manager_impl::start()::<lambda()>()>::_M_invoke<>(std::_Index_tuple<>) (this=0x61a200)
at /home/matthias/opt/gcc/lib/gcc/x86_64-redhat-linux/4.7.0/../../../../include/c++/4.7.0/functional:1598
#7 0x00007ffff66bc237 in std::_Bind_simple<{anonymous}::network_manager_impl::start()::<lambda()>()>::operator()(void) (this=0x61a200)
at /home/matthias/opt/gcc/lib/gcc/x86_64-redhat-linux/4.7.0/../../../../include/c++/4.7.0/functional:1586
#8 0x00007ffff66bc15e in std::thread::_Impl<std::_Bind_simple<{anonymous}::network_manager_impl::start()::<lambda()>()> >::_M_run(void) (this=0x61a1e8)
at /home/matthias/opt/gcc/lib/gcc/x86_64-redhat-linux/4.7.0/../../../../include/c++/4.7.0/thread:115
#9 0x00007ffff54666c0 in std::(anonymous namespace)::execute_native_thread_routine (__p=<optimized out>) at ../../../../../libstdc++-v3/src/c++11/thread.cc:73
#10 0x0000003191207b31 in start_thread () from /lib64/libpthread.so.0
#11 0x0000003190edfd2d in clone () from /lib64/libc.so.6
at line 116 where you use ::send
:
112 void ipv4_io_stream::write(const void* vbuf, size_t len) {
113 auto buf = reinterpret_cast<const char*>(vbuf);
114 size_t written = 0;
115 while (written < len) {
116 auto send_result = ::send(m_fd, buf + written, len - written, 0);
117 handle_syscall_result(send_result, len - written, true);
118 written += static_cast<size_t>(send_result);
I cannot reproduce this on Darwin. The unit tests pass on both platforms.
On the plus side, issue #49 seems to have disappeared, at least on the Mac. Once this showstopper disappears on Linux, we might be able to close #49 in one shot.
Tests pass with Clang, but with GCC 4.7 installed via MacPorts, I get this:
Total Test time (real) = 3.21 sec
The following tests FAILED:
1 - unit_tests (OTHER_FAULT)
Libcppa compiles fine on a 64-bit Linux and the most recent Clang. However, the unit tests do not succeed:
*** glibc detected *** /home/matthias/src/libcppa/build/bin/unit_tests: free(): invalid pointer: 0x00007fff7bd1bc68 ***
======= Backtrace: =========
/lib64/libc.so.6[0x3190e7703a]
/opt/llvm/lib/libcxxrt.so(__cxa_demangle+0xcc)[0x7f0e80dbd4c6]
/home/matthias/src/libcppa/build/lib/libcppa.so.0(_ZN4cppa6detail8demangleEPKc+0x50)[0x7f0e80a337c0]
/home/matthias/src/libcppa/build/lib/libcppa.so.0(+0x1a9887)[0x7f0e80ac3887]
/home/matthias/src/libcppa/build/lib/libcppa.so.0(+0x1a39b4)[0x7f0e80abd9b4]
/home/matthias/src/libcppa/build/lib/libcppa.so.0(_ZN4cppa6detail15to_uniform_nameERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE+0x5bd)[0x7f0e80ab7cdd]
/home/matthias/src/libcppa/build/lib/libcppa.so.0(_ZN4cppa6detail15to_uniform_nameERKSt9type_info+0x3c)[0x7f0e80ac34bc]
/home/matthias/src/libcppa/build/lib/libcppa.so.0(_ZN4cppa6detail30default_uniform_type_info_implIaEC2Ev+0x33)[0x7f0e80b2dfd3]
/home/matthias/src/libcppa/build/lib/libcppa.so.0(_ZN4cppa6detail9int_tinfoIaEC2Ev+0x1f)[0x7f0e80b2df7f]
/home/matthias/src/libcppa/build/lib/libcppa.so.0(_ZN4cppa6detail9int_tinfoIaEC1Ev+0x15)[0x7f0e80b2df55]
/home/matthias/src/libcppa/build/lib/libcppa.so.0(_ZN4cppa6detail28uniform_type_info_map_helper10insert_intIaEEvv+0x59)[0x7f0e80ad3a19]
/home/matthias/src/libcppa/build/lib/libcppa.so.0(_ZN4cppa6detail21uniform_type_info_mapC2Ev+0x17b)[0x7f0e80acc19b]
/home/matthias/src/libcppa/build/lib/libcppa.so.0(+0x17fc06)[0x7f0e80a99c06]
/home/matthias/src/libcppa/build/lib/libcppa.so.0(_ZN4cppa6detail17singleton_manager25get_uniform_type_info_mapEv+0x15)[0x7f0e80a99b15]
/home/matthias/src/libcppa/build/lib/libcppa.so.0(+0x1b6fd9)[0x7f0e80ad0fd9]
/home/matthias/src/libcppa/build/lib/libcppa.so.0(_ZN4cppa17uniform_type_info4fromERKSt9type_info+0x17)[0x7f0e80ad1117]
/home/matthias/src/libcppa/build/lib/libcppa.so.0(_ZN4cppa14uniform_typeidERKSt9type_info+0x15)[0x7f0e80ad1785]
/home/matthias/src/libcppa/build/bin/unit_tests(_ZN4cppa6detail7ta_utilILNS0_14type_info_implE1ELb1ENS_13intrusive_ptrINS_19process_informationEEEE3getEv+0x14)[0x6ad424]
/home/matthias/src/libcppa/build/lib/libcppa.so.0(_ZN4cppa6detail16types_array_implILb1EJNS_13intrusive_ptrINS_19process_informationEEENS0_17addressed_messageEEEC2Ev+0x19)[0x7f0e80a0ff89]
/home/matthias/src/libcppa/build/lib/libcppa.so.0(_ZN4cppa6detail11types_arrayIJNS_13intrusive_ptrINS_19process_informationEEENS0_17addressed_messageEEEC2Ev+0x15)[0x7f0e80a0ff65]
/home/matthias/src/libcppa/build/lib/libcppa.so.0(_ZN4cppa6detail11types_arrayIJNS_13intrusive_ptrINS_19process_informationEEENS0_17addressed_messageEEEC1Ev+0x15)[0x7f0e80a0b2d5]
/home/matthias/src/libcppa/build/lib/libcppa.so.0(+0xe98c0)[0x7f0e80a038c0]
/home/matthias/src/libcppa/build/lib/libcppa.so.0(+0xe9939)[0x7f0e80a03939]
/lib64/ld-linux-x86-64.so.2[0x3190a0e2d6]
/lib64/ld-linux-x86-64.so.2[0x3190a0e3b3]
/lib64/ld-linux-x86-64.so.2[0x3190a016ea]
======= Memory map: ========
00400000-0082d000 r-xp 00000000 fd:00 262062 /home/matthias/src/libcppa/build/bin/unit_tests
00a2d000-00a2e000 rw-p 0042d000 fd:00 262062 /home/matthias/src/libcppa/build/bin/unit_tests
00a2e000-00a2f000 rw-p 00000000 00:00 0
00fac000-00fcd000 rw-p 00000000 00:00 0 [heap]
3190a00000-3190a1f000 r-xp 00000000 fd:00 1054 /lib64/ld-2.14.so
3190c1e000-3190c1f000 r--p 0001e000 fd:00 1054 /lib64/ld-2.14.so
3190c1f000-3190c20000 rw-p 0001f000 fd:00 1054 /lib64/ld-2.14.so
3190c20000-3190c21000 rw-p 00000000 00:00 0
3190e00000-3190f8f000 r-xp 00000000 fd:00 1058 /lib64/libc-2.14.so
3190f8f000-319118f000 ---p 0018f000 fd:00 1058 /lib64/libc-2.14.so
319118f000-3191193000 r--p 0018f000 fd:00 1058 /lib64/libc-2.14.so
3191193000-3191194000 rw-p 00193000 fd:00 1058 /lib64/libc-2.14.so
3191194000-319119a000 rw-p 00000000 00:00 0
3191200000-3191216000 r-xp 00000000 fd:00 1061 /lib64/libpthread-2.14.so
3191216000-3191415000 ---p 00016000 fd:00 1061 /lib64/libpthread-2.14.so
3191415000-3191416000 r--p 00015000 fd:00 1061 /lib64/libpthread-2.14.so
3191416000-3191417000 rw-p 00016000 fd:00 1061 /lib64/libpthread-2.14.so
3191417000-319141b000 rw-p 00000000 00:00 0
3191600000-3191683000 r-xp 00000000 fd:00 461 /lib64/libm-2.14.so
3191683000-3191882000 ---p 00083000 fd:00 461 /lib64/libm-2.14.so
3191882000-3191883000 r--p 00082000 fd:00 461 /lib64/libm-2.14.so
3191883000-3191884000 rw-p 00083000 fd:00 461 /lib64/libm-2.14.so
3191a00000-3191a02000 r-xp 00000000 fd:00 1099 /lib64/libdl-2.14.so
3191a02000-3191c02000 ---p 00002000 fd:00 1099 /lib64/libdl-2.14.so
3191c02000-3191c03000 r--p 00002000 fd:00 1099 /lib64/libdl-2.14.so
3191c03000-3191c04000 rw-p 00003000 fd:00 1099 /lib64/libdl-2.14.so
3191e00000-3191e07000 r-xp 00000000 fd:00 1068 /lib64/librt-2.14.so
3191e07000-3192006000 ---p 00007000 fd:00 1068 /lib64/librt-2.14.so
3192006000-3192007000 r--p 00006000 fd:00 1068 /lib64/librt-2.14.so
3192007000-3192008000 rw-p 00007000 fd:00 1068 /lib64/librt-2.14.so
3192600000-3192615000 r-xp 00000000 fd:00 1182 /lib64/libgcc_s-4.6.1-20110908.so.1
3192615000-3192814000 ---p 00015000 fd:00 1182 /lib64/libgcc_s-4.6.1-20110908.so.1
3192814000-3192815000 rw-p 00014000 fd:00 1182 /lib64/libgcc_s-4.6.1-20110908.so.1
319aa00000-319aae8000 r-xp 00000000 fd:00 265025 /usr/lib64/libstdc++.so.6.0.16
319aae8000-319ace8000 ---p 000e8000 fd:00 265025 /usr/lib64/libstdc++.so.6.0.16
319ace8000-319acf0000 r--p 000e8000 fd:00 265025 /usr/lib64/libstdc++.so.6.0.16
319acf0000-319acf2000 rw-p 000f0000 fd:00 265025 /usr/lib64/libstdc++.so.6.0.16
319acf2000-319ad07000 rw-p 00000000 00:00 0
7f0e80046000-7f0e8004b000 rw-p 00000000 00:00 0
7f0e8004b000-7f0e8004f000 r-xp 00000000 fd:00 25102843 /home/matthias/opt/clang/lib/libboost_system.so.1.50.0
7f0e8004f000-7f0e8024e000 ---p 00004000 fd:00 25102843 /home/matthias/opt/clang/lib/libboost_system.so.1.50.0
7f0e8024e000-7f0e8024f000 rw-p 00003000 fd:00 25102843 /home/matthias/opt/clang/lib/libboost_system.so.1.50.0
7f0e8024f000-7f0e80256000 r-xp 00000000 fd:00 25102837 /home/matthias/opt/clang/lib/libboost_chrono.so.1.50.0
7f0e80256000-7f0e80455000 ---p 00007000 fd:00 25102837 /home/matthias/opt/clang/lib/libboost_chrono.so.1.50.0
7f0e80455000-7f0e80456000 rw-p 00006000 fd:00 25102837 /home/matthias/opt/clang/lib/libboost_chrono.so.1.50.0
7f0e80456000-7f0e80458000 rw-p 00000000 00:00 0
7f0e80458000-7f0e804ee000 r-xp 00000000 fd:00 24424978 /opt/llvm/lib/libc++.so.1.0
7f0e804ee000-7f0e806ee000 ---p 00096000 fd:00 24424978 /opt/llvm/lib/libc++.so.1.0
7f0e806ee000-7f0e806f4000 rw-p 00096000 fd:00 24424978 /opt/llvm/lib/libc++.so.1.0
7f0e806f4000-7f0e806f7000 rw-p 00000000 00:00 0
7f0e806f7000-7f0e80717000 r-xp 00000000 fd:00 25102839 /home/matthias/opt/clang/lib/libboost_thread.so.1.50.0
7f0e80717000-7f0e80917000 ---p 00020000 fd:00 25102839 /home/matthias/opt/clang/lib/libboost_thread.so.1.50.0
7f0e80917000-7f0e80919000 rw-p 00020000 fd:00 25102839 /home/matthias/opt/clang/lib/libboost_thread.so.1.50.0
7f0e80919000-7f0e8091a000 rw-p 00000000 00:00 0
7f0e8091a000-7f0e80ba3000 r-xp 00000000 fd:00 178371 /home/matthias/src/libcppa/build/lib/libcppa.so.0.2.0
7f0e80ba3000-7f0e80da3000 ---p 00289000 fd:00 178371 /home/matthias/src/libcppa/build/lib/libcppa.so.0.2.0
7f0e80da3000-7f0e80db1000 rw-p 00289000 fd:00 178371 /home/matthias/src/libcppa/build/lib/libcppa.so.0.2.0
7f0e80db1000-7f0e80db2000 rw-p 00000000 00:00 0
7f0e80db2000-7f0e80dca000 r-xp 00000000 fd:00 24424979 /opt/llvm/lib/libcxxrt.so.1.0
7f0e80dca000-7f0e80fc9000 ---p 00018000 fd:00 24424979 /opt/llvm/lib/libcxxrt.so.1.0
7f0e80fc9000-7f0e80fcb000 rw-p 00017000 fd:00 24424979 /opt/llvm/lib/libcxxrt.so.1.0
7f0e80fcb000-7f0e80fd0000 rw-p 00000000 00:00 0
7f0e80fee000-7f0e80ff0000 rw-p 00000000 00:00 0
7fff7bcfc000-7fff7bd1c000 rwxp 00000000 00:00 0 [stack]
7fff7bd1c000-7fff7bd1d000 rw-p 00000000 00:00 0
7fff7bd50000-7fff7bd51000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
Here is a stack trace when running the binary unit_tests
in the debugger:
#0 0x0000003190e352d5 in raise () from /lib64/libc.so.6
#1 0x0000003190e36beb in abort () from /lib64/libc.so.6
#2 0x0000003190e70bce in __libc_message () from /lib64/libc.so.6
#3 0x0000003190e7703a in malloc_printerr () from /lib64/libc.so.6
#4 0x00007ffff7dcb4c6 in __cxa_demangle () from /opt/llvm/lib/libcxxrt.so
#5 0x00007ffff7a417c0 in cppa::detail::demangle (decorated=0x7ffff7dd43f4 "Ds") at /home/matthias/src/libcppa/src/demangle.cpp:47
#6 0x00007ffff7ad1887 in (anonymous namespace)::demangled<char16_t> () at /home/matthias/src/libcppa/src/to_uniform_name.cpp:74
#7 0x00007ffff7acb9b4 in (anonymous namespace)::to_uniform_name_impl<std::__1::__wrap_iter<char const*> > (begin=..., end=..., first_run=true) at /home/matthias/src/libcppa/src/to_uniform_name.cpp:109
#8 0x00007ffff7ac5cdd in cppa::detail::to_uniform_name (dname=...) at /home/matthias/src/libcppa/src/to_uniform_name.cpp:228
#9 0x00007ffff7ad14bc in cppa::detail::to_uniform_name (tinfo=...) at /home/matthias/src/libcppa/src/to_uniform_name.cpp:243
#10 0x00007ffff7b3bfd3 in cppa::detail::default_uniform_type_info_impl<signed char>::default_uniform_type_info_impl (this=0xa2f620) at /home/matthias/src/libcppa/./cppa/detail/default_uniform_type_info_impl.hpp:57
#11 0x00007ffff7b3bf7f in cppa::detail::int_tinfo<signed char>::int_tinfo (this=0xa2f620) at /home/matthias/src/libcppa/src/uniform_type_info.cpp:606
#12 0x00007ffff7b3bf55 in cppa::detail::int_tinfo<signed char>::int_tinfo (this=0xa2f620) at /home/matthias/src/libcppa/src/uniform_type_info.cpp:606
#13 0x00007ffff7ae1a19 in cppa::detail::uniform_type_info_map_helper::insert_int<signed char> (this=0x7fffffffd0f8) at /home/matthias/src/libcppa/src/uniform_type_info.cpp:630
#14 0x00007ffff7ada19b in cppa::detail::uniform_type_info_map::uniform_type_info_map (this=0xa2f0d0) at /home/matthias/src/libcppa/src/uniform_type_info.cpp:671
#15 0x00007ffff7aa7c06 in (anonymous namespace)::lazy_get<cppa::detail::uniform_type_info_map> (ptr=..., register_atexit_fun=true) at /home/matthias/src/libcppa/src/singleton_manager.cpp:103
#16 0x00007ffff7aa7b15 in cppa::detail::singleton_manager::get_uniform_type_info_map () at /home/matthias/src/libcppa/src/singleton_manager.cpp:136
#17 0x00007ffff7adefd9 in cppa::detail::(anonymous namespace)::uti_map () at /home/matthias/src/libcppa/src/uniform_type_info.cpp:70
#18 0x00007ffff7adf117 in cppa::uniform_type_info::from (tinf=...) at /home/matthias/src/libcppa/src/uniform_type_info.cpp:766
#19 0x00007ffff7adf785 in cppa::uniform_typeid (tinfo=...) at /home/matthias/src/libcppa/src/uniform_type_info.cpp:795
#20 0x00000000006ad424 in cppa::detail::ta_util<(cppa::detail::type_info_impl)1, true, cppa::intrusive_ptr<cppa::process_information> >::get () at /home/matthias/src/libcppa/./cppa/detail/types_array.hpp:66
#21 0x00007ffff7a1df89 in _ZN4cppa6detail16types_array_implILb1EJNS_13intrusive_ptrINS_19process_informationEEENS0_17addressed_messageEEEC2Ev (this=0x7ffff7dbee00) at /home/matthias/src/libcppa/./cppa/detail/types_array.hpp:90
#22 0x00007ffff7a1df65 in _ZN4cppa6detail11types_arrayIJNS_13intrusive_ptrINS_19process_informationEEENS0_17addressed_messageEEEC2Ev (this=0x7ffff7dbee00) at /home/matthias/src/libcppa/./cppa/detail/types_array.hpp:157
#23 0x00007ffff7a192d5 in _ZN4cppa6detail11types_arrayIJNS_13intrusive_ptrINS_19process_informationEEENS0_17addressed_messageEEEC1Ev (this=0x7ffff7dbee00) at /home/matthias/src/libcppa/./cppa/detail/types_array.hpp:157
#24 0x00007ffff7a118c0 in __cxx_global_var_init () from /home/matthias/src/libcppa/build/lib/libcppa.so.0
#25 0x00007ffff7a11939 in global constructors keyed to a () from /home/matthias/src/libcppa/build/lib/libcppa.so.0
#26 0x0000003190a0e2d6 in call_init.part.0 () from /lib64/ld-linux-x86-64.so.2
#27 0x0000003190a0e3b3 in _dl_init_internal () from /lib64/ld-linux-x86-64.so.2
#28 0x0000003190a016ea in _dl_start_user () from /lib64/ld-linux-x86-64.so.2
Let me know what information you need to track this down. This sort of segfault occurs for all binaries created during the build:
While I was on a mission to compare Clang and GCC benchmarks, I encountered a crash when running the Mixed Case benchmark.
GCC:
./bin/mixed_case event-based 10 10 42 1 14.96s user 0.17s system 188% cpu 8.038 total
Clang:
terminate called after throwing an instance of 'std::runtime_error'
what(): uniform_type_info::by_type_info(): std::__1::basic_string<@i8,std::__1::char_traits<@i8>,std::__1::allocator<@i8>> is an unknown typeid name
Stack trace:
#0 0x00007fff8e43582a in __kill () from /usr/lib/system/libsystem_kernel.dylib
#1 0x00007fff8ae43a9c in abort () from /usr/lib/system/libsystem_c.dylib
#2 0x00000001008f45d5 in __gnu_cxx::__verbose_terminate_handler() () from /opt/local/lib/gcc47/libstdc++.6.dylib
#3 0x00000001008f23b8 in __cxxabiv1::__terminate(void (*)()) () from /opt/local/lib/gcc47/libstdc++.6.dylib
#4 0x00000001008f2403 in std::terminate() () from /opt/local/lib/gcc47/libstdc++.6.dylib
#5 0x00000001008f262e in __cxa_throw () from /opt/local/lib/gcc47/libstdc++.6.dylib
#6 0x00000001002d9c5c in ?? () from /Users/mavam/code/root/lib/libcppa.0.dylib
#7 0x00000001002d9e59 in ?? () from /Users/mavam/code/root/lib/libcppa.0.dylib
#8 0x0000000100015073 in cppa::detail::ta_util<(cppa::detail::type_info_impl)1, true, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::get() ()
#9 0x000000010003bd49 in cppa::detail::types_array_impl<true, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::types_array_impl() ()
#10 0x000000010003bd25 in cppa::detail::types_array<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::types_array() ()
#11 0x0000000100014fb5 in cppa::detail::types_array<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::types_array() ()
#12 0x000000010004a440 in __cxx_global_var_init21 ()
#13 0x000000010004a4f0 in global constructors keyed to a ()
I get segfaults when trying to get announce_example_1 running on my Ubuntu box.
I've tracked the problem down to indeterminate object destruction order.
Particularly, when exit() is called, thread pool scheduler, scheduled actors and existing actors themselves are destroyed.
During destruction each actor removes itself from ID map.
However, by the time this happens, ID map itself is already destroyed.
I think it is not possible to guarantee that static objects are automatically destroyed in particular order,
so there is a need in manual global object management.
For now I've implemented a work-around for this particular problem:
(https://github.com/mephi42/libcppa/commit/ccd05eed72f784e8f9ba3e079079cf47f7464784)
Note that it does not free actors_registry singleton (this definitely needs to be fixed in future)
There is one more crash type into which I didn't look yet, but it must be similar.
Here is the relevant piece of Valgrind trace:
==28198== Memcheck, a memory error detector
==28198== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==28198== Using Valgrind-3.6.0.SVN-Debian and LibVEX; rerun with -h for copyright info
==28198== Command: ./cppa
==28198==
==28198== Thread 2:
==28198== Invalid read of size 4
==28198== at 0x406A8E5: cppa::detail::get_actor_proxy_cache() (sp_counted_base_gcc_x86.hpp:66)
==28198== by 0x407FC44: cppa::detail::(anonymous namespace)::post_office_loop(int) (post_office.cpp:668)
==28198== by 0x4082255: boost::detail::thread_data<boost::_bi::bind_t<void, void (*)(int), boost::bi::list1<boost::bi::value > > >::run() (bind.hpp:253)
==28198== by 0x437296D: start_thread (pthread_create.c:300)
==28198== by 0x42E0A4D: clone (clone.S:130)
==28198== Address 0x43abad4 is 4 bytes inside a block of size 20 free'd
==28198== at 0x4024851: operator delete(void) (vg_replace_malloc.c:387)
==28198== by 0x406B495: boost::detail::sp_counted_impl_pdboost::thread_specific_ptr<cppa::detail::actor_proxy_cache::delete_data, boost::detail::do_heap_deleteboost::thread_specific_ptrcppa::detail::actor_proxy_cache::delete_data >::~sp_counted_impl_pd() (sp_counted_impl.hpp:122)
==28198== by 0x4066C03: ??? (in /usr/local/lib/libcppa.so.0.0.0)
==28198== by 0x40B248F: ??? (in /usr/local/lib/libcppa.so.0.0.0)
==28198== by 0x400E215: _dl_fini (dl-fini.c:248)
==28198== by 0x42421BE: __run_exit_handlers (exit.c:78)
==28198== by 0x424222E: exit (exit.c:100)
==28198== by 0x804B6C5: _ZZ4mainENKUlvE_clEv (in /home/beep/cppa)
==28198== by 0x804C5C6: ZN4cppa6detail13invoke_helperILj0EZ4mainEUlvE_vNS_10tuple_viewIINS_10atom_valueEEEENS_4util9type_listIIEEEIEE1_ERS2_RKS5 (in /home/beep/cppa)
==28198== by 0x804C561: ZN4cppa6detail11invoke_implILb0EZ4mainEUlvE_NS_10tuple_viewIINS_10atom_valueEEEEE1_ERS2_RKS5 (in /home/beep/cppa)
==28198== by 0x804C4B5: ZN4cppa6invokeIZ4mainEUlvE_NS_10tuple_viewIINS_10atom_valueEEEEEENS_6detail11invoke_implIXsrSt11is_functionINSt14remove_pointerIT_E4typeEE5valueES9_T0_E11result_typeES9_RKSD (in /home/beep/cppa)
==28198== by 0x804C78F: _ZZNK4cppa6detail14invokable_implINS_10tuple_viewIINS_10atom_valueEEEESt8functionIFbRKNS_9any_tupleEPSt6vectorIjSaIjEEEEZ4mainEUlvE_E16get_intermediateES8_EN5iimpl6invokeEv (in /home/beep/cppa)
In the same vein of <iosfwd>
of the standard library, does (or could) libcppa provide an include that forward-declares heavily used data structures, such as actor_ptr
, sb_actor<T>
, etc.?
Hi,
I'm getting the below build error when trying to build libcppa. I'm running MacOS 10.5.8 on an Intel Core 2 Duo and using gcc 4.7.1 from MacPorts.
I have my own build of Boost 1.49 on my system. Should I point libcppa to use that?
/opt/local/bin/c++ -Dlibcppa_EXPORTS -std=c++11 -Wextra -Wall -pedantic -O3 -DNDEBUG -fPIC -I/Users/pknotz/workspace/libcppa/. -I/usr/local/boost-1.49.0/include -I/Users/pknotz/workspace/libcppa/third_party/boost_context/include -o CMakeFiles/libcppa.dir/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.o -c /Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:45:bad register name `%rbx'
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:46:bad register name `%r12'
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:47:bad register name `%r13'
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:48:bad register name `%r14'
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:49:bad register name `%r15'
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:50:bad register name `%rbp'
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:52:bad register name `%rcx'
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:55:bad register name `%rdi)'
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:56:bad register name `%rdi)'
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:58:bad register name `%rsi)'
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:59:bad register name `%rsi)'
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:62:bad register name `%rsp)'
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:63:bad register name `%rax'
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:64:bad register name `%rsp)'
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:65:bad register name `%rax'
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:67:bad register name `%rsi)'
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:68:bad register name `%rsi)'
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:69:bad register name `%rsi)'
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:70:bad register name `%rsi)'
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:71:bad register name `%rsi)'
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:72:bad register name `%rsi)'
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:74:bad register name `%rsi)'
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:75:bad register name `%rsi)'
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:77:bad register name `%rdx'
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:78:bad register name `%rdx'
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:80:bad register name `%rcx'
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:86:bad register name `%rdi'
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:87:bad register name `%rsi'
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:88:bad register name `%rdi)'
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:90:bad register name `%rdi'
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:91:bad register name `%rdx'
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:94:bad register name `%rax'
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:95:bad register name `%rdi'
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:97:bad register name `%rdx)'
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:98:bad register name `%rdx'
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:100:bad register name `%rdi)'
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:101:bad register name `%rdi)'
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:103:`finish(%rip)' is not a valid base/index expression
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:104:bad register name `%rcx'
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:106:bad register name `%rax'
/Users/pknotz/workspace/libcppa/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.S:110:bad register name `%rdi'
make[2]: *** [CMakeFiles/libcppa.dir/third_party/boost_context/src/asm/fcontext_x86_64_sysv_macho_gas.o] Error 1
make[1]: *** [CMakeFiles/libcppa.dir/all] Error 2
make: *** [all] Error 2
''''
--- from mephi42 ---
[ERROR] In file included from target/nar/cppa-0.1-noarch/include/cppa/on.hpp:12:0, [ERROR] from target/nar/cppa-0.1-noarch/include/cppa/cppa.hpp:36, [ERROR] from src/main/include/libd2assist/actors/Cli.hpp:8, [ERROR] from src/main/c++/Core.cpp:9: [ERROR] target/nar/cppa-0.1-noarch/include/cppa/util/duration.hpp: In constructor โconstexpr cppa::util::duration::duration(std::chrono::duration<_Rep, _Period>) [with Rep = long long int, Period = std::ratio<1ll, 1000000ll>]โ: [ERROR] target/nar/cppa-0.1-noarch/include/cppa/on.hpp:200:32: instantiated from โconstexpr cppa::detail::timed_invoke_rule_builder cppa::after(const std::chrono::duration<_Rep, _Period>&) [with Rep = long long int, Period = std::ratio<1ll, 1000000ll>]โ [ERROR] src/main/c++/Core.cpp:236:86: instantiated from here [WARNING] target/nar/cppa-0.1-noarch/include/cppa/util/duration.hpp:46:69: warning: conversion to โuint32_t {aka unsigned int}โ from โstd::chrono::duration >::rep {aka long long int}โ may alter its value [-Wconversion]
Thank you for implementing timeouts! I re-implemented my code with new cppa::after infrastructure and it works.
However, from time to time I run into segfaults during startup.
Valgrind says:
[ERROR] ==32369== Thread 6: [ERROR] ==32369== Conditional jump or move depends on uninitialised value(s) [ERROR] ==32369== at 0x4564F3A: pthread_mutex_lock (pthread_mutex_lock.c:51) [ERROR] ==32369== by 0x44DDBA5: pthread_mutex_lock (forward.c:182) [ERROR] ==32369== by 0x42A8C16: cppa::detail::thread_pool_scheduler::worker_loop(cppa::detail::thread_pool_scheduler::worker*) (gthr-default.h:742) [ERROR] ==32369== by 0x42AA45F: std::thread::_Impl >::_M_run() (functional:1287) [ERROR] ==32369== by 0x44D0A4D: clone (clone.S:130) [ERROR] ==32369== [ERROR] ==32369== Conditional jump or move depends on uninitialised value(s) [ERROR] ==32369== at 0x4564F48: pthread_mutex_lock (pthread_mutex_lock.c:56) [ERROR] ==32369== by 0x44DDBA5: pthread_mutex_lock (forward.c:182) [ERROR] ==32369== by 0x42A8C16: cppa::detail::thread_pool_scheduler::worker_loop(cppa::detail::thread_pool_scheduler::worker*) (gthr-default.h:742) [ERROR] ==32369== by 0x42AA45F: std::thread::_Impl >::_M_run() (functional:1287) [ERROR] ==32369== by 0x44D0A4D: clone (clone.S:130) [ERROR] ==32369== [ERROR] ==32369== Conditional jump or move depends on uninitialised value(s) [ERROR] ==32369== at 0x4564F5B: pthread_mutex_lock (pthread_mutex_lock.c:61) [ERROR] ==32369== by 0x44DDBA5: pthread_mutex_lock (forward.c:182) [ERROR] ==32369== by 0x42A8C16: cppa::detail::thread_pool_scheduler::worker_loop(cppa::detail::thread_pool_scheduler::worker*) (gthr-default.h:742) [ERROR] ==32369== by 0x42AA45F: std::thread::_Impl >::_M_run() (functional:1287) [ERROR] ==32369== by 0x44D0A4D: clone (clone.S:130) [ERROR] ==32369== [ERROR] ==32369== Conditional jump or move depends on uninitialised value(s) [ERROR] ==32369== at 0x4564F66: pthread_mutex_lock (pthread_mutex_lock.c:62) [ERROR] ==32369== by 0x44DDBA5: pthread_mutex_lock (forward.c:182) [ERROR] ==32369== by 0x42A8C16: cppa::detail::thread_pool_scheduler::worker_loop(cppa::detail::thread_pool_scheduler::worker*) (gthr-default.h:742) [ERROR] ==32369== by 0x42AA45F: std::thread::_Impl >::_M_run() (functional:1287) [ERROR] ==32369== by 0x44D0A4D: clone (clone.S:130) [ERROR] ==32369== [ERROR] ==32369== Conditional jump or move depends on uninitialised value(s) [ERROR] ==32369== at 0x4566F94: pthread_cond_wait@@GLIBC_2.3.2 (pthread_cond_wait.S:56) [ERROR] ==32369== by 0x43593D4: std::condition_variable::wait(std::unique_lock&) (gthr-default.h:846) [ERROR] ==32369== by 0x42A8E6A: cppa::detail::thread_pool_scheduler::worker_loop(cppa::detail::thread_pool_scheduler::worker*) (thread_pool_scheduler.cpp:59) [ERROR] ==32369== by 0x42AA45F: std::thread::_Impl >::_M_run() (functional:1287) [ERROR] ==32369== by 0x44D0A4D: clone (clone.S:130) [ERROR] ==32369== [ERROR] ==32369== Conditional jump or move depends on uninitialised value(s) [ERROR] ==32369== at 0x4566FA2: pthread_cond_wait@@GLIBC_2.3.2 (pthread_cond_wait.S:62) [ERROR] ==32369== by 0x43593D4: std::condition_variable::wait(std::unique_lock&) (gthr-default.h:846) [ERROR] ==32369== by 0x42A8E6A: cppa::detail::thread_pool_scheduler::worker_loop(cppa::detail::thread_pool_scheduler::worker*) (thread_pool_scheduler.cpp:59) [ERROR] ==32369== by 0x42AA45F: std::thread::_Impl >::_M_run() (functional:1287) [ERROR] ==32369== by 0x44D0A4D: clone (clone.S:130) [ERROR] ==32369== [ERROR] ==32369== Conditional jump or move depends on uninitialised value(s) [ERROR] ==32369== at 0x4566327: __pthread_mutex_unlock_usercnt (pthread_mutex_unlock.c:38) [ERROR] ==32369== by 0x4566FAD: pthread_cond_wait@@GLIBC_2.3.2 (pthread_cond_wait.S:67) [ERROR] ==32369== by 0x43593D4: std::condition_variable::wait(std::unique_lock&) (gthr-default.h:846) [ERROR] ==32369== by 0x42A8E6A: cppa::detail::thread_pool_scheduler::worker_loop(cppa::detail::thread_pool_scheduler::worker*) (thread_pool_scheduler.cpp:59) [ERROR] ==32369== by 0x42AA45F: std::thread::_Impl >::_M_run() (functional:1287) [ERROR] ==32369== by 0x44D0A4D: clone (clone.S:130) [ERROR] ==32369== [ERROR] ==32369== Conditional jump or move depends on uninitialised value(s) [ERROR] ==32369== at 0x456632B: __pthread_mutex_unlock_usercnt (pthread_mutex_unlock.c:41) [ERROR] ==32369== by 0x4566FAD: pthread_cond_wait@@GLIBC_2.3.2 (pthread_cond_wait.S:67) [ERROR] ==32369== by 0x43593D4: std::condition_variable::wait(std::unique_lock&) (gthr-default.h:846) [ERROR] ==32369== by 0x42A8E6A: cppa::detail::thread_pool_scheduler::worker_loop(cppa::detail::thread_pool_scheduler::worker*) (thread_pool_scheduler.cpp:59) [ERROR] ==32369== by 0x42AA45F: std::thread::_Impl >::_M_run() (functional:1287) [ERROR] ==32369== by 0x44D0A4D: clone (clone.S:130) [ERROR] ==32369== [ERROR] ==32369== Syscall param futex(val) contains uninitialised byte(s) [ERROR] ==32369== at 0x4567015: pthread_cond_wait@@GLIBC_2.3.2 (pthread_cond_wait.S:123) [ERROR] ==32369== by 0x43593D4: std::condition_variable::wait(std::unique_lock&) (gthr-default.h:846) [ERROR] ==32369== by 0x42A8E6A: cppa::detail::thread_pool_scheduler::worker_loop(cppa::detail::thread_pool_scheduler::worker*) (thread_pool_scheduler.cpp:59) [ERROR] ==32369== by 0x42AA45F: std::thread::_Impl >::_M_run() (functional:1287) [ERROR] ==32369== by 0x44D0A4D: clone (clone.S:130) [ERROR] ==32369== [ERROR] ==32369== Syscall param futex(futex) points to uninitialised byte(s) [ERROR] ==32369== at 0x4567015: pthread_cond_wait@@GLIBC_2.3.2 (pthread_cond_wait.S:123) [ERROR] ==32369== by 0x43593D4: std::condition_variable::wait(std::unique_lock&) (gthr-default.h:846) [ERROR] ==32369== by 0x42A8E6A: cppa::detail::thread_pool_scheduler::worker_loop(cppa::detail::thread_pool_scheduler::worker*) (thread_pool_scheduler.cpp:59) [ERROR] ==32369== by 0x42AA45F: std::thread::_Impl >::_M_run() (functional:1287) [ERROR] ==32369== by 0x44D0A4D: clone (clone.S:130) [ERROR] ==32369== Address 0x4847064 is 52 bytes inside a block of size 96 alloc'd [ERROR] ==32369== at 0x402569A: operator new(unsigned int) (vg_replace_malloc.c:255) [ERROR] ==32369== by 0x42A94FF: cppa::detail::thread_pool_scheduler::supervisor_loop(cppa::util::single_reader_queue*, cppa::detail::scheduled_actor*) (thread_pool_scheduler.cpp:111) [ERROR] ==32369== by 0x44D0A4D: clone (clone.S:130) [ERROR] ==32369==
Any ideas?
The MONITOR message ends up being unanswered if an actor terminates beforehand.
A stateless actor represents a pure "message-based function". Since each message computation is guaranteed to have no side effects to the actor, the runtime system can invoke the message handler of a stateless actor concurrently. Hence, a stateless actor is the ultimate working horse if it comes to parallel computations. However, stateless actors require some serious changes to libcppa's scheduling.
The following code gives me:
terminate called after throwing an instance of 'std::runtime_error'
what(): uniform_type_info::by_type_info(): bool is an unknown typeid name
Seems there is something weird going on with boolean values.
#include <csignal>
#include <cppa/cppa.hpp>
using namespace cppa;
struct boolean : sb_actor<boolean>
{
behavior init_state = (
on(atom("hello"), arg_match) >> [=](bool b)
{
std::cout << "I " << (b ? "sleep" : "work") << std::endl;
quit();
});
};
int main()
{
send(spawn<boolean>(), atom("hello"), true);
await_all_others_done();
return 0;
}
Tested on Mac with Clang and Linux with GCC.
I tried to create 42 default-constructed cow-tuples in a vector, but cannot get this to compile:
#include <cppa/cppa.hpp>
using namespace cppa;
int main()
{
std::vector<cow_tuple<int>> v;
v.resize(42);
return 0;
}
Clang and GCC both complain here. Is it invalid to create an empty cow_tuple?
Do you think it makes sense to add a retry feature to sync_send
? In the same vein as after
, the user could specify how many times the runtime should try to send the same message again by adding a retry(n)
partial function.
Such a feature would allow for more resilience in a distributed systems where it is expected that not all messages arrive.
Forwarding a message to a remote group works only partially. The message arrives but is not sent back.
Based on the mailing list thread about syntactic sugar for handle_respose(sync_send(..))
, I would be very happy to see member functions handle
and receive
in the class message_future
in order to enable the syntax sync_send(...).{handle|receive}(on...);
.
In Scala actors there is the "synchronous message sends" method, "!?":
def !? (msec: Long, msg: Any): Option[Any]
Sends msg to this actor and awaits reply (synchronous) within msec milliseconds.
def !? (msg: Any): Any
Sends msg to this actor and awaits reply (synchronous).
" It sends the Next message to the coordinator, but instead of returning like a normal (asynchronous) message send, it waits for a reply from the coordinator. The reply is the return value of !?. A message that was sent using !? is replied to using reply. Note that simply sending a message to sender does not work! That's because !? waits to receive a message from a private reply channel instead of the mailbox. This is necessary to distinguish "true" replies from "fake" ones resulting from old messages that happen to be in the mailbox. " (http://www.scala-lang.org/node/242)
Such operator in libcppa would be very convenient to call actors from the non-actor code.
For example, currently: 1) we send message Q1 to an actor; 2) we wait for the reply R1, but then decide not to (timeout happens or whatever); 3) another iteration, we send message Q2 to an actor; 4) we expect reply R2 but we get R1 instead.
Having a "synchronous message sends" method should allow us to get the expected R2 (R1 being discarded when !? interrupts by timeout or exception).
Since there is currently no version indicator on the manual, it's sometimes confusing to what version (master, unstable, 0.3, etc.) it applies.
I'm trying to build libcppa from the git repository.
There is only an old_configure script file. When I run it, it generates a Makefile. I run make
and it starts to build libcppa. Unfortunately, it soon fails with this message :
/usr/bin/g++ -std=c++0x -pedantic -Wall -Wextra -g -O0 -I/opt/local/include/ -fpermissive -Wno-deprecated-declarations -I./ -fPIC -c src/blocking_message_queue.cpp -o src/blocking_message_queue.o
In file included from src/blocking_message_queue.cpp:8:0:
./cppa/invoke_rules.hpp:77:5: error: โcppa::invoke_rules_base::invoke_rules_base()โ cannot be overloaded
./cppa/invoke_rules.hpp:67:5: error: with โcppa::invoke_rules_base::invoke_rules_base()โ
./cppa/invoke_rules.hpp:79:5: error: โcppa::invoke_rules_base::invoke_rules_base(cppa::invokable_list&&)โ cannot be overloaded
./cppa/invoke_rules.hpp:69:5: error: with โcppa::invoke_rules_base::invoke_rules_base(cppa::invokable_list&&)โ
./cppa/invoke_rules.hpp:81:5: error: โcppa::invoke_rules_base::invoke_rules_base(cppa::invoke_rules_base&&)โ cannot be overloaded
./cppa/invoke_rules.hpp:71:5: error: with โcppa::invoke_rules_base::invoke_rules_base(cppa::invoke_rules_base&&)โ
make[1]: *** [src/blocking_message_queue.o] Error 1
I have no ideas how libcppa is coded, and I am not sure that to use ./old_configure
was the correct command to launch.
The readme file doesn't help much (and I can't help to try out this library).
As said in the title, I'm on a archlinux system, with gcc4.6.1, and with the x86_64 processor instruction set.
In Scala actors there is the "!?" method:
def !? (msec: Long, msg: Any): Option[Any]
Sends msg to this actor and awaits reply (synchronous) within msec milliseconds.
def !?(msg: Any): Any
Sends msg to this actor and awaits reply (synchronous).
" It sends the Next message to the coordinator, but instead of returning like a normal (asynchronous) message send, it waits for a reply from the coordinator. The reply is the return value of !?. A message that was sent using !? is replied to using reply. Note that simply sending a message to sender does not work! That's because !? waits to receive a message from a private reply channel instead of the mailbox. This is necessary to distinguish "true" replies from "fake" ones resulting from old messages that happen to be in the mailbox. " (http://www.scala-lang.org/node/242)
Such operator in libcppa would be very convenient to call actors from the non-actor code.
For example: 1) we send message Q1 to an actor; 2) we wait for the reply R1, but then decide not to (timeout happens or whatever); 3) another iteration, we send message Q2
Right now, an actor always accepts all kinds of messages, even if its behavior is defined only for a few cases. Encoding the list of accepted messages in an actors type is not feasible, since objects are guarded by actor_ptr
, which in fact uses type erasure. However, a type annotation still can be very useful. If compiled in debug mode, the actor can check each incoming message at runtime.
Annotations might look like the following example.
class foobar : public annotated_actor<event_based_actor,
type_list<atom_value, int>,
type_list<atom_value, double, string> > {
foobar() {
annotation<0>().add_guard(_x1 == atom("foo"));
annotation<1>().add_guard(_x1 == atom("bar"));
}
// ...
};
// ...
auto x = spawn<foobar>();
In the example above, x
would have an annotated actor_ptr
which then could type check passed messages using send
. However, the annotations are lost as soon as x
is used in messages or passed wherever an ordinary actor_ptr
is expected. Still, each bug found at compile time is a bug less at runtime.
The real feature, however, is the runtime check with optional guards. Each unsupported message will raise an exception or print a stack trace to give developers are clear hint that an actor has received a message it shouldn't.
Is it possible to implement try_receive() function that would wait until either specified number of microseconds has elapsed or message has arrived?
I'm trying to implement an actor that a) sends ticks to other actors and b) waits until it's told to terminate.
try_receive with timeout would be of great help, since it would make instant termination possible -
currently actor has to wait for the next scheduled tick in order to check whether it got termination message.
I haven't managed to write a small test case, but here is already the stacktrace. Ideally you know what's going on, but I believe this requires more context. The troublemaker is a cow_tuple<T>
stored outside a libcppa handler. I obtain the cow_tuple
as follows:
auto opt = tuple_cast<T>(last_dequeued());
assert(opt.valid());
f(*opt); // stores *opt.
As the actors terminate, this segfault occurs:
#0 0x0000000000000035 in ?? ()
#1 0x00007ffff7a94bd5 in cppa::intrusive_ptr<cppa::process_information>::~intrusive_ptr (this=0x7fffac000b80, __in_chrg=<optimized out>) at /home/matthias/opt/gcc/include/cppa/intrusive_ptr.hpp:88
#2 0x00007ffff671fe0b in cppa::detail::tdata<cppa::intrusive_ptr<cppa::process_information>, cppa::detail::addressed_message>::~tdata (this=0x7fffac000b58, __in_chrg=<optimized out>) at /home/matthias/libcppa/./cppa/detail/tdata.hpp:227
#3 0x00007ffff67226c1 in cppa::detail::tuple_vals<cppa::intrusive_ptr<cppa::process_information>, cppa::detail::addressed_message>::~tuple_vals (this=0x7fffac000b40, __in_chrg=<optimized out>) at /home/matthias/libcppa/./cppa/detail/tuple_vals.hpp:46
#4 0x00007ffff6722720 in cppa::detail::tuple_vals<cppa::intrusive_ptr<cppa::process_information>, cppa::detail::addressed_message>::~tuple_vals (this=0x7fffac000b40, __in_chrg=<optimized out>) at /home/matthias/libcppa/./cppa/detail/tuple_vals.hpp:46
#5 0x00007ffff7b6ab53 in cppa::intrusive_ptr<cppa::detail::abstract_tuple>::reset (this=0x61b818, new_value=0x617fc0) at /home/matthias/opt/gcc/include/cppa/intrusive_ptr.hpp:113
#6 0x00007ffff7b697e1 in cppa::cow_ptr<cppa::detail::abstract_tuple>::reset (this=0x61b818, value=0x617fc0) at /home/matthias/opt/gcc/include/cppa/cow_ptr.hpp:88
#7 0x00007ffff6729af9 in cppa::any_tuple::reset (this=0x61b818) at /home/matthias/libcppa/src/any_tuple.cpp:59
#8 0x00007ffff6736c01 in cppa::detail::abstract_actor<cppa::local_actor>::release_node (this=0x61b540, node=0x61b800) at /home/matthias/libcppa/./cppa/detail/abstract_actor.hpp:210
#9 0x00007ffff6735f8d in cppa::detail::receive_policy::invoke<cppa::thread_mapped_actor, cppa::behavior> (this=0x61b738, client=0x61b540, node=0x61b800, fun=..., awaited_response=...) at /home/matthias/libcppa/./cppa/detail/receive_policy.hpp:113
#10 0x00007ffff6735d77 in cppa::detail::receive_policy::receive_wo_timeout<cppa::thread_mapped_actor, cppa::behavior> (this=0x61b738, client=0x61b540, fun=...) at /home/matthias/libcppa/./cppa/detail/receive_policy.hpp:137
#11 0x00007ffff6735276 in cppa::detail::receive_policy::receive<cppa::thread_mapped_actor> (this=0x61b738, client=0x61b540, bhvr=...) at /home/matthias/libcppa/./cppa/detail/receive_policy.hpp:149
#12 0x00007ffff6734b24 in cppa::detail::stacked_actor_mixin<cppa::thread_mapped_actor, cppa::detail::abstract_actor<cppa::local_actor> >::dequeue (this=0x61b540, bhvr=...) at /home/matthias/libcppa/./cppa/detail/stacked_actor_mixin.hpp:64
#13 0x00007ffff674b712 in cppa::detail::do_receive_helper::until<cppa::ge_reference_wrapper<bool> >(cppa::ge_reference_wrapper<bool>&&) (this=0x7ffff270f8d0, stmt=...) at /home/matthias/libcppa/./cppa/detail/receive_loop_helper.hpp:122
#14 0x00007ffff6745bfb in cppa::detail::mailman_loop () at /home/matthias/libcppa/src/mailman.cpp:114
#15 0x00007ffff674dd2a in operator() (__closure=0x61ba50) at /home/matthias/libcppa/src/network_manager.cpp:82
#16 0x00007ffff675038e in std::_Bind_simple<{anonymous}::network_manager_impl::start()::<lambda()>()>::_M_invoke<>(std::_Index_tuple<>) (this=0x61ba50) at /home/matthias/opt/gcc/lib/gcc/x86_64-redhat-linux/4.7.0/../../../../include/c++/4.7.0/functional:1598
#17 0x00007ffff6750269 in std::_Bind_simple<{anonymous}::network_manager_impl::start()::<lambda()>()>::operator()(void) (this=0x61ba50) at /home/matthias/opt/gcc/lib/gcc/x86_64-redhat-linux/4.7.0/../../../../include/c++/4.7.0/functional:1586
#18 0x00007ffff675019a in std::thread::_Impl<std::_Bind_simple<{anonymous}::network_manager_impl::start()::<lambda()>()> >::_M_run(void) (this=0x61ba38) at /home/matthias/opt/gcc/lib/gcc/x86_64-redhat-linux/4.7.0/../../../../include/c++/4.7.0/thread:115
#19 0x00007ffff55f76c0 in std::(anonymous namespace)::execute_native_thread_routine (__p=<optimized out>) at ../../../../../libstdc++-v3/src/c++11/thread.cc:73
#20 0x0000003191207b31 in start_thread () from /lib64/libpthread.so.0
#21 0x0000003190edfd2d in clone () from /lib64/libc.so.6
System: 64-bit Linux with GCC 4.7.
This is what I get when running test__spawn
after a recent pull from unstable.
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7fff9dffb700 (LWP 18632)]
0x00000000006cb5a8 in cppa::ge_mutable_reference_wrapper<std::string const>::operator std::string const& (this=0x0) at /home/matthias/libcppa/./cppa/guard_expr.hpp:126
126 operator T& () const { CPPA_REQUIRE(value != 0); return *value; }
Here is the stack trace:
#0 0x00000000006cb5a8 in cppa::ge_mutable_reference_wrapper<std::string const>::operator std::string const& (this=0x0) at /home/matthias/libcppa/./cppa/guard_expr.hpp:126
#1 0x00000000006cac28 in cppa::detail::projection_helper<cppa::tpartial_function<testee_actor::wait4string()::{lambda()#1}, cppa::detail::value_guard<cppa::util::type_list<> >, void, std::string const&> const>::operator()<cppa::ge_mutable_reference_wrapper<cppa::detail::value_guard<cppa::util::type_list<> > >&>(cppa::ge_mutable_reference_wrapper<cppa::detail::value_guard<cppa::util::type_list<> > >&&&) const (this=0x7ffff7ff20f0) at /home/matthias/libcppa/./cppa/detail/projection.hpp:53
#2 0x00000000006c9e0a in cppa::util::apply_tuple_impl<bool, true, 0ul>::apply<cppa::detail::projection_helper<cppa::tpartial_function<testee_actor::wait4string()::{lambda()#1}, cppa::detail::value_guard<cppa::util::type_list<> >, void, std::string const&> const>, cppa::detail::tdata<cppa::ge_mutable_reference_wrapper<cppa::detail::value_guard<cppa::util::type_list<> > > > >(cppa::detail::projection_helper<cppa::tpartial_function<testee_actor::wait4string()::{lambda()#1}, cppa::detail::value_guard<cppa::util::type_list<> >, void, std::string const&> const>&, cppa::detail::tdata<cppa::ge_mutable_reference_wrapper<cppa::detail::value_guard<cppa::util::type_list<> > > >&) (f=..., args=...) at /home/matthias/libcppa/./cppa/util/apply_tuple.hpp:54
#3 0x00000000006c8c7e in cppa::util::unchecked_apply_tuple<bool, cppa::detail::projection_helper<cppa::tpartial_function<testee_actor::wait4string()::{lambda()#1}, cppa::detail::value_guard<cppa::util::type_list<> >, void, std::string const&> const>&, cppa::detail::tdata, cppa::ge_mutable_reference_wrapper<cppa::detail::value_guard<cppa::util::type_list<> > > >(cppa::detail::projection_helper<cppa::tpartial_function<testee_actor::wait4string()::{lambda()#1}, cppa::detail::value_guard<cppa::util::type_list<> >, void, std::string const&> const>&&&, cppa::detail::tdata<cppa::ge_mutable_reference_wrapper<cppa::detail::value_guard<cppa::util::type_list<> > > >&) (fun=..., tup=...) at /home/matthias/libcppa/./cppa/util/apply_tuple.hpp:133
#4 0x00000000006c7786 in cppa::detail::projection<cppa::util::type_list<cppa::util::void_type>, std::string const&>::operator()<cppa::tpartial_function<testee_actor::wait4string()::{lambda()#1}, cppa::detail::value_guard<cppa::util::type_list<> >, void, std::string const&> const>(cppa::tpartial_function<testee_actor::wait4string()::{lambda()#1}, cppa::detail::value_guard<cppa::util::type_list<> >, void, std::string const&> const&, std::string const&) const (this=0x7fff600010c0, fun=..., args#0="hello testee_actor") at /home/matthias/libcppa/./cppa/detail/projection.hpp:101
Can you reproduce this one?
Just found another segfault by running my project's tests in a loop:
[ERROR] ==25985== Thread 2: [ERROR] ==25985== Invalid read of size 4 [ERROR] ==25985== at 0x426D93D: cppa::detail::get_actor_proxy_cache() (shared_ptr.hpp:238) [ERROR] ==25985== by 0x428857E: cppa::detail::(anonymous namespace)::post_office_loop(int) (post_office.cpp:622) [ERROR] ==25985== by 0x428AECF: std::thread::_Impl >::_M_run() (functional:1287) [ERROR] ==25985== by 0x44C9A4D: clone (clone.S:130) [ERROR] ==25985== Address 0x0 is not stack'd, malloc'd or (recently) free'd [ERROR] ==25985== [ERROR] ==25985== [ERROR] ==25985== Process terminating with default action of signal 11 (SIGSEGV) [ERROR] ==25985== Access not within mapped region at address 0x0 [ERROR] ==25985== at 0x426D93D: cppa::detail::get_actor_proxy_cache() (shared_ptr.hpp:238) [ERROR] ==25985== by 0x428857E: cppa::detail::(anonymous namespace)::post_office_loop(int) (post_office.cpp:622) [ERROR] ==25985== by 0x428AECF: std::thread::_Impl >::_M_run() (functional:1287) [ERROR] ==25985== by 0x44C9A4D: clone (clone.S:130) [ERROR] ==25985== If you believe this happened as a result of a stack [ERROR] ==25985== overflow in your program's main thread (unlikely but [ERROR] ==25985== possible), you can try to increase the size of the [ERROR] ==25985== main thread stack using the --main-stacksize= flag. [ERROR] ==25985== The main thread stack size used in this run was 8388608.
Otherwise one can't use the same port for an actor because of TIME_WAIT sockets.
Currently, receiving a synchronous response always requires a timeout specification. This is because the following cases were guaranteed to be deadlocks otherwise:
The runtime system might send a special kind of message in such cases to inform the sender that its message was dropped. In order to do this, the runtime system needs to have the ability to check whether a mailbox is "closed". Furthermore, a terminating actor must scan its mailbox for unreplied-to messages after closing it.
By implementing the mentioned improvement, the only remaining deadlock scenario is an actor that does not have a matching handler defined in its current behavior. However, it is the responsibility of application developers to prevent such deadlocks and libcppa would not have to enforce timeout definitions for synchronous response handlers.
FYI, unstable branch does not compile by default:
[ 65%] Building CXX object unit_testing/CMakeFiles/test__atom.dir/test__atom.cpp.o
Linking CXX executable ../bin/test__atom
/root/work/libcppa/build/lib/libcppa.so: undefined reference to `pthread_key_create'
/root/work/libcppa/build/lib/libcppa.so: undefined reference to `pthread_once'
/root/work/libcppa/build/lib/libcppa.so: undefined reference to `pthread_getspecific'
/root/work/libcppa/build/lib/libcppa.so: undefined reference to `pthread_setspecific'
collect2: error: ld returned 1 exit status
make[3]: *** [bin/test__atom] Error 1
make[3]: Leaving directory `/home/root/work/libcppa/build'
make[2]: *** [unit_testing/CMakeFiles/test__atom.dir/all] Error 2
make[2]: Leaving directory `/home/root/work/libcppa/build'
make[1]: *** [all] Error 2
make[1]: Leaving directory `/home/root/work/libcppa/build'
make: *** [all] Error 2
root@pro1453:~/work/libcppa# Write failed: Connection reset by peer
$ ./unit_tests
run test__pattern ...
0 error(s) detected
run test__yield_interface ...
ERROR in file test__yield_interface.cpp on line 67 => ((yielded_state()) == (yield_state::done))
1 error(s) detected
run test__ripemd_160 ...
0 error(s) detected
run test__primitive_variant ...
0 error(s) detected
run test__uniform_type ...
0 error(s) detected
run test__intrusive_ptr ...
0 error(s) detected
run test__type_list ...
0 error(s) detected
run test__tuple ...
0 error(s) detected
run test__serialization ...
0 error(s) detected
run test__spawn ...
^C
The last test hangs indefinitely. I'm not sure how to proceed with testing this, any thoughts?
After the recent changes, it is impossible to copy a cow_tuple
anymore, it can only be moved. In general, my assumption was that copying a cow_tuple
should be fine, as it only increases an internal reference count. In fact, I am relying on this assumption and build my classes with copy semantics---which breaks at this point.
Below is an example illustrating the issue (slightly modified from the group discussion). I marked the critical line with comment <----------------------------
.
#include <cppa/cppa.hpp>
using namespace cppa;
struct expensive
{
expensive() = default;
expensive(expensive const& other)
{
std::cout << "expensive copy!" << std::endl;
}
expensive(expensive&& other)
{
std::cout << "nice move" << std::endl;
}
int data = 42;
};
bool operator==(expensive const& x, expensive const& y)
{
return x.data == y.data;
}
struct actress : sb_actor<actress>
{
actress(actor_ptr a)
: receiver(a)
{ }
behavior init_state = (
on(atom("foo"), arg_match) >> [=](expensive const& exp)
{
auto opt = tuple_cast<anything, expensive>(last_dequeued());
cow_tuple<expensive> t(*opt); /// <----------------------------
std::cout << "sending tuple" << std::endl;
send_tuple(receiver, t);
self->quit();
});
actor_ptr receiver;
};
int main()
{
announce<expensive>(&expensive::data);
auto a = spawn<actress>(self);
expensive exp;
send(a, atom("foo"), std::move(exp));
receive(
on_arg_match >> [=](expensive const& exp)
{
std::cout << "received expensive data" << std::endl;
});
await_all_others_done();
return 0;
}
And here is the compiler complaint:
/Users/mavam/code/root/include/cppa/detail/tuple_vals.hpp:64:7: error: no matching constructor for initialization of 'data_type' (aka 'tdata<expensive>') [6/9756]
, m_data(std::forward<Args>(args)...) { }
^ ~~~~~~~~~~~~~~~~~~~~~~~~
/Users/mavam/code/root/include/cppa/cow_tuple.hpp:97:44: note: in instantiation of function template specialization 'cppa::detail::tuple_vals<expensive>::tuple_vals<cppa::cow_tuple<expensive> &>' requested here
cow_tuple(Args&&... args) : m_vals(new data_type(std::forward<Args>(args)...)) { }
^
expensive.cc:39:30: note: in instantiation of function template specialization 'cppa::cow_tuple<expensive>::cow_tuple<cppa::cow_tuple<expensive> &>' requested here
cow_tuple<expensive> t(*opt);
^
/Users/mavam/code/root/include/cppa/detail/tdata.hpp:252:5: note: candidate constructor not viable: no known conversion from 'cppa::cow_tuple<expensive>' to 'const expensive' for 1st argument
tdata(const Head& arg) : super(), head(arg) { }
^
/Users/mavam/code/root/include/cppa/detail/tdata.hpp:253:5: note: candidate constructor not viable: no known conversion from 'cppa::cow_tuple<expensive>' to 'expensive' for 1st argument
tdata(Head&& arg) : super(), head(std::move(arg)) { }
^
/Users/mavam/code/root/include/cppa/detail/tdata.hpp:261:5: note: candidate constructor not viable: no known conversion from 'cppa::cow_tuple<expensive>' to 'const cppa::detail::tdata<expensive>' for 1st argument
tdata(const tdata&) = default;
^
/Users/mavam/code/root/include/cppa/detail/tdata.hpp:263:5: note: candidate constructor not viable: no known conversion from 'cppa::cow_tuple<expensive>' to 'cppa::detail::tdata<expensive>' for 1st argument
tdata(tdata&& other)
^
/Users/mavam/code/root/include/cppa/detail/tdata.hpp:270:5: note: candidate template ignored: failed template argument deduction
tdata(tdata<Y...>& other) : super(other.tail()), head(other.head) {
^
/Users/mavam/code/root/include/cppa/detail/tdata.hpp:274:5: note: candidate template ignored: failed template argument deduction
tdata(const tdata<Y...>& other) : super(other.tail()), head(other.head) {
^
/Users/mavam/code/root/include/cppa/detail/tdata.hpp:278:5: note: candidate template ignored: failed template argument deduction
tdata(tdata<Y...>&& other)
^
/Users/mavam/code/root/include/cppa/detail/tdata.hpp:256:5: note: candidate constructor template not viable: requires at least 2 arguments, but 1 was provided
tdata(Arg0&& arg0, Arg1&& arg1, Args&&... args)
^
/Users/mavam/code/root/include/cppa/detail/tdata.hpp:256:5: note: candidate constructor template not viable: requires at least 2 arguments, but 1 was provided
tdata(Arg0&& arg0, Arg1&& arg1, Args&&... args)
^
/Users/mavam/code/root/include/cppa/detail/tdata.hpp:248:12: note: candidate constructor not viable: requires 0 arguments, but 1 was provided
inline tdata() : super(), head() { }
^
This may be a compiler bug, but then it's in both GCC and Clang :-).
I cannot get a reply when doing a sync_send
to a remote actor. Locally it works just fine though. Here is the test case:
#include <cppa/cppa.hpp>
using namespace cppa;
struct hinz : sb_actor<hinz>
{
hinz(actor_ptr buddy) : buddy(buddy) { }
behavior init_state = (
on(atom("call")) >> [=]
{
handle_response(sync_send(buddy, "wischdisch"))(
on_arg_match >> [=](std::string const& answer)
{
std::cout << "was meinsch du mit: " << answer << "?" << std::endl;
quit();
},
after(std::chrono::seconds(1)) >> [=]
{
std::cout << "ruft nommo aan" << std::endl;
});
});
actor_ptr buddy;
};
struct kunz : sb_actor<kunz>
{
behavior init_state = (
on_arg_match >> [=](std::string const& str)
{
std::cout << "unwischtisch" << std::endl;
reply("heee man uff");
quit();
});
};
int main()
{
auto a = spawn<kunz>();
publish(a, 45678);
auto r = remote_actor("localhost", 45678);
auto b = spawn<hinz>(r);
send(b, atom("call"));
await_all_others_done();
return 0;
}
This is the output and the program hangs (because the actor did not terminate in the after
case):
unwischtisch
ruft nommo aan
As a side note: if I change
auto b = spawn<hinz>(r);
to
auto b = spawn<hinz>(a);
the program terminates with an exception. I thought the only thing that I've done is ignoring the remote actor, so the crash seems to be unexpected behavior. This is a separate issue though which arose in the same context, hence I mentioned it here.
After wondering why VAST does not work anymore with the lastest unstable, I had to figure out which commit was the culprit. This one: d209355. Before this commit, my messages arrive, but with this commit certain messages do not arrive anymore. Unfortunately I could not reproduce this with a small example. Here are some hopefully related random facts:
a1 << last_dequeued();
followed by a2 << last_dequeued();
forward_to(a)
cat: /proc/cpuinfo: No such file or directory
./run_benchmarks.sh: line 9: declare: -A: invalid option
declare: usage: declare [-afFirtx] [-p] [name[=value] ...]
./run_benchmarks.sh: line 14: declare: -A: invalid option
declare: usage: declare [-afFirtx] [-p] [name[=value] ...]
./run_benchmarks.sh: line 15: cppa.mixed_case: syntax error: invalid arithmetic operator (error token is ".mixed_case")
./run_benchmarks.sh: line 16: cppa.actor_creation: syntax error: invalid arithmetic operator (error token is ".actor_creation")
./run_benchmarks.sh: line 17: cppa.mailbox_performance: syntax error: invalid arithmetic operator (error token is ".mailbox_performance")
./run_benchmarks.sh: line 18: scala.mixed_case: syntax error: invalid arithmetic operator (error token is ".mixed_case")
./run_benchmarks.sh: line 19: scala.actor_creation: syntax error: invalid arithmetic operator (error token is ".actor_creation")
./run_benchmarks.sh: line 20: scala.mailbox_performance: syntax error: invalid arithmetic operator (error token is ".mailbox_performance")
./run_benchmarks.sh: line 21: erlang.mixed_case: syntax error: invalid arithmetic operator (error token is ".mixed_case")
./run_benchmarks.sh: line 22: erlang.actor_creation: syntax error: invalid arithmetic operator (error token is ".actor_creation")
./run_benchmarks.sh: line 23: erlang.mailbox_performance: syntax error: invalid arithmetic operator (error token is ".mailbox_performance")
./run_benchmarks.sh: line 25: declare: -A: invalid option
declare: usage: declare [-afFirtx] [-p] [name[=value] ...]
./run_benchmarks.sh: line 37: cppa.actor_creation: syntax error: invalid arithmetic operator (error token is ".actor_creation")
Should be self-explanatory :-).
When building libcppa on ARM, the assembler will emit many warnings in a few places that look like this:
libtool: compile: g++ -DPACKAGE_NAME=\"libcppa\" -DPACKAGE_TARNAME=\"libcppa\" -DPACKAGE_VERSION=\"0.1\" "-DPACKAGE_STRING=\"libcppa 0.1\"" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DPACKAGE=\"@PACKAGE_NAME@\" -DVERSION=\"@PACKAGE_VERSION@\" "-DHAVE_BOOST=/**/" "-DHAVE_BOOST_THREAD=/**/" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 -DLT_OBJDIR=\".libs/\" -I. --std=c++0x -pedantic -Wall -Wextra -march=armv7-a -mfloat-abi=hard -mfpu=vfpv3-d16 -O2 -pipe -fstack-protector --param=ssp-buffer-size=4 -D_FORTIFY_SOURCE=2 -MT libcppa_la-actor_proxy_cache.lo -MD -MP -MF .deps/libcppa_la-actor_proxy_cache.Tpo -c src/actor_proxy_cache.cpp -fPIC -DPIC -o .libs/libcppa_la-actor_proxy_cache.o
{standard input}: Assembler messages:
{standard input}:337: Warning: swp{b} use is deprecated for this architecture
{standard input}:345: Warning: swp{b} use is deprecated for this architecture
{standard input}:361: Warning: swp{b} use is deprecated for this architecture
{standard input}:402: Warning: swp{b} use is deprecated for this architecture
{standard input}:410: Warning: swp{b} use is deprecated for this architecture
{standard input}:426: Warning: swp{b} use is deprecated for this architecture
{standard input}:501: Warning: swp{b} use is deprecated for this architecture
{standard input}:509: Warning: swp{b} use is deprecated for this architecture
{standard input}:525: Warning: swp{b} use is deprecated for this architecture
{standard input}:557: Warning: swp{b} use is deprecated for this architecture
{standard input}:566: Warning: swp{b} use is deprecated for this architecture
{standard input}:582: Warning: swp{b} use is deprecated for this architecture
{standard input}:632: Warning: swp{b} use is deprecated for this architecture
{standard input}:640: Warning: swp{b} use is deprecated for this architecture
{standard input}:656: Warning: swp{b} use is deprecated for this architecture
{standard input}:700: Warning: swp{b} use is deprecated for this architecture
{standard input}:709: Warning: swp{b} use is deprecated for this architecture
{standard input}:725: Warning: swp{b} use is deprecated for this architecture
{standard input}:870: Warning: swp{b} use is deprecated for this architecture
{standard input}:877: Warning: swp{b} use is deprecated for this architecture
{standard input}:934: Warning: swp{b} use is deprecated for this architecture
{standard input}:943: Warning: swp{b} use is deprecated for this architecture
{standard input}:988: Warning: swp{b} use is deprecated for this architecture
{standard input}:996: Warning: swp{b} use is deprecated for this architecture
It looks like the SWP instruction (atomic swap) is deprecated on ARMv7 because it performs very poorly. I haven't looked at exactly how it's getting into the assembly output, but it looks like it could just be an upstream issue.
I've always been nervous about having to duplicate knowledge about atom value and message parameter types on sending (cppa::send) and receiving (cppa::on) ends, that might cause trouble when some of them change in one place and are not properly updated in the other.
I wrote a helper class that helps consolidating this knowledge and I'm wondering if something similar could be added to the library.
Here is the code:
#include <iostream>
#include <string>
#include <cppa/cppa.hpp>
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
#define MESSAGE_ON_TEMPLATE_ELEMENT(z, n, unused) , typename T##n
#define MESSAGE_ON_TEMPLATE(n) template<typename T1 BOOST_PP_REPEAT_FROM_TO(2, BOOST_PP_ADD(1, n), MESSAGE_ON_TEMPLATE_ELEMENT, nil)>
#define MESSAGE_ON_ARGUMENT(z, n, unused) , cppa::val<T##n>()
#define MESSAGE_ON_RETVAL(n) cppa::on(id BOOST_PP_REPEAT_FROM_TO(1, BOOST_PP_ADD(1, n), MESSAGE_ON_ARGUMENT, nil))
#define MESSAGE_ON(z, n, unused) \
MESSAGE_ON_TEMPLATE(n) \
auto message_on(cppa::atom_value id) -> decltype(MESSAGE_ON_RETVAL(n)) { \
return MESSAGE_ON_RETVAL(n); \
}
BOOST_PP_REPEAT_FROM_TO(1, 23, MESSAGE_ON, nil)
template<typename M, typename... Args>
class message {
public:
static void send(cppa::actor_ptr actor, Args... args) {
cppa::send(actor, M::id, args...);
}
static decltype(message_on<Args...>(M::id)) on() {
return message_on<Args...>(M::id);
}
};
class hello_id {
public:
static const cppa::atom_value id;
};
const cppa::atom_value hello_id::id = cppa::atom("hello");
class hello : public message<hello_id, std::string> {
};
int main() {
hello::send(cppa::self(), "world");
cppa::receive(hello::on() >> [](const std::string s) {
std::cout << "hello " << s << std::endl;
});
return 0;
}
I've just seen this
Invalid read of size 8
==15807== at 0x8AFAB28: uw_update_context (unwind-dw2.c:216)
==15807== by 0x8AFBF7B: _Unwind_RaiseException (unwind.inc:122)
==15807== by 0x85C6A30: __cxa_throw (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.17)
==15807== by 0x7FF55B2: cppa::detail::fd_util::throw_io_failure(std::string&&, bool) (fd_util.cpp:57)
==15807== by 0x7FF59DA: cppa::detail::fd_util::handle_write_result(long, bool) (fd_util.cpp:105)
==15807== by 0x7FF5A4B: cppa::detail::fd_util::handle_read_result(long, bool) (fd_util.cpp:110)
==15807== by 0x801CE45: cppa::detail::ipv4_io_stream::read(void*, unsigned long) (ipv4_io_stream.cpp:69)
==15807== by 0x8066A77: cppa::remote_actor(std::pair<cppa::intrusive_ptr<cppa::util::input_stream>, cppa::intrusive_ptr<cppa::util::output_stream> >) (unicast_network.cpp:77)
And looking at the code, I think that
https://github.com/Neverlord/libcppa/blob/master/src/fd_util.cpp#L51
might benefit from less std::move
and &&
,
see http://stackoverflow.com/questions/4986673/c11-rvalues-and-move-semantics-confusion
What do you think?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.