Commit 7893d7a1 authored by neverlord's avatar neverlord

improve group handling

parent 466b6322
......@@ -60,15 +60,15 @@
<valuemap type="QVariantMap">
<value key="ProjectExplorer.BuildConfiguration.DisplayName" type="QString">all</value>
<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">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">LOGNAME=neverlord</value>
<value type="QString">PATH=/usr/bin:/bin:/usr/sbin:/sbin</value>
<value type="QString">SHELL=/bin/bash</value>
<value type="QString">SSH_AUTH_SOCK=/tmp/launch-vifjfO/Listeners</value>
<value type="QString">TMPDIR=/var/folders/1p/1p6iuPgbH7GoDkrjrT20tU+++TI/-Tmp-/</value>
<value type="QString">SSH_AUTH_SOCK=/tmp/launch-H5MBik/Listeners</value>
<value type="QString">TMPDIR=/var/folders/SE/SEReyCW0H-yDPCnNCe8mN++++TI/-Tmp-/</value>
<value type="QString">USER=neverlord</value>
<value type="QString">__CF_USER_TEXT_ENCODING=0x1F5:0:3</value>
</valuelist>
......
......@@ -88,3 +88,8 @@ cppa/reply.hpp
unit_testing/test__local_group.cpp
unit_testing/hash_of.cpp
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
#define ACTOR_HPP
#include "cppa/tuple.hpp"
#include "cppa/intrusive_ptr.hpp"
#include "cppa/message_receiver.hpp"
#include "cppa/detail/actor_public.hpp"
#include "cppa/detail/actor_private.hpp"
namespace cppa {
class actor
class actor : public message_receiver
{
typedef message_receiver super;
public:
typedef cppa::intrusive_ptr<detail::actor_public> ptr_type;
actor() = default;
inline actor(detail::actor_public* ptr) : m_ptr(ptr) { }
inline actor(const ptr_type& ptr) : m_ptr(ptr) { }
inline actor(ptr_type&& ptr) : m_ptr(ptr) { }
actor(const actor&) = default;
inline actor(detail::actor_public* ptr) : super(ptr) { }
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)
{
m_ptr = std::move(other.m_ptr);
return *this;
}
inline actor(const actor& other) : super(other) { }
template<typename... Args>
void send(const Args&... args)
{
this_actor()->send(m_ptr.get(), tuple<Args...>(args...));
}
inline actor(actor&& other) : super(other) { }
template<typename... Args>
void send_tuple(const tuple<Args...>& args)
{
this_actor()->send(m_ptr.get(), args);
}
actor& operator=(const actor&);
inline bool operator==(const actor& other) const
{
return m_ptr == other.m_ptr;
}
private:
ptr_type m_ptr;
actor& operator=(actor&& other);
};
/*
template<typename... Args>
actor& operator<<(actor& whom, const tuple<Args...>& data)
{
whom.send_tuple(data);
}
*/
} // namespace cppa
#endif // ACTOR_HPP
......@@ -3,6 +3,8 @@
#include "cppa/invoke_rules.hpp"
#include "cppa/untyped_tuple.hpp"
#include "cppa/detail/channel.hpp"
#include "cppa/detail/actor_public.hpp"
namespace cppa { class message; }
......@@ -15,7 +17,7 @@ struct actor_private : public actor_public
virtual const message& receive() = 0;
virtual const message& last_dequeued() const = 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
......
#ifndef ACTOR_PUBLIC_HPP
#define ACTOR_PUBLIC_HPP
#include "cppa/ref_counted.hpp"
namespace cppa { class message; }
#include "cppa/detail/channel.hpp"
namespace cppa { namespace detail {
// public part of the actor interface
struct actor_public : ref_counted
struct actor_public : channel
{
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 @@
#include "cppa/tuple.hpp"
#include "cppa/untyped_tuple.hpp"
#include "cppa/intrusive_ptr.hpp"
#include "cppa/message_receiver.hpp"
#include "cppa/detail/channel.hpp"
namespace cppa {
......@@ -16,13 +19,14 @@ class message
struct content : ref_counted
{
const actor sender;
const actor receiver;
const message_receiver receiver;
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)
{
}
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)
{
}
......@@ -35,22 +39,22 @@ class message
public:
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...))) { }
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)) { }
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))) { }
message() : m_content(new content(actor(), actor(), tuple<int>(0))) { }
message() : m_content(new content(0, 0, tuple<int>(0))) { }
const actor& sender() const
{
return m_content->sender;
}
const actor& receiver() const
const message_receiver& receiver() const
{
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 \
cppa/util.hpp \
cppa/detail/abstract_tuple.hpp \
cppa/detail/decorated_tuple.hpp \
cppa/detail/channel.hpp \
cppa/detail/intermediate.hpp \
cppa/detail/invokable.hpp \
cppa/detail/matcher.hpp \
......@@ -53,8 +54,10 @@ HEADERS = cppa/actor.hpp \
cppa/util/utype_iterator.hpp \
cppa/util/void_type.hpp
SOURCES = src/decorated_tuple.cpp \
SOURCES = src/actor.cpp \
src/decorated_tuple.cpp \
src/deserializer.cpp \
src/message_receiver.cpp \
src/mock_scheduler.cpp \
src/ref_counted.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);
boost::thread_specific_ptr<actor_impl> m_this_actor(cleanup_fun);
struct actor_impl : cppa::detail::actor_private
{
......@@ -66,7 +65,7 @@ struct actor_impl : cppa::detail::actor_private
mailbox.prepend(std::move(buffer));
}
virtual void send(cppa::detail::actor_public* whom,
virtual void send(cppa::detail::channel* whom,
cppa::untyped_tuple&& what)
{
if (whom) whom->enqueue_msg(cppa::message(this, whom, std::move(what)));
......
......@@ -7,7 +7,8 @@ INCLUDES = -I./ -I../
EXECUTABLE = ../test
HEADERS = test.hpp
HEADERS = hash_of.hpp \
test.hpp
SOURCES = hash_of.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;
using namespace cppa;
class group : public ref_counted
class group : public detail::channel
{
boost::mutex m_mtx;
......@@ -58,21 +58,26 @@ class group : public ref_counted
}
}
template<typename... Args>
void send(const Args&... args)
void enqueue_msg(const message& msg)
{
boost::mutex::scoped_lock guard(m_mtx);
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 {
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