Commit 6886fd45 authored by neverlord's avatar neverlord

actor interface changes

parent b8168356
......@@ -60,14 +60,14 @@
<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-qKmNvj/Render</value>
<value type="QString">Apple_PubSub_Socket_Render=/tmp/launch-acy9jv/Render</value>
<value type="QString">COMMAND_MODE=unix2003</value>
<value type="QString">DISPLAY=/tmp/launch-bKBD8m/org.x:0</value>
<value type="QString">DISPLAY=/tmp/launch-Dz1e1O/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-voyypI/Listeners</value>
<value type="QString">SSH_AUTH_SOCK=/tmp/launch-AouAZz/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>
......
......@@ -96,3 +96,5 @@ cppa/message_queue.hpp
cppa/cppa.hpp
cppa/scheduling_hint.hpp
src/actor_behavior.cpp
cppa/group.hpp
src/group.cpp
#ifndef ACTOR_HPP
#define ACTOR_HPP
#include "cppa/group.hpp"
#include "cppa/channel.hpp"
namespace cppa {
class serializer;
class deserializer;
class actor : public channel
{
public:
virtual void link_to(const intrusive_ptr<actor>& other) = 0;
virtual void join(group_ptr& what) = 0;
virtual void leave(const group_ptr& what) = 0;
virtual void link(intrusive_ptr<actor>& other) = 0;
virtual void unlink(intrusive_ptr<actor>& other) = 0;
virtual bool remove_backlink(const intrusive_ptr<actor>& to) = 0;
virtual bool establish_backlink(const intrusive_ptr<actor>& to) = 0;
};
......@@ -18,4 +28,8 @@ typedef intrusive_ptr<actor> actor_ptr;
} // namespace cppa
cppa::serializer& operator<<(cppa::serializer&, const cppa::actor_ptr&);
cppa::deserializer& operator>>(cppa::deserializer&, cppa::actor_ptr&);
#endif // ACTOR_HPP
......@@ -13,8 +13,6 @@ class context : public actor
virtual message_queue& mailbox() = 0;
virtual void unlink(const actor_ptr& other) = 0;
};
} // namespace cppa
......
#ifndef CPPA_HPP
#define CPPA_HPP
#include "cppa/tuple.hpp"
#include "cppa/actor.hpp"
#include "cppa/invoke.hpp"
#include "cppa/channel.hpp"
#include "cppa/context.hpp"
#include "cppa/message.hpp"
......@@ -13,7 +15,7 @@
namespace cppa {
template<typename F>
actor_ptr spawn(F fun, scheduling_hint hint = scheduled)
actor_ptr spawn(scheduling_hint hint, F fun)
{
struct fun_behavior : actor_behavior
{
......@@ -27,11 +29,29 @@ actor_ptr spawn(F fun, scheduling_hint hint = scheduled)
return detail::scheduler::spawn(new fun_behavior(fun), hint);
}
inline actor_ptr spawn(actor_behavior* ab, scheduling_hint hint = scheduled)
template<typename F, typename Arg0, typename... Args>
actor_ptr spawn(scheduling_hint hint, F fun, const Arg0& arg0, const Args&... args)
{
auto arg_tuple = make_tuple(arg0, args...);
return spawn(hint, [=]() { invoke(fun, arg_tuple); });
}
template<typename F, typename... Args>
inline actor_ptr spawn(F fun, const Args&... args)
{
return spawn(scheduled, fun, args...);
}
inline actor_ptr spawn(scheduling_hint hint, actor_behavior* ab)
{
return detail::scheduler::spawn(ab, hint);
}
inline actor_ptr spawn(actor_behavior* ab)
{
return detail::scheduler::spawn(ab, scheduled);
}
inline context* self()
{
return detail::scheduler::get_context();
......
......@@ -9,22 +9,62 @@ class comparable
friend bool operator==(const Subclass& lhs, const T& rhs)
{
return lhs.equal_to(rhs);
return lhs.compare(rhs) == 0;
}
friend bool operator==(const T& lhs, const Subclass& rhs)
{
return rhs.equal_to(lhs);
return rhs.compare(lhs) == 0;
}
friend bool operator!=(const Subclass& lhs, const T& rhs)
{
return !lhs.equal_to(rhs);
return lhs.compare(rhs) != 0;
}
friend bool operator!=(const T& lhs, const Subclass& rhs)
{
return !rhs.equal_to(lhs);
return rhs.compare(lhs) != 0;
}
friend bool operator<(const Subclass& lhs, const T& rhs)
{
return lhs.compare(rhs) < 0;
}
friend bool operator>(const Subclass& lhs, const T& rhs)
{
return lhs.compare(rhs) > 0;
}
friend bool operator<(const T& lhs, const Subclass& rhs)
{
return rhs > lhs;
}
friend bool operator>(const T& lhs, const Subclass& rhs)
{
return rhs < lhs;
}
friend bool operator<=(const Subclass& lhs, const T& rhs)
{
return lhs.compare(rhs) <= 0;
}
friend bool operator>=(const Subclass& lhs, const T& rhs)
{
return lhs.compare(rhs) >= 0;
}
friend bool operator<=(const T& lhs, const Subclass& rhs)
{
return rhs >= lhs;
}
friend bool operator>=(const T& lhs, const Subclass& rhs)
{
return rhs <= lhs;
}
};
......@@ -35,12 +75,32 @@ class comparable<Subclass, Subclass>
friend bool operator==(const Subclass& lhs, const Subclass& rhs)
{
return lhs.equal_to(rhs);
return lhs.compare(rhs) == 0;
}
friend bool operator!=(const Subclass& lhs, const Subclass& rhs)
{
return !lhs.equal_to(rhs);
return lhs.compare(rhs) != 0;
}
friend bool operator<(const Subclass& lhs, const Subclass& rhs)
{
return lhs.compare(rhs) < 0;
}
friend bool operator<=(const Subclass& lhs, const Subclass& rhs)
{
return lhs.compare(rhs) <= 0;
}
friend bool operator>(const Subclass& lhs, const Subclass& rhs)
{
return lhs.compare(rhs) > 0;
}
friend bool operator>=(const Subclass& lhs, const Subclass& rhs)
{
return lhs.compare(rhs) >= 0;
}
};
......
#ifndef INTRUSIVE_PTR_HPP
#define INTRUSIVE_PTR_HPP
#include <cstddef>
#include <algorithm>
#include <stdexcept>
#include <type_traits>
......@@ -125,6 +126,17 @@ class intrusive_ptr : detail::comparable<intrusive_ptr<T>, T*>,
inline explicit operator bool() const { return m_ptr != 0; }
inline ptrdiff_t compare(const T* ptr) const
{
return static_cast<ptrdiff_t>(get() - ptr);
}
inline ptrdiff_t compare(const intrusive_ptr& other) const
{
return compare(other.get());
}
/*
inline bool equal_to(const T* ptr) const
{
return get() == ptr;
......@@ -134,6 +146,7 @@ class intrusive_ptr : detail::comparable<intrusive_ptr<T>, T*>,
{
return get() == other.get();
}
*/
};
......
......@@ -58,6 +58,7 @@ SOURCES = src/actor_behavior.cpp \
src/channel.cpp \
src/decorated_tuple.cpp \
src/deserializer.cpp \
src/group.cpp \
src/mock_scheduler.cpp \
src/serializer.cpp \
src/uniform_type_info.cpp \
......
#include <cstdint>
#include "cppa/actor.hpp"
#include "cppa/deserializer.hpp"
namespace cppa {
......@@ -10,6 +11,11 @@ deserializer::deserializer(const intrusive_ptr<util::source>& src) : m_src(src)
} // namespace cppa
cppa::deserializer& operator>>(cppa::deserializer& d, cppa::actor_ptr& aptr)
{
return d;
}
cppa::deserializer& operator>>(cppa::deserializer& d, std::string& str)
{
std::uint32_t str_size;
......
#include <set>
#include <map>
#include <boost/thread.hpp>
#include "cppa/message.hpp"
......@@ -90,11 +93,17 @@ struct mbox : message_queue
struct actor_impl : context
{
mbox m_mbox;
actor_behavior* m_behavior;
bool m_exited;
actor_impl(actor_behavior* b = 0) : m_behavior(b) { }
// guards m_exited, m_grp_lst and m_links
boost::mutex m_mtx;
std::map<group_ptr, intrusive_ptr<group::subscription> > m_grp_lst;
std::set<actor_ptr> m_links;
mbox m_mbox;
actor_impl(actor_behavior* b = 0) : m_behavior(b), m_exited(false) { }
~actor_impl()
{
......@@ -106,9 +115,59 @@ struct actor_impl : context
m_mbox.enqueue(msg);
}
virtual void link_to(const intrusive_ptr<actor>&) { }
virtual void link(intrusive_ptr<actor>& other)
{
boost::mutex::scoped_lock guard(m_mtx);
if (other && !m_exited && other->establish_backlink(this))
{
m_links.insert(other);
}
}
virtual bool remove_backlink(const intrusive_ptr<actor>& other)
{
if (other && other != this)
{
boost::mutex::scoped_lock guard(m_mtx);
return m_links.erase(other) > 0;
}
return false;
}
virtual void unlink(const intrusive_ptr<actor>&) { }
virtual bool establish_backlink(const intrusive_ptr<actor>& other)
{
if (other && other != this)
{
boost::mutex::scoped_lock guard(m_mtx);
return m_links.insert(other).second;
}
return false;
}
virtual void unlink(intrusive_ptr<actor>& other)
{
boost::mutex::scoped_lock guard(m_mtx);
if (other && !m_exited && other->remove_backlink(this))
{
m_links.erase(other);
}
}
virtual void join(group_ptr& what)
{
boost::mutex::scoped_lock guard(m_mtx);
if (!m_exited && m_grp_lst.count(what) == 0)
{
m_grp_lst[what] = what->subscribe(this);
}
}
virtual void leave(const group_ptr& what)
{
boost::mutex::scoped_lock guard(m_mtx);
m_grp_lst.erase(what);
}
virtual message_queue& mailbox()
{
......
#include <cstdint>
#include "cppa/actor.hpp"
#include "cppa/serializer.hpp"
namespace cppa {
......@@ -9,6 +11,11 @@ serializer::serializer(const intrusive_ptr<util::sink>& dsink) : m_sink(dsink)
} // namespace cppa
cppa::serializer& operator<<(cppa::serializer& s, const cppa::actor_ptr& aptr)
{
return s;
}
cppa::serializer& operator<<(cppa::serializer& s, const std::string& str)
{
auto str_size = static_cast<std::uint32_t>(str.size());
......
......@@ -4,6 +4,7 @@
#include "cppa/on.hpp"
#include "cppa/cppa.hpp"
#include "cppa/actor.hpp"
#include "cppa/group.hpp"
#include "cppa/ref_counted.hpp"
#include "cppa/intrusive_ptr.hpp"
......@@ -21,47 +22,13 @@ using namespace cppa;
namespace {
struct group : channel
{
// NOT thread safe
class subscription : public detail::ref_counted_impl<std::size_t>
{
actor_ptr m_self;
intrusive_ptr<group> m_group;
public:
subscription() = delete;
subscription(const subscription&) = delete;
subscription& operator=(const subscription&) = delete;
subscription(const actor_ptr& s, const intrusive_ptr<group>& g)
: m_self(s), m_group(g)
{
}
~subscription()
{
m_group->unsubscribe(m_self);
}
};
virtual intrusive_ptr<subscription> subscribe(const actor_ptr& who) = 0;
virtual void unsubscribe(const actor_ptr& who) = 0;
};
class local_group : public group
{
boost::mutex m_mtx;
std::list<actor_ptr> m_subscribers;
std::list<channel_ptr> m_subscribers;
inline std::list<actor_ptr>::iterator find(const actor_ptr& what)
inline std::list<channel_ptr>::iterator find(const channel_ptr& what)
{
return std::find(m_subscribers.begin(), m_subscribers.end(), what);
}
......@@ -77,7 +44,7 @@ class local_group : public group
}
}
virtual intrusive_ptr<group::subscription> subscribe(const actor_ptr& who)
virtual intrusive_ptr<group::subscription> subscribe(const channel_ptr& who)
{
boost::mutex::scoped_lock guard(m_mtx);
auto i = find(who);
......@@ -89,7 +56,7 @@ class local_group : public group
return new group::subscription(0, 0);
}
virtual void unsubscribe(const actor_ptr& who)
virtual void unsubscribe(const channel_ptr& who)
{
boost::mutex::scoped_lock guard(m_mtx);
auto i = find(who);
......@@ -164,14 +131,14 @@ std::size_t test__local_group()
std::list<intrusive_ptr<group::subscription>> m_subscriptions;
auto self_ptr = self();
actor_ptr self_ptr = self();
auto consume_actor = spawn([=]() { consumer(self_ptr); });
auto consume_actor = spawn(consumer, self_ptr);
auto lg = local("foobar");
for (int i = 0; i < 5; ++i)
{
auto fa = spawn([=]() { producer(consume_actor); });
auto fa = spawn(producer, consume_actor);
auto sptr = lg->subscribe(fa);
m_subscriptions.push_back(sptr);
}
......
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