Commit 7017d49f authored by neverlord's avatar neverlord

Merge https://github.com/mephi42/libcppa into singletons

parents 9c5ee9fe bdcee9fa
lib_LTLIBRARIES = libcppa.la
libcppa_la_SOURCES = \
src/abstract_type_list.cpp \
src/actor_behavior.cpp \
src/actor_count.cpp \
src/actor.cpp \
src/actor_proxy_cache.cpp \
src/actor_proxy.cpp \
src/any_tuple.cpp \
src/any_tuple_iterator.cpp \
src/atom.cpp \
src/attachable.cpp \
src/binary_deserializer.cpp \
src/binary_serializer.cpp \
src/blocking_message_queue.cpp \
src/channel.cpp \
src/context.cpp \
src/converted_thread_context.cpp \
src/cppa.cpp \
src/delegate.cpp \
src/demangle.cpp \
src/deserializer.cpp \
src/exception.cpp \
src/fiber.cpp \
src/group.cpp \
src/intermediate.cpp \
src/invokable.cpp \
src/mailman.cpp \
src/matcher_arguments.cpp \
src/message.cpp \
src/message_queue.cpp \
src/mock_scheduler.cpp \
src/native_socket.cpp \
src/object_array.cpp \
src/object.cpp \
src/post_office.cpp \
src/primitive_variant.cpp \
src/process_information.cpp \
src/ripemd_160.cpp \
src/scheduled_actor.cpp \
src/scheduler.cpp \
src/serializer.cpp \
src/shared_spinlock.cpp \
src/string_serialization.cpp \
src/task_scheduler.cpp \
src/thread_pool_scheduler.cpp \
src/to_uniform_name.cpp \
src/unicast_network.cpp \
src/uniform_type_info.cpp \
src/yielding_message_queue.cpp \
src/yield_interface.cpp
nobase_include_HEADERS = \
cppa/actor_behavior.hpp \
cppa/actor.hpp \
cppa/actor_proxy.hpp \
cppa/announce.hpp \
cppa/any_tuple.hpp \
cppa/any_type.hpp \
cppa/atom.hpp \
cppa/attachable.hpp \
cppa/binary_deserializer.hpp \
cppa/binary_serializer.hpp \
cppa/channel.hpp \
cppa/config.hpp \
cppa/context.hpp \
cppa/cow_ptr.hpp \
cppa/cppa.hpp \
cppa/deserializer.hpp \
cppa/detail/abstract_actor.hpp \
cppa/detail/abstract_message_queue.hpp \
cppa/detail/abstract_tuple.hpp \
cppa/detail/actor_count.hpp \
cppa/detail/actor_proxy_cache.hpp \
cppa/detail/atom_val.hpp \
cppa/detail/blocking_message_queue.hpp \
cppa/detail/boxed.hpp \
cppa/detail/buffer.hpp \
cppa/detail/channel.hpp \
cppa/detail/converted_thread_context.hpp \
cppa/detail/decorated_tuple.hpp \
cppa/detail/default_uniform_type_info_impl.hpp \
cppa/detail/delegate.hpp \
cppa/detail/demangle.hpp \
cppa/detail/get_behavior.hpp \
cppa/detail/intermediate.hpp \
cppa/detail/invokable.hpp \
cppa/detail/list_member.hpp \
cppa/detail/mailman.hpp \
cppa/detail/map_member.hpp \
cppa/detail/matcher_arguments.hpp \
cppa/detail/matcher.hpp \
cppa/detail/mock_scheduler.hpp \
cppa/detail/native_socket.hpp \
cppa/detail/object_array.hpp \
cppa/detail/object_impl.hpp \
cppa/detail/pair_member.hpp \
cppa/detail/post_office.hpp \
cppa/detail/primitive_member.hpp \
cppa/detail/ptype_to_type.hpp \
cppa/detail/receive_loop_helper.hpp \
cppa/detail/ref_counted_impl.hpp \
cppa/detail/scheduled_actor.hpp \
cppa/detail/serialize_tuple.hpp \
cppa/detail/swap_bytes.hpp \
cppa/detail/task_scheduler.hpp \
cppa/detail/tdata.hpp \
cppa/detail/thread_pool_scheduler.hpp \
cppa/detail/to_uniform_name.hpp \
cppa/detail/tuple_vals.hpp \
cppa/detail/type_to_ptype.hpp \
cppa/detail/unboxed.hpp \
cppa/detail/yielding_message_queue.hpp \
cppa/detail/yield_interface.hpp \
cppa/exception.hpp \
cppa/exit_reason.hpp \
cppa/from_string.hpp \
cppa/get.hpp \
cppa/get_view.hpp \
cppa/group.hpp \
cppa/intrusive_ptr.hpp \
cppa/invoke.hpp \
cppa/invoke_rules.hpp \
cppa/match.hpp \
cppa/message.hpp \
cppa/message_queue.hpp \
cppa/object.hpp \
cppa/on.hpp \
cppa/primitive_type.hpp \
cppa/primitive_variant.hpp \
cppa/process_information.hpp \
cppa/ref_counted.hpp \
cppa/scheduler.hpp \
cppa/scheduling_hint.hpp \
cppa/serializer.hpp \
cppa/to_string.hpp \
cppa/tuple.hpp \
cppa/tuple_view.hpp \
cppa/uniform_type_info.hpp \
cppa/util/abstract_type_list.hpp \
cppa/util/abstract_uniform_type_info.hpp \
cppa/util/a_matches_b.hpp \
cppa/util/any_tuple_iterator.hpp \
cppa/util/apply.hpp \
cppa/util/at.hpp \
cppa/util/callable_trait.hpp \
cppa/util/comparable.hpp \
cppa/util/compare_tuples.hpp \
cppa/util/concat_type_lists.hpp \
cppa/util/conjunction.hpp \
cppa/util/disable_if.hpp \
cppa/util/disjunction.hpp \
cppa/util/element_at.hpp \
cppa/util/enable_if.hpp \
cppa/util/eval_first_n.hpp \
cppa/util/eval_type_list.hpp \
cppa/util/eval_type_lists.hpp \
cppa/util/fiber.hpp \
cppa/util/filter_type_list.hpp \
cppa/util/first_n.hpp \
cppa/util/has_copy_member_fun.hpp \
cppa/util.hpp \
cppa/util/if_else.hpp \
cppa/util/is_comparable.hpp \
cppa/util/is_copyable.hpp \
cppa/util/is_forward_iterator.hpp \
cppa/util/is_iterable.hpp \
cppa/util/is_legal_tuple_type.hpp \
cppa/util/is_one_of.hpp \
cppa/util/is_primitive.hpp \
cppa/util/pop_back.hpp \
cppa/util/pt_dispatch.hpp \
cppa/util/pt_token.hpp \
cppa/util/remove_const_reference.hpp \
cppa/util/replace_type.hpp \
cppa/util/reverse_type_list.hpp \
cppa/util/ripemd_160.hpp \
cppa/util/rm_ref.hpp \
cppa/util/shared_lock_guard.hpp \
cppa/util/shared_spinlock.hpp \
cppa/util/single_reader_queue.hpp \
cppa/util/singly_linked_list.hpp \
cppa/util/type_list_apply.hpp \
cppa/util/type_list.hpp \
cppa/util/upgrade_lock_guard.hpp \
cppa/util/void_type.hpp \
cppa/util/wrapped.hpp
libcppa_la_CXXFLAGS = --std=c++0x -pedantic -Wall -Wextra -Werror
libcppa_la_LDFLAGS = -lboost_thread
#!/bin/bash
# some neede variables to create 'Makefile.rules'
HEADERS=""
SOURCES=""
NLINE="\\n"
BSLASH="\\\\"
# appends *.hpp from $1 to $HEADERS
function append_hpp_from()
{
for i in "$1"/*.hpp ; do
HEADERS="$HEADERS ${BSLASH}${NLINE} $i"
done
}
# appends *.cpp from $1 to $SOURCES
function append_cpp_from()
{
for i in "$1/"*.cpp ; do
SOURCES="$SOURCES ${BSLASH}${NLINE} $i"
done
}
# default flags
gcc_flags="-std=c++0x -pedantic -Wall -Wextra -g -O0 -I/opt/local/include/ -fpermissive -Wno-deprecated-declarations"
# get all g++ binaries
gcc_found=$(find /bin/ /usr/bin /usr/local/bin /opt/bin /opt/local/bin -regex "^.*/g\+\+.*$" 2>/dev/null)
# holds the finally selected g++ binary
gcc_selected=""
# checks if g++ binary $1 is able to compile cpp0x_test.cpp
function compatibility_test()
{
if $1 $gcc_flags -o cpp0x_test cpp0x_test.cpp &>/dev/null ; then
if test "$(./cpp0x_test)" "!=" "yes" ; then
return -1
else
return 0
fi
fi
}
# iterates over all found g++ binaries until a suitable binary is found
for i in $gcc_found ; do
version=$($i -v 2>&1 | grep -oE "gcc version [0-9](\.[0-9]){2}" | grep -oE "[0-9](\.[0-9]){2}")
if test "!" $version "<" 4.6.0 ; then
if compatibility_test "$i" ; then
gcc_selected=$i
break
fi
fi
done
# did we found a suitable g++ binary?
if test -z "$gcc_selected" ; then
echo "no GCC >= 4.6.0 found ... quit"
exit
fi
echo "chosen g++ binary: $gcc_selected"
# ok, write makefiles now
echo "build Makefiles..."
# link file descriptor #6 to stdout
exec 6>&1
# redirect stdout to Makefile.rules
exec >Makefile.rules
printf "%b\n" "CXX = $gcc_selected"
printf "%b\n" "CXXFLAGS = $gcc_flags"
if test $(uname) = "Darwin" ; then
printf "%b\n" "LIBS = -L/opt/local/lib -lboost_thread-mt"
else
printf "%b\n" "LIBS = -lboost_thread"
fi
# redirect stdout to libcppa.Makefile
exec >libcppa.Makefile
append_hpp_from "cppa"
append_hpp_from "cppa/detail"
append_hpp_from "cppa/util"
append_cpp_from "src"
printf "%b\n" "include Makefile.rules"
printf "%b\n" "INCLUDE_FLAGS = \$(INCLUDES) -I./"
printf "\n"
printf "%b\n" "HEADERS =$HEADERS"
printf "\n"
printf "%b\n" "SOURCES =$SOURCES"
printf "\n"
printf "%b\n" "OBJECTS = \$(SOURCES:.cpp=.o)"
printf "\n"
printf "%b\n" "LIB_NAME = $LIB_NAME"
printf "\n"
printf "%b\n" "%.o : %.cpp \$(HEADERS)"
printf "%b\n" "\t\$(CXX) \$(CXXFLAGS) \$(INCLUDE_FLAGS) -fPIC -c \$< -o \$@"
printf "\n"
printf "%b\n" "libcppa.so.0.0.0 : \$(OBJECTS) \$(HEADERS)"
if test "$(uname)" "=" "Darwin" ; then
printf "%b\n" "\t\$(CXX) \$(LIBS) -dynamiclib -o libcppa.dylib \$(OBJECTS)"
else
printf "%b\n" "\t\$(CXX) \$(LIBS) -shared -Wl,-soname,libcppa.so.0 -o libcppa.so.0.0.0 \$(OBJECTS)"
printf "%b\n" "\tln -s libcppa.so.0.0.0 libcppa.so.0.0"
printf "%b\n" "\tln -s libcppa.so.0.0.0 libcppa.so.0"
printf "%b\n" "\tln -s libcppa.so.0.0.0 libcppa.so"
fi
printf "\n"
printf "%b\n" "all : libcppa.so.0.0.0 \$(OBJECTS)"
printf "\n"
printf "%b\n" "clean:"
printf "%b\n" "\trm -f libcppa.so libcppa.so.0 libcppa.so.0.0 libcppa.so.0.0.0 \$(OBJECTS)"
# redirect stdout to Makefile
exec >Makefile
printf "%b\n" "all:"
printf "%b\n" "\tmake -f libcppa.Makefile"
printf "%b\n" "\tmake -C unit_testing"
printf "%b\n" "\tmake -C queue_performances"
printf "\n"
printf "%b\n" "clean:"
printf "%b\n" "\tmake -f libcppa.Makefile clean"
printf "%b\n" "\tmake -C unit_testing clean"
printf "%b\n" "\tmake -C queue_performances clean"
# restore stdout
exec 1>&6
echo "done"
AC_INIT([libcppa], [1.0.0])
AM_INIT_AUTOMAKE
AC_PROG_CXX
AC_PROG_LIBTOOL
AC_LANG([C++])
ORIGINAL_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS -Werror --std=c++0x"
AC_CACHE_CHECK(
[whether C++ compiler supports variadic templates],
[ac_cv_cpp_variadic_templates],
AC_COMPILE_IFELSE([[#include "variadic_templates_test.cpp"]],
[ac_cv_cpp_variadic_templates=yes],
[ac_cv_cpp_variadic_templates=no]))
AC_CACHE_CHECK(
[whether C++ compiler supports nullptr],
[ac_cv_cpp_nullptr],
AC_COMPILE_IFELSE([[static void* myptr = nullptr;]],
[ac_cv_cpp_nullptr=yes],
[ac_cv_cpp_nullptr=no]))
AS_IF(
[test "x$ac_cv_cpp_variadic_templates" = "xyes" &&
test "x$ac_cv_cpp_nullptr" = "xyes"],
[],
[AC_MSG_ERROR([at least one required C++ compiler feature is not supported])])
CPPFLAGS="$ORIGINAL_CPPFLAGS"
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
// ADD PREDEFINED MACROS HERE!
cppa/ref_counted.hpp
cppa/tuple.hpp
unit_testing/main.cpp
cppa/util/void_type.hpp
cppa/util/type_list.hpp
cppa/util/a_matches_b.hpp
cppa/util.hpp
cppa/util/is_one_of.hpp
cppa/util/conjunction.hpp
cppa/util/disjunction.hpp
unit_testing/test.hpp
unit_testing/test__a_matches_b.cpp
cppa/uniform_type_info.hpp
src/uniform_type_info.cpp
cppa/config.hpp
unit_testing/test__tuple.cpp
cppa/detail/abstract_tuple.hpp
cppa/tuple_view.hpp
cppa/any_type.hpp
cppa/detail/matcher.hpp
cppa/detail/tuple_vals.hpp
cppa/match.hpp
cppa/detail/decorated_tuple.hpp
cppa/cow_ptr.hpp
cppa/detail/ref_counted_impl.hpp
cppa/intrusive_ptr.hpp
unit_testing/test__spawn.cpp
src/mock_scheduler.cpp
cppa/actor.hpp
cppa/message.hpp
unit_testing/test__intrusive_ptr.cpp
cppa/util/concat_type_lists.hpp
cppa/util/filter_type_list.hpp
cppa/util/is_comparable.hpp
cppa/util/callable_trait.hpp
cppa/util/reverse_type_list.hpp
unit_testing/test__type_list.cpp
cppa/util/remove_const_reference.hpp
cppa/util/type_list_apply.hpp
cppa/util/eval_type_lists.hpp
cppa/util/compare_tuples.hpp
cppa/get.hpp
cppa/detail/tdata.hpp
cppa/util/is_copyable.hpp
cppa/util/has_copy_member_fun.hpp
cppa/detail/intermediate.hpp
cppa/detail/invokable.hpp
cppa/invoke_rules.hpp
cppa/invoke.hpp
cppa/on.hpp
unit_testing/test__serialization.cpp
cppa/serializer.hpp
cppa/deserializer.hpp
cppa/util/enable_if.hpp
cppa/object.hpp
cppa/detail/object_impl.hpp
cppa/detail/swap_bytes.hpp
src/serializer.cpp
src/deserializer.cpp
cppa/util/eval_type_list.hpp
cppa/util/is_legal_tuple_type.hpp
cppa/util/replace_type.hpp
cppa/util/abstract_type_list.hpp
cppa/detail/serialize_tuple.hpp
unit_testing/test__atom.cpp
unit_testing/test__queue_performance.cpp
cppa/util/single_reader_queue.hpp
cppa/util/singly_linked_list.hpp
unit_testing/test__local_group.cpp
unit_testing/hash_of.cpp
unit_testing/hash_of.hpp
cppa/detail/channel.hpp
cppa/util/first_n.hpp
cppa/util/eval_first_n.hpp
cppa/context.hpp
cppa/channel.hpp
src/channel.cpp
cppa/actor_behavior.hpp
cppa/message_queue.hpp
cppa/cppa.hpp
cppa/scheduling_hint.hpp
src/actor_behavior.cpp
cppa/group.hpp
src/group.cpp
queue_performances/main.cpp
queue_performances/sutter_list.hpp
queue_performances/defines.hpp
queue_performances/cached_stack.hpp
queue_performances/blocking_cached_stack.hpp
queue_performances/blocking_cached_stack2.hpp
queue_performances/blocking_sutter_list.hpp
queue_performances/lockfree_list.hpp
queue_performances/intrusive_sutter_list.hpp
src/context.cpp
cppa/scheduler.hpp
cppa/detail/mock_scheduler.hpp
src/scheduler.cpp
cppa/detail/blocking_message_queue.hpp
src/blocking_message_queue.cpp
cppa/detail/converted_thread_context.hpp
src/converted_thread_context.cpp
unit_testing/test__uniform_type.cpp
cppa/detail/demangle.hpp
src/demangle.cpp
cppa/detail/to_uniform_name.hpp
src/to_uniform_name.cpp
cppa/detail/default_uniform_type_info_impl.hpp
src/object.cpp
cppa/util/comparable.hpp
cppa/util/disable_if.hpp
cppa/util/apply.hpp
cppa/primitive_variant.hpp
cppa/primitive_type.hpp
cppa/util/pt_token.hpp
cppa/detail/type_to_ptype.hpp
cppa/detail/ptype_to_type.hpp
cppa/util/is_primitive.hpp
cppa/util/is_iterable.hpp
src/primitive_variant.cpp
unit_testing/test__primitive_variant.cpp
cppa/detail/primitive_member.hpp
cppa/detail/list_member.hpp
cppa/detail/pair_member.hpp
cppa/detail/map_member.hpp
cppa/util/is_forward_iterator.hpp
cppa/util/rm_ref.hpp
cppa/util/is_iterable.hpp
cppa/binary_serializer.hpp
src/binary_serializer.cpp
cppa/binary_deserializer.hpp
src/binary_deserializer.cpp
src/actor.cpp
cppa/announce.hpp
src/abstract_type_list.cpp
src/message.cpp
cppa/util/shared_spinlock.hpp
src/shared_spinlock.cpp
cppa/util/shared_lock_guard.hpp
cppa/get_view.hpp
cppa/detail/object_array.hpp
src/object_array.cpp
cppa/any_tuple.hpp
src/any_tuple.cpp
cppa/util/abstract_uniform_type_info.hpp
cppa/util/upgrade_lock_guard.hpp
cppa/to_string.hpp
src/string_serialization.cpp
cppa/from_string.hpp
cppa/util/at.hpp
cppa/util/element_at.hpp
cppa/util/if_else.hpp
cppa/util/pop_back.hpp
cppa/util/pt_dispatch.hpp
cppa/detail/get_behavior.hpp
unit_testing/test__ripemd_160.cpp
cppa/process_information.hpp
src/process_information.cpp
cppa/util/ripemd_160.hpp
src/ripemd_160.cpp
src/unicast_network.cpp
unit_testing/test__remote_actor.cpp
unit_testing/ping_pong.hpp
unit_testing/ping_pong.cpp
cppa/exception.hpp
src/exception.cpp
cppa/actor_proxy.hpp
src/actor_proxy.cpp
cppa/detail/actor_proxy_cache.hpp
src/actor_proxy_cache.cpp
src/attachable.cpp
cppa/attachable.hpp
cppa/atom.hpp
cppa/detail/atom_val.hpp
src/atom.cpp
src/cppa.cpp
cppa/exit_reason.hpp
cppa/detail/abstract_actor.hpp
cppa/detail/mailman.hpp
src/mailman.cpp
cppa/detail/native_socket.hpp
src/native_socket.cpp
cppa/detail/post_office.hpp
src/post_office.cpp
cppa/detail/buffer.hpp
cppa/detail/task_scheduler.hpp
src/task_scheduler.cpp
cppa/detail/actor_count.hpp
src/actor_count.cpp
cppa/util/fiber.hpp
src/fiber.cpp
cppa/detail/yield_interface.hpp
src/yield_interface.cpp
cppa/detail/yielding_message_queue.hpp
src/yielding_message_queue.cpp
cppa/detail/scheduled_actor.hpp
src/scheduled_actor.cpp
src/intermediate.cpp
cppa/detail/abstract_message_queue.hpp
src/message_queue.cpp
src/invokable.cpp
cppa/detail/thread_pool_scheduler.hpp
src/thread_pool_scheduler.cpp
cppa/detail/delegate.hpp
src/delegate.cpp
cppa/detail/receive_loop_helper.hpp
cppa/util/wrapped.hpp
cppa/util/any_tuple_iterator.hpp
src/any_tuple_iterator.cpp
cppa/detail/boxed.hpp
cppa/detail/unboxed.hpp
cppa/detail/matcher_arguments.hpp
src/matcher_arguments.cpp
/Users/neverlord/libcppa
/home/neverlord/libcppa
/opt/local/include/gcc46/c++
/opt/local/include/
/Users/neverlord/libcppa/unit_testing
/home/neverlord/libcppa/unit_testing
#ifndef ACTOR_COUNT_HPP
#define ACTOR_COUNT_HPP
#include <atomic>
#include <boost/thread.hpp>
#include "cppa/attachable.hpp"
namespace cppa { namespace detail {
void inc_actor_count();
void dec_actor_count();
class actor_count {
public:
actor_count();
void inc();
void dec();
// @pre expected <= 1
void actor_count_wait_until(size_t expected);
// @pre expected <= 1
void wait_until(size_t expected);
static actor_count& get();
private:
static actor_count* s_instance;
boost::mutex m_ra_mtx;
boost::condition_variable m_ra_cv;
std::atomic<size_t> m_running_actors;
};
struct exit_observer : cppa::attachable
{
......
......@@ -11,16 +11,67 @@
namespace {
std::atomic<std::uint32_t> s_ids(1);
std::map<std::uint32_t, cppa::actor*> s_instances;
cppa::util::shared_spinlock s_instances_mtx;
typedef std::lock_guard<cppa::util::shared_spinlock> exclusive_guard;
typedef cppa::util::shared_lock_guard<cppa::util::shared_spinlock> shared_guard;
} // namespace <anonmyous>
namespace cppa {
class actors_registry
{
public:
actors_registry() : m_ids(1)
{
}
void add(actor& act)
{
exclusive_guard guard(m_instances_mtx);
m_instances.insert(std::make_pair(act.id(), &act));
}
void remove(actor& act)
{
exclusive_guard guard(m_instances_mtx);
m_instances.erase(act.id());
}
intrusive_ptr<actor> find(std::uint32_t actor_id)
{
shared_guard guard(m_instances_mtx);
auto i = m_instances.find(actor_id);
if (i != m_instances.end())
{
return i->second;
}
return nullptr;
}
std::uint32_t next_id()
{
return m_ids.fetch_add(1);
}
static actors_registry* s_instance;
static inline actors_registry& get()
{
return *s_instance;
}
private:
std::atomic<std::uint32_t> m_ids;
std::map<std::uint32_t, cppa::actor*> m_instances;
cppa::util::shared_spinlock m_instances_mtx;
};
// TODO: free
actors_registry* actors_registry::s_instance = new actors_registry();
actor::actor(std::uint32_t aid, const process_information_ptr& pptr)
: m_is_proxy(true), m_id(aid), m_parent_process(pptr)
......@@ -32,7 +83,7 @@ actor::actor(std::uint32_t aid, const process_information_ptr& pptr)
}
actor::actor(const process_information_ptr& pptr)
: m_is_proxy(false), m_id(s_ids.fetch_add(1)), m_parent_process(pptr)
: m_is_proxy(false), m_id(actors_registry::get().next_id()), m_parent_process(pptr)
{
if (!pptr)
{
......@@ -40,8 +91,7 @@ actor::actor(const process_information_ptr& pptr)
}
else
{
exclusive_guard guard(s_instances_mtx);
s_instances.insert(std::make_pair(m_id, this));
actors_registry::get().add(*this);
}
}
......@@ -49,20 +99,13 @@ actor::~actor()
{
if (!m_is_proxy)
{
exclusive_guard guard(s_instances_mtx);
s_instances.erase(m_id);
actors_registry::get().remove(*this);
}
}
intrusive_ptr<actor> actor::by_id(std::uint32_t actor_id)
{
shared_guard guard(s_instances_mtx);
auto i = s_instances.find(actor_id);
if (i != s_instances.end())
{
return i->second;
}
return nullptr;
return actors_registry::get().find(actor_id);
}
void actor::join(group_ptr& what)
......
#include <limits>
#include <atomic>
#include <stdexcept>
#include <boost/thread.hpp>
#include "cppa/detail/actor_count.hpp"
namespace {
boost::mutex s_ra_mtx;
boost::condition_variable s_ra_cv;
std::atomic<size_t> s_running_actors(0);
typedef boost::unique_lock<boost::mutex> guard_type;
} // namespace <anonymous>
namespace cppa { namespace detail {
void inc_actor_count()
// TODO: free
actor_count* actor_count::s_instance = new actor_count();
actor_count& actor_count::get()
{
return *s_instance;
}
actor_count::actor_count() : m_running_actors(0)
{
}
void actor_count::inc()
{
++s_running_actors;
++m_running_actors;
}
void dec_actor_count()
void actor_count::dec()
{
size_t new_val = --s_running_actors;
size_t new_val = --m_running_actors;
if (new_val == std::numeric_limits<size_t>::max())
{
throw std::underflow_error("dec_actor_count()");
throw std::underflow_error("actor_count::dec()");
}
else if (new_val <= 1)
{
guard_type guard(s_ra_mtx);
s_ra_cv.notify_all();
guard_type guard(m_ra_mtx);
m_ra_cv.notify_all();
}
}
void actor_count_wait_until(size_t expected)
void actor_count::wait_until(size_t expected)
{
guard_type lock(s_ra_mtx);
while (s_running_actors.load() != expected)
guard_type lock(m_ra_mtx);
while (m_running_actors.load() != expected)
{
s_ra_cv.wait(lock);
m_ra_cv.wait(lock);
}
}
exit_observer::~exit_observer()
{
cppa::detail::dec_actor_count();
actor_count::get().dec();
}
} } // namespace cppa::detail
......@@ -4,13 +4,36 @@
#include "cppa/message.hpp"
#include "cppa/detail/actor_proxy_cache.hpp"
namespace {
namespace cppa { namespace detail {
boost::thread_specific_ptr<cppa::detail::actor_proxy_cache> t_proxy_cache;
class actor_proxy_caches {
} // namespace <anonymous>
public:
namespace cppa { namespace detail {
actor_proxy_cache& get_actor_proxy_cache()
{
if (m_proxy_cache.get() == nullptr)
{
m_proxy_cache.reset(new actor_proxy_cache);
}
return *m_proxy_cache.get();
}
static actor_proxy_caches& get()
{
return *s_instance;
}
private:
static actor_proxy_caches* s_instance;
boost::thread_specific_ptr<cppa::detail::actor_proxy_cache> m_proxy_cache;
};
// TODO: free
actor_proxy_caches* actor_proxy_caches::s_instance = new actor_proxy_caches();
process_information_ptr
actor_proxy_cache::get_pinfo(const actor_proxy_cache::key_tuple& key)
......@@ -65,11 +88,7 @@ size_t actor_proxy_cache::size() const
actor_proxy_cache& get_actor_proxy_cache()
{
if (t_proxy_cache.get() == nullptr)
{
t_proxy_cache.reset(new actor_proxy_cache);
}
return *t_proxy_cache.get();
return actor_proxy_caches::get().get_actor_proxy_cache();
}
} } // namespace cppa::detail
......@@ -126,7 +126,7 @@ void mailman_loop()
// disconnect peer if send() failed
disconnect_peer = (sent <= 0);
// make sure all bytes are written
if (sent != size32)
if (static_cast<std::uint32_t>(sent) != size32)
{
throw std::logic_error("send() not a synchronous socket");
}
......
......@@ -34,7 +34,7 @@ void run_actor(cppa::intrusive_ptr<cppa::context> m_self,
catch (...) { }
delete behavior;
}
cppa::detail::dec_actor_count();
cppa::detail::actor_count::get().dec();
}
} // namespace <anonymous>
......@@ -43,7 +43,7 @@ namespace cppa { namespace detail {
actor_ptr mock_scheduler::spawn(actor_behavior* behavior)
{
inc_actor_count();
actor_count::get().inc();
CPPA_MEMORY_BARRIER();
intrusive_ptr<context> ctx(new detail::converted_thread_context);
boost::thread(run_actor, ctx, behavior).detach();
......
#include <atomic>
#ifndef _GLIBCXX_HAS_GTHREADS
#define _GLIBCXX_HAS_GTHREADS
#endif
#include <mutex>
#include "cppa/context.hpp"
......@@ -41,21 +43,21 @@ scheduler::~scheduler()
void scheduler::await_others_done()
{
detail::actor_count_wait_until((unchecked_self() == nullptr) ? 0 : 1);
detail::actor_count::get().wait_until((unchecked_self() == nullptr) ? 0 : 1);
}
void scheduler::register_converted_context(context* what)
{
if (what)
{
detail::inc_actor_count();
detail::actor_count::get().inc();
what->attach(new detail::exit_observer);
}
}
attachable* scheduler::register_hidden_context()
{
detail::inc_actor_count();
detail::actor_count::get().inc();
return new detail::exit_observer;
}
......
......@@ -40,7 +40,7 @@ void task_scheduler::worker_loop(job_queue* jq, scheduled_actor* dummy)
{
if (!job->deref()) delete job;
CPPA_MEMORY_BARRIER();
dec_actor_count();
actor_count::get().dec();
});
}
}
......@@ -75,7 +75,7 @@ void task_scheduler::schedule(scheduled_actor* what)
actor_ptr task_scheduler::spawn(actor_behavior* behavior, scheduling_hint)
{
inc_actor_count();
actor_count::get().inc();
intrusive_ptr<scheduled_actor> ctx(new scheduled_actor(behavior,
enqueue_fun,
this));
......
......@@ -78,7 +78,7 @@ struct thread_pool_scheduler::worker
{
if (!m_job->deref()) delete m_job;
CPPA_MEMORY_BARRIER();
dec_actor_count();
actor_count::get().dec();
});
if (reschedule)
{
......@@ -184,7 +184,7 @@ actor_ptr thread_pool_scheduler::spawn(actor_behavior* behavior,
}
else
{
inc_actor_count();
actor_count::get().inc();
CPPA_MEMORY_BARRIER();
intrusive_ptr<scheduled_actor> ctx(new scheduled_actor(behavior,
enqueue_fun,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment