GithubHelp home page GithubHelp logo

actor-framework / actor-framework Goto Github PK

View Code? Open in Web Editor NEW
3.1K 178.0 531.0 41.34 MB

An Open Source Implementation of the Actor Model in C++

Home Page: http://actor-framework.org/

License: BSD 3-Clause "New" or "Revised" License

CMake 0.98% C++ 97.18% Shell 0.37% R 0.30% Python 0.31% Dockerfile 0.09% Batchfile 0.01% RobotFramework 0.77%
actor-model caf pattern-matching actors async

actor-framework's Introduction

CAF: the C++ Actor Framework

CAF is an open source implementation of the actor model for C++ featuring lightweight & fast actor implementations, pattern matching for messages, network transparent messaging, and more.

Gitter Documentation Status Coverage

Online Resources

Report Bugs / Get Help

Community

Get CAF

We do not officially maintain packages for CAF. However, some of our community members made packages available for these package managers:

Get the Sources

git clone https://github.com/actor-framework/actor-framework.git
cd actor-framework

Build CAF from Source

CAF uses CMake as its build system of choice. To make building CAF more convenient from the command line, we provide a configure script that wraps the CMake invocation. The script only works on UNIX systems. On Windows, we recommend generating an MSVC project file via CMake for native builds.

Using the configure Script

The script is a convenient frontend for CMake. See configure -h for a list of available options. By default, the script creates a build directory and asks CMake to generate a Makefile. A build with default settings generally follows these steps:

./configure
cd build
make
make test [optional]
make install [as root, optional]

Using CMake

To generate a Makefile for building CAF with default settings, either use a CMake GUI or perform these steps on the command line:

mkdir build
cd build
cmake ..

After this step, cmake -LH prints the most useful configuration options for CAF, their default value, and a helptext.

Other CMake projects can add CAF as a dependency by using find_package and listing the required modules (e.g., core or io) . When installing CAF to a non-standard location, set CAF_ROOT prior to calling find_package.

Dependencies

  • CMake (for building CAF)
  • OpenSSL (only when building the OpenSSL module)

Supported Platforms

C++ is an evolving language. Compiler vendors constantly add more language and standard library features. Since CAF runs on many platforms, this means we need a policy that on the one hand ensures that we only use a widely supported subset of C++ and on the other hand that we naturally progress with the shifting landscape to eventually catch up to more recent C++ additions (in order to not "get stuck").

So instead of singling out individual compiler versions, we build CAF for each commit on all platforms that we currently deem relevant. Everything that passes our CI is "fair game".

Our CI covers Windows (latest MSVC release), macOS (latest Xcode release), FreeBSD (latest) and several Linux distributions (via the Docker images found here). For Linux, we aim to support the current releases (that still receive active support) for the major distributions. Note that we do not build on Linux distributions with rolling releases, because they generally provide more recent build tools than distributions with traditional release schedules and thus would only add redundancy.

Build Documentation Locally

  • Building an offline version of the manual requires Sphinx:
    cd manual
    sphinx-build . html
  • Building an offline version of the API reference documentation requires Doxygen (simply run the doxygen command at the root directory of the repository).

Scientific Use

If you use CAF in a scientific context, please use one of the following citations:

@inproceedings{cshw-nassp-13,
  author = {Dominik Charousset and Thomas C. Schmidt and Raphael Hiesgen and Matthias W{\"a}hlisch},
  title = {{Native Actors -- A Scalable Software Platform for Distributed, Heterogeneous Environments}},
  booktitle = {Proc. of the 4rd ACM SIGPLAN Conference on Systems, Programming, and Applications (SPLASH '13), Workshop AGERE!},
  pages = {87--96},
  month = {Oct.},
  year = {2013},
  publisher = {ACM},
  address = {New York, NY, USA}
}

@article{chs-rapc-16,
  author = {Dominik Charousset and Raphael Hiesgen and Thomas C. Schmidt},
  title = {{Revisiting Actor Programming in C++}},
  journal = {Computer Languages, Systems \& Structures},
  volume = {45},
  year = {2016},
  month = {April},
  pages = {105--131},
  publisher = {Elsevier}
}

You can find the papers online at http://dx.doi.org/10.1145/2541329.2541336 and http://dx.doi.org/10.1016/j.cl.2016.01.002.

actor-framework's People

Contributors

allspark avatar andrismednis avatar cppphil avatar dominiklohmann avatar firegurafiku avatar hamdor avatar i-ky avatar inet-jenkins avatar jakobod avatar jokalode avatar josephnoir avatar jsiwek avatar lingxi-li avatar mavam avatar mephi42 avatar mroethke avatar neverlord avatar nq-ebaratte avatar outro56 avatar raphaelzulliger avatar riemass avatar rkfg avatar shariarriday avatar sourcedelica avatar suadh avatar tobim avatar toffaletti avatar uentity avatar ufownl avatar woelke avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

actor-framework's Issues

SEGV while using remote actor?

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");}
    );

Segfault in cppa::detail::get_actor_proxy_cache

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.

Announce not working for STL vector

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?

Problem installing (Debian Wheezy)

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

Destruction issues

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)

Segfaults during startup

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?

Mixed Case benchmark fails on Mac (Clang only)

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 ()

Convenience includes for forward declarations

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.?

RFE: Implement "synchronous message sends".

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

RFE: Implement "synchronous message sends".

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

Segfault in test___spawn on Linux w/ GCC (unstable branch)

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?

ARM Assembler Warnings

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.

Annotations for actors to ease debugging

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.

Enable serialization of group_ptr

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.

Segfault in intrusive_ptr destructor

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.

Building examples on Fedora w/ Clang 3.2 (git)

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?

Add stateless actors

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.

Add a bit of type safety to message handling

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;
}

Broken pipe with new network layer changes

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.

dangerous pessimization at throw_io_failure

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?

run_benchmarks.sh broken on Mac

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 :-).

Build failure in Boost.Context on MacOS 10.5.8 with gcc 4.7.1

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
''''

RFE: Implement "synchronous message sends".

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).

Handle select errors.

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).

Segfault with boolean tuple elements

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.

unicode conversions

Provide unicode conversion to cppa::to_string and cppa::from_string as soon as unicode codecvt implementations are available in GCC.

try_receive() with timeout

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.

Build error [gcc 4.6.1, archlinux, x86_64]

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.

Remote sync_send woes

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.

Failing unit test on Mac with GCC

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)

Yet another cow_tuple constructor issue

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?

Termination issue with await_all_others_done()

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;
}

"make test" makes 64-bit Linux incredibly slow

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?

Use 64bit integer for duration type.

--- from mephi42 ---

  1. I get the following warning during compilation when I use std::chrono::microseconds
[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]

Provide an asynchronous IO API for actors

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.

Indicate libcppa version on manual

Since there is currently no version indicator on the manual, it's sometimes confusing to what version (master, unstable, 0.3, etc.) it applies.

sync_send: retry feature

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.

Problem with sync_send and asynchronous handling

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;
}

Cannot copy cow_tuple anymore

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 :-).

Improve synchronous messaging, i.e., make timeouts for synchronous response handlers optional

Currently, receiving a synchronous response always requires a timeout specification. This is because the following cases were guaranteed to be deadlocks otherwise:

  • sync_send to a terminated actor
  • sync_send to an actor that finishes execution afterwards without handling the message
  • request forwarding, e.g., by an actor proxy, with one of the two previously mentioned cases

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.

Segfault on 64-bit Linux with Clang (git)

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:

  • actor_creation
  • announce_example_1
  • announce_example_2
  • announce_example_3
  • announce_example_4
  • announce_example_5
  • dancing_kirby
  • dining_philosophers
  • distributed
  • hello_world_example
  • mailbox_performance
  • matching
  • math_actor_example
  • mixed_case
  • unit_tests

try_receive() with timeout

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.

undefined reference to `pthread_once'

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

Noisy actor termination

When a remote actor disconnects, libcppa prints on the console:

Connection reset by peer [errno = 104]

Could we get rid of this output? :-)

Bug in "serialization fix"

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:

  • I use a1 << last_dequeued(); followed by a2 << last_dequeued();
  • I use forward_to(a)

ARM Unittest Failures

$ ./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?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.