Commit 7893d7a1 authored by neverlord's avatar neverlord

improve group handling

parent 466b6322
...@@ -60,15 +60,15 @@ ...@@ -60,15 +60,15 @@
<valuemap type="QVariantMap"> <valuemap type="QVariantMap">
<value key="ProjectExplorer.BuildConfiguration.DisplayName" type="QString">all</value> <value key="ProjectExplorer.BuildConfiguration.DisplayName" type="QString">all</value>
<valuelist key="abstractProcess.Environment" type="QVariantList"> <valuelist key="abstractProcess.Environment" type="QVariantList">
<value type="QString">Apple_PubSub_Socket_Render=/tmp/launch-Ii2KqP/Render</value> <value type="QString">Apple_PubSub_Socket_Render=/tmp/launch-gSC9AO/Render</value>
<value type="QString">COMMAND_MODE=unix2003</value> <value type="QString">COMMAND_MODE=unix2003</value>
<value type="QString">DISPLAY=/tmp/launch-6FAyZP/org.x:0</value> <value type="QString">DISPLAY=/tmp/launch-1vsPWG/org.x:0</value>
<value type="QString">HOME=/Users/neverlord</value> <value type="QString">HOME=/Users/neverlord</value>
<value type="QString">LOGNAME=neverlord</value> <value type="QString">LOGNAME=neverlord</value>
<value type="QString">PATH=/usr/bin:/bin:/usr/sbin:/sbin</value> <value type="QString">PATH=/usr/bin:/bin:/usr/sbin:/sbin</value>
<value type="QString">SHELL=/bin/bash</value> <value type="QString">SHELL=/bin/bash</value>
<value type="QString">SSH_AUTH_SOCK=/tmp/launch-vifjfO/Listeners</value> <value type="QString">SSH_AUTH_SOCK=/tmp/launch-H5MBik/Listeners</value>
<value type="QString">TMPDIR=/var/folders/1p/1p6iuPgbH7GoDkrjrT20tU+++TI/-Tmp-/</value> <value type="QString">TMPDIR=/var/folders/SE/SEReyCW0H-yDPCnNCe8mN++++TI/-Tmp-/</value>
<value type="QString">USER=neverlord</value> <value type="QString">USER=neverlord</value>
<value type="QString">__CF_USER_TEXT_ENCODING=0x1F5:0:3</value> <value type="QString">__CF_USER_TEXT_ENCODING=0x1F5:0:3</value>
</valuelist> </valuelist>
......
...@@ -88,3 +88,8 @@ cppa/reply.hpp ...@@ -88,3 +88,8 @@ cppa/reply.hpp
unit_testing/test__local_group.cpp unit_testing/test__local_group.cpp
unit_testing/hash_of.cpp unit_testing/hash_of.cpp
cppa/spawn.hpp cppa/spawn.hpp
unit_testing/hash_of.hpp
cppa/detail/channel.hpp
cppa/message_receiver.hpp
src/message_receiver.cpp
src/actor.cpp
#ifndef ACTOR_HPP #ifndef ACTOR_HPP
#define ACTOR_HPP #define ACTOR_HPP
#include "cppa/tuple.hpp" #include "cppa/message_receiver.hpp"
#include "cppa/intrusive_ptr.hpp"
#include "cppa/detail/actor_public.hpp" #include "cppa/detail/actor_public.hpp"
#include "cppa/detail/actor_private.hpp" #include "cppa/detail/actor_private.hpp"
namespace cppa { namespace cppa {
class actor class actor : public message_receiver
{ {
typedef message_receiver super;
public: public:
typedef cppa::intrusive_ptr<detail::actor_public> ptr_type; typedef cppa::intrusive_ptr<detail::actor_public> ptr_type;
actor() = default; actor() = default;
inline actor(detail::actor_public* ptr) : m_ptr(ptr) { } inline actor(detail::actor_public* ptr) : super(ptr) { }
inline actor(const ptr_type& ptr) : m_ptr(ptr) { }
inline actor(ptr_type&& ptr) : m_ptr(ptr) { }
actor(const actor&) = default;
inline actor(actor&& other) : m_ptr(std::move(other.m_ptr)) { } inline actor(const ptr_type& ptr) : super(ptr) { }
actor& operator=(const actor&) = default; inline actor(ptr_type&& ptr) : super(ptr) { }
actor& operator=(actor&& other) inline actor(const actor& other) : super(other) { }
{
m_ptr = std::move(other.m_ptr);
return *this;
}
template<typename... Args> inline actor(actor&& other) : super(other) { }
void send(const Args&... args)
{
this_actor()->send(m_ptr.get(), tuple<Args...>(args...));
}
template<typename... Args> actor& operator=(const actor&);
void send_tuple(const tuple<Args...>& args)
{
this_actor()->send(m_ptr.get(), args);
}
inline bool operator==(const actor& other) const actor& operator=(actor&& other);
{
return m_ptr == other.m_ptr;
}
private:
ptr_type m_ptr;
}; };
/*
template<typename... Args>
actor& operator<<(actor& whom, const tuple<Args...>& data)
{
whom.send_tuple(data);
}
*/
} // namespace cppa } // namespace cppa
#endif // ACTOR_HPP #endif // ACTOR_HPP
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
#include "cppa/invoke_rules.hpp" #include "cppa/invoke_rules.hpp"
#include "cppa/untyped_tuple.hpp" #include "cppa/untyped_tuple.hpp"
#include "cppa/detail/channel.hpp"
#include "cppa/detail/actor_public.hpp" #include "cppa/detail/actor_public.hpp"
namespace cppa { class message; } namespace cppa { class message; }
...@@ -15,7 +17,7 @@ struct actor_private : public actor_public ...@@ -15,7 +17,7 @@ struct actor_private : public actor_public
virtual const message& receive() = 0; virtual const message& receive() = 0;
virtual const message& last_dequeued() const = 0; virtual const message& last_dequeued() const = 0;
virtual void receive(invoke_rules&) = 0; virtual void receive(invoke_rules&) = 0;
virtual void send(actor_public* whom, untyped_tuple&& what) = 0; virtual void send(channel* whom, untyped_tuple&& what) = 0;
}; };
} } // namespace cppa::detail } } // namespace cppa::detail
......
#ifndef ACTOR_PUBLIC_HPP #ifndef ACTOR_PUBLIC_HPP
#define ACTOR_PUBLIC_HPP #define ACTOR_PUBLIC_HPP
#include "cppa/ref_counted.hpp" #include "cppa/detail/channel.hpp"
namespace cppa { class message; }
namespace cppa { namespace detail { namespace cppa { namespace detail {
// public part of the actor interface // public part of the actor interface
struct actor_public : ref_counted struct actor_public : channel
{ {
virtual void enqueue_msg(const message& msg) = 0; virtual void enqueue_msg(const message& msg) = 0;
}; };
......
#ifndef CHANNEL_HPP
#define CHANNEL_HPP
#include "cppa/ref_counted.hpp"
namespace cppa { class message; }
namespace cppa { namespace detail {
// public part of the actor interface
struct channel : ref_counted
{
virtual void enqueue_msg(const message& msg) = 0;
};
} } // namespace cppa::detail
#endif // CHANNEL_HPP
...@@ -5,6 +5,9 @@ ...@@ -5,6 +5,9 @@
#include "cppa/tuple.hpp" #include "cppa/tuple.hpp"
#include "cppa/untyped_tuple.hpp" #include "cppa/untyped_tuple.hpp"
#include "cppa/intrusive_ptr.hpp" #include "cppa/intrusive_ptr.hpp"
#include "cppa/message_receiver.hpp"
#include "cppa/detail/channel.hpp"
namespace cppa { namespace cppa {
...@@ -16,13 +19,14 @@ class message ...@@ -16,13 +19,14 @@ class message
struct content : ref_counted struct content : ref_counted
{ {
const actor sender; const actor sender;
const actor receiver; const message_receiver receiver;
const untyped_tuple data; const untyped_tuple data;
content(const actor& s, const actor& r, const untyped_tuple& ut) content(const actor& s, const message_receiver& r,
const untyped_tuple& ut)
: sender(s), receiver(r), data(ut) : sender(s), receiver(r), data(ut)
{ {
} }
content(const actor& s, const actor& r, untyped_tuple&& ut) content(const actor& s, const message_receiver& r, untyped_tuple&& ut)
: sender(s), receiver(r), data(ut) : sender(s), receiver(r), data(ut)
{ {
} }
...@@ -35,22 +39,22 @@ class message ...@@ -35,22 +39,22 @@ class message
public: public:
template<typename... Args> template<typename... Args>
message(const actor& from, const actor& to, const Args&... args) message(const actor& from, const message_receiver& to, const Args&... args)
: m_content(new content(from, to, tuple<Args...>(args...))) { } : m_content(new content(from, to, tuple<Args...>(args...))) { }
message(const actor& from, const actor& to, const untyped_tuple& ut) message(const actor& from, const message_receiver& to, const untyped_tuple& ut)
: m_content(new content(from, to, ut)) { } : m_content(new content(from, to, ut)) { }
message(const actor& from, const actor& to, untyped_tuple&& ut) message(const actor& from, const message_receiver& to, untyped_tuple&& ut)
: m_content(new content(from, to, std::move(ut))) { } : m_content(new content(from, to, std::move(ut))) { }
message() : m_content(new content(actor(), actor(), tuple<int>(0))) { } message() : m_content(new content(0, 0, tuple<int>(0))) { }
const actor& sender() const const actor& sender() const
{ {
return m_content->sender; return m_content->sender;
} }
const actor& receiver() const const message_receiver& receiver() const
{ {
return m_content->receiver; return m_content->receiver;
} }
......
#ifndef MESSAGE_RECEIVER_HPP
#define MESSAGE_RECEIVER_HPP
#include "cppa/tuple.hpp"
#include "cppa/intrusive_ptr.hpp"
#include "cppa/detail/channel.hpp"
#include "cppa/detail/comparable.hpp"
#include "cppa/detail/actor_private.hpp"
namespace cppa {
class message_receiver :
detail::comparable<message_receiver, intrusive_ptr<detail::channel>>,
detail::comparable<message_receiver, message_receiver>
{
protected:
intrusive_ptr<detail::channel> m_channel;
public:
inline message_receiver(detail::channel* ch_ptr) : m_channel(ch_ptr) { }
inline message_receiver(const intrusive_ptr<detail::channel>& ch_ptr)
: m_channel(ch_ptr)
{
}
inline message_receiver(intrusive_ptr<detail::channel>&& ch_ptr)
: m_channel(std::move(ch_ptr))
{
}
message_receiver() = default;
message_receiver(message_receiver&&) = default;
message_receiver(const message_receiver&) = default;
message_receiver& operator=(const message_receiver&) = default;
message_receiver& operator=(detail::channel*);
message_receiver& operator=(const intrusive_ptr<detail::channel>&);
message_receiver& operator=(intrusive_ptr<detail::channel>&&);
void enqueue_msg(const message& msg)
{
m_channel->enqueue_msg(msg);
}
template<typename... Args>
void send(const Args&... args)
{
this_actor()->send(m_channel.get(), tuple<Args...>(args...));
}
inline bool equal_to(const intrusive_ptr<detail::channel>& ch_ptr) const
{
return m_channel == ch_ptr;
}
inline bool equal_to(const message_receiver& other) const
{
return m_channel == other.m_channel;
}
};
} // namespace cppa
#endif // MESSAGE_RECEIVER_HPP
#ifndef SPAWN_HPP
#define SPAWN_HPP
#include <functional>
#include "cppa/actor.hpp"
#include "cppa/detail/scheduler.hpp"
using std::cout;
using std::endl;
using namespace cppa;
template<typename F>
actor spawn(F act_fun)
{
struct bhv : cppa::detail::behavior
{
std::function<void ()> m_act;
bhv(const F& invokable) : m_act(invokable) { }
virtual void act()
{
m_act();
}
virtual void on_exit()
{
}
};
return cppa::detail::spawn_impl(new bhv(act_fun));
}
#endif // SPAWN_HPP
...@@ -23,6 +23,7 @@ HEADERS = cppa/actor.hpp \ ...@@ -23,6 +23,7 @@ HEADERS = cppa/actor.hpp \
cppa/util.hpp \ cppa/util.hpp \
cppa/detail/abstract_tuple.hpp \ cppa/detail/abstract_tuple.hpp \
cppa/detail/decorated_tuple.hpp \ cppa/detail/decorated_tuple.hpp \
cppa/detail/channel.hpp \
cppa/detail/intermediate.hpp \ cppa/detail/intermediate.hpp \
cppa/detail/invokable.hpp \ cppa/detail/invokable.hpp \
cppa/detail/matcher.hpp \ cppa/detail/matcher.hpp \
...@@ -53,8 +54,10 @@ HEADERS = cppa/actor.hpp \ ...@@ -53,8 +54,10 @@ HEADERS = cppa/actor.hpp \
cppa/util/utype_iterator.hpp \ cppa/util/utype_iterator.hpp \
cppa/util/void_type.hpp cppa/util/void_type.hpp
SOURCES = src/decorated_tuple.cpp \ SOURCES = src/actor.cpp \
src/decorated_tuple.cpp \
src/deserializer.cpp \ src/deserializer.cpp \
src/message_receiver.cpp \
src/mock_scheduler.cpp \ src/mock_scheduler.cpp \
src/ref_counted.cpp \ src/ref_counted.cpp \
src/serializer.cpp \ src/serializer.cpp \
......
#include "cppa/actor.hpp"
namespace cppa {
actor& actor::operator=(const actor& other)
{
static_cast<super&>(*this) = other;
return *this;
}
actor& actor::operator=(actor&& other)
{
static_cast<super&>(*this) = other;
return *this;
}
} // namespace cppa
#include "cppa/message_receiver.hpp"
namespace cppa {
message_receiver& message_receiver::operator=(detail::channel* ch_ptr)
{
m_channel.reset(ch_ptr);
return *this;
}
message_receiver&
message_receiver::operator=(const intrusive_ptr<detail::channel>& ch_ptr)
{
m_channel = ch_ptr;
return *this;
}
message_receiver&
message_receiver::operator=(intrusive_ptr<detail::channel>&& ch_ptr)
{
m_channel.swap(ch_ptr);
return *this;
}
} // namespace cppa
...@@ -20,7 +20,6 @@ void cleanup_fun(actor_impl* what); ...@@ -20,7 +20,6 @@ void cleanup_fun(actor_impl* what);
boost::thread_specific_ptr<actor_impl> m_this_actor(cleanup_fun); boost::thread_specific_ptr<actor_impl> m_this_actor(cleanup_fun);
struct actor_impl : cppa::detail::actor_private struct actor_impl : cppa::detail::actor_private
{ {
...@@ -66,7 +65,7 @@ struct actor_impl : cppa::detail::actor_private ...@@ -66,7 +65,7 @@ struct actor_impl : cppa::detail::actor_private
mailbox.prepend(std::move(buffer)); mailbox.prepend(std::move(buffer));
} }
virtual void send(cppa::detail::actor_public* whom, virtual void send(cppa::detail::channel* whom,
cppa::untyped_tuple&& what) cppa::untyped_tuple&& what)
{ {
if (whom) whom->enqueue_msg(cppa::message(this, whom, std::move(what))); if (whom) whom->enqueue_msg(cppa::message(this, whom, std::move(what)));
......
...@@ -7,7 +7,8 @@ INCLUDES = -I./ -I../ ...@@ -7,7 +7,8 @@ INCLUDES = -I./ -I../
EXECUTABLE = ../test EXECUTABLE = ../test
HEADERS = test.hpp HEADERS = hash_of.hpp \
test.hpp
SOURCES = hash_of.cpp \ SOURCES = hash_of.cpp \
main.cpp \ main.cpp \
......
#include "hash_of.hpp"
unsigned int MurmurHash2 ( const void * key, int len, unsigned int seed )
{
static_assert(sizeof(int) == 4,
"MurmurHash2 requires sizeof(int) == 4");
// 'm' and 'r' are mixing constants generated offline.
// They're not really 'magic', they just happen to work well.
const unsigned int m = 0x5bd1e995;
const int r = 24;
// Initialize the hash to a 'random' value
unsigned int h = seed ^ len;
// Mix 4 bytes at a time into the hash
const unsigned char * data = (const unsigned char *)key;
while(len >= 4)
{
unsigned int k = *(unsigned int *)data;
k *= m;
k ^= k >> r;
k *= m;
h *= m;
h ^= k;
data += 4;
len -= 4;
}
// Handle the last few bytes of the input array
switch(len)
{
case 3: h ^= data[2] << 16;
case 2: h ^= data[1] << 8;
case 1: h ^= data[0];
h *= m;
};
// Do a few final mixes of the hash to ensure the last few
// bytes are well-incorporated.
h ^= h >> 13;
h *= m;
h ^= h >> 15;
return h;
}
unsigned int hash_of(const char* what, int what_length)
{
return MurmurHash2(what, what_length, 0x15091984);
}
unsigned int hash_of(const std::string& what)
{
return MurmurHash2(what.c_str(), what.size(), 0x15091984);
}
#ifndef HASH_OF_HPP
#define HASH_OF_HPP
#include <string>
unsigned int hash_of(const std::string& what);
unsigned int hash_of(const char* what, int what_length);
#endif // HASH_OF_HPP
...@@ -19,7 +19,7 @@ using std::endl; ...@@ -19,7 +19,7 @@ using std::endl;
using namespace cppa; using namespace cppa;
class group : public ref_counted class group : public detail::channel
{ {
boost::mutex m_mtx; boost::mutex m_mtx;
...@@ -58,21 +58,26 @@ class group : public ref_counted ...@@ -58,21 +58,26 @@ class group : public ref_counted
} }
} }
template<typename... Args> void enqueue_msg(const message& msg)
void send(const Args&... args)
{ {
boost::mutex::scoped_lock guard(m_mtx); boost::mutex::scoped_lock guard(m_mtx);
for (auto i = m_subscribers.begin(); i != m_subscribers.end(); ++i) for (auto i = m_subscribers.begin(); i != m_subscribers.end(); ++i)
{ {
i->send(args...); i->enqueue_msg(msg);
} }
} }
template<typename... Args>
void send(const Args&... args)
{
message msg(this_actor(), this, args...);
enqueue_msg(msg);
}
}; };
namespace { namespace {
class group_bucket class group_bucket
{ {
......
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