Commit 791bf4c3 authored by neverlord's avatar neverlord

new implementation for cppa::self

parent 4b517a33
...@@ -48,6 +48,7 @@ libcppa_la_SOURCES = \ ...@@ -48,6 +48,7 @@ libcppa_la_SOURCES = \
src/ripemd_160.cpp \ src/ripemd_160.cpp \
src/abstract_scheduled_actor.cpp \ src/abstract_scheduled_actor.cpp \
src/scheduler.cpp \ src/scheduler.cpp \
src/self.cpp \
src/serializer.cpp \ src/serializer.cpp \
src/shared_spinlock.cpp \ src/shared_spinlock.cpp \
src/singleton_manager.cpp \ src/singleton_manager.cpp \
...@@ -158,6 +159,7 @@ nobase_library_include_HEADERS = \ ...@@ -158,6 +159,7 @@ nobase_library_include_HEADERS = \
cppa/ref_counted.hpp \ cppa/ref_counted.hpp \
cppa/scheduler.hpp \ cppa/scheduler.hpp \
cppa/scheduling_hint.hpp \ cppa/scheduling_hint.hpp \
cppa/self.hpp \
cppa/serializer.hpp \ cppa/serializer.hpp \
cppa/stacked_event_based_actor.hpp \ cppa/stacked_event_based_actor.hpp \
cppa/to_string.hpp \ cppa/to_string.hpp \
......
...@@ -240,3 +240,5 @@ cppa/stacked_event_based_actor.hpp ...@@ -240,3 +240,5 @@ cppa/stacked_event_based_actor.hpp
src/stacked_event_based_actor.cpp src/stacked_event_based_actor.cpp
cppa/event_based_actor_mixin.hpp cppa/event_based_actor_mixin.hpp
cppa/fsm_actor.hpp cppa/fsm_actor.hpp
cppa/self.hpp
src/self.cpp
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include "cppa/on.hpp" #include "cppa/on.hpp"
#include "cppa/atom.hpp" #include "cppa/atom.hpp"
#include "cppa/self.hpp"
#include "cppa/tuple.hpp" #include "cppa/tuple.hpp"
#include "cppa/actor.hpp" #include "cppa/actor.hpp"
#include "cppa/invoke.hpp" #include "cppa/invoke.hpp"
...@@ -185,7 +186,7 @@ ...@@ -185,7 +186,7 @@
* *
* // send a message to a1, a2 and a3 * // send a message to a1, a2 and a3
* auto msg = make_tuple(atom("compute"), 1, 2, 3); * auto msg = make_tuple(atom("compute"), 1, 2, 3);
* auto s = self(); // cache self() pointer * auto s = self; // cache self pointer
* // note: this is more efficient then using send() three times because * // note: this is more efficient then using send() three times because
* // send() would create a new tuple each time; * // send() would create a new tuple each time;
* // this safes both time and memory thanks to libcppa's copy-on-write * // this safes both time and memory thanks to libcppa's copy-on-write
...@@ -328,7 +329,7 @@ ...@@ -328,7 +329,7 @@
* Usage example: * Usage example:
* *
* @code * @code
* future_send(self(), std::chrono::seconds(1), atom("poll")); * future_send(self, std::chrono::seconds(1), atom("poll"));
* receive_loop * receive_loop
* ( * (
* // ... * // ...
...@@ -336,7 +337,7 @@ ...@@ -336,7 +337,7 @@
* { * {
* // ... poll something ... * // ... poll something ...
* // and do it again after 1sec * // and do it again after 1sec
* future_send(self(), std::chrono::seconds(1), atom("poll")); * future_send(self, std::chrono::seconds(1), atom("poll"));
* } * }
* ); * );
* @endcode * @endcode
...@@ -353,14 +354,14 @@ ...@@ -353,14 +354,14 @@
* A few examples: * A few examples:
* @code * @code
* // sends an std::string containing "hello actor!" to itself * // sends an std::string containing "hello actor!" to itself
* send(self(), "hello actor!"); * send(self, "hello actor!");
* *
* const char* cstring = "cstring"; * const char* cstring = "cstring";
* // sends an std::string containing "cstring" to itself * // sends an std::string containing "cstring" to itself
* send(self(), cstring); * send(self, cstring);
* *
* // sends an std::u16string containing the UTF16 string "hello unicode world!" * // sends an std::u16string containing the UTF16 string "hello unicode world!"
* send(self(), u"hello unicode world!"); * send(self, u"hello unicode world!");
* *
* // x has the type cppa::tuple<std::string, std::string> * // x has the type cppa::tuple<std::string, std::string>
* auto x = make_tuple("hello", "tuple"); * auto x = make_tuple("hello", "tuple");
...@@ -446,7 +447,7 @@ void demonitor(actor_ptr& whom); ...@@ -446,7 +447,7 @@ void demonitor(actor_ptr& whom);
*/ */
inline bool trap_exit() inline bool trap_exit()
{ {
return self()->trap_exit(); return self->trap_exit();
} }
/** /**
...@@ -458,7 +459,7 @@ inline bool trap_exit() ...@@ -458,7 +459,7 @@ inline bool trap_exit()
*/ */
inline void trap_exit(bool new_value) inline void trap_exit(bool new_value)
{ {
self()->trap_exit(new_value); self->trap_exit(new_value);
} }
inline actor_ptr spawn(scheduled_actor* what) inline actor_ptr spawn(scheduled_actor* what)
...@@ -516,11 +517,11 @@ spawn(F&& what, const Args&... args) ...@@ -516,11 +517,11 @@ spawn(F&& what, const Args&... args)
/** /**
* @copydoc local_actor::quit() * @copydoc local_actor::quit()
* *
* Alias for <tt>self()->quit(reason);</tt> * Alias for <tt>self->quit(reason);</tt>
*/ */
inline void quit(std::uint32_t reason) inline void quit(std::uint32_t reason)
{ {
self()->quit(reason); self->quit(reason);
} }
/** /**
...@@ -654,7 +655,7 @@ detail::do_receive_helper do_receive(Args&&... args) ...@@ -654,7 +655,7 @@ detail::do_receive_helper do_receive(Args&&... args)
*/ */
inline any_tuple& last_received() inline any_tuple& last_received()
{ {
return self()->last_dequeued(); return self->last_dequeued();
} }
/** /**
...@@ -663,7 +664,7 @@ inline any_tuple& last_received() ...@@ -663,7 +664,7 @@ inline any_tuple& last_received()
*/ */
inline actor_ptr& last_sender() inline actor_ptr& last_sender()
{ {
return self()->last_sender(); return self->last_sender();
} }
#ifdef CPPA_DOCUMENTATION #ifdef CPPA_DOCUMENTATION
...@@ -684,7 +685,7 @@ void send(channel_ptr& whom, const Arg0& arg0, const Args&... args); ...@@ -684,7 +685,7 @@ void send(channel_ptr& whom, const Arg0& arg0, const Args&... args);
* *
* <b>Usage example:</b> * <b>Usage example:</b>
* @code * @code
* self() << make_tuple(1, 2, 3); * self << make_tuple(1, 2, 3);
* @endcode * @endcode
* *
* Sends the tuple @p what as a message to @p whom. * Sends the tuple @p what as a message to @p whom.
...@@ -700,7 +701,7 @@ template<class C, typename Arg0, typename... Args> ...@@ -700,7 +701,7 @@ template<class C, typename Arg0, typename... Args>
typename util::enable_if<std::is_base_of<channel, C>, void>::type typename util::enable_if<std::is_base_of<channel, C>, void>::type
send(intrusive_ptr<C>& whom, const Arg0& arg0, const Args&... args) send(intrusive_ptr<C>& whom, const Arg0& arg0, const Args&... args)
{ {
if (whom) whom->enqueue(self(), make_tuple(arg0, args...)); if (whom) whom->enqueue(self, make_tuple(arg0, args...));
} }
template<class C, typename Arg0, typename... Args> template<class C, typename Arg0, typename... Args>
...@@ -708,21 +709,21 @@ typename util::enable_if<std::is_base_of<channel, C>, void>::type ...@@ -708,21 +709,21 @@ typename util::enable_if<std::is_base_of<channel, C>, void>::type
send(intrusive_ptr<C>&& whom, const Arg0& arg0, const Args&... args) send(intrusive_ptr<C>&& whom, const Arg0& arg0, const Args&... args)
{ {
intrusive_ptr<C> tmp(std::move(whom)); intrusive_ptr<C> tmp(std::move(whom));
if (tmp) tmp->enqueue(self(), make_tuple(arg0, args...)); if (tmp) tmp->enqueue(self, make_tuple(arg0, args...));
} }
// matches send(self(), ...); // matches send(self, ...);
template<typename Arg0, typename... Args> template<typename Arg0, typename... Args>
void send(local_actor* whom, const Arg0& arg0, const Args&... args) void send(local_actor* whom, const Arg0& arg0, const Args&... args)
{ {
if (whom) whom->enqueue(self(), make_tuple(arg0, args...)); if (whom) whom->enqueue(self, make_tuple(arg0, args...));
} }
template<class C> template<class C>
typename util::enable_if<std::is_base_of<channel, C>, void>::type typename util::enable_if<std::is_base_of<channel, C>, void>::type
send_tuple(intrusive_ptr<C>& whom, const any_tuple& what) send_tuple(intrusive_ptr<C>& whom, const any_tuple& what)
{ {
if (whom) whom->enqueue(self(), what); if (whom) whom->enqueue(self, what);
} }
template<class C> template<class C>
...@@ -730,20 +731,20 @@ typename util::enable_if<std::is_base_of<channel, C>, void>::type ...@@ -730,20 +731,20 @@ typename util::enable_if<std::is_base_of<channel, C>, void>::type
send_tuple(intrusive_ptr<C>&& whom, const any_tuple& what) send_tuple(intrusive_ptr<C>&& whom, const any_tuple& what)
{ {
intrusive_ptr<C> tmp(std::move(whom)); intrusive_ptr<C> tmp(std::move(whom));
if (tmp) tmp->enqueue(self(), what); if (tmp) tmp->enqueue(self, what);
} }
// matches send(self(), ...); // matches send(self, ...);
inline void send_tuple(local_actor* whom, const any_tuple& what) inline void send_tuple(local_actor* whom, const any_tuple& what)
{ {
if (whom) whom->enqueue(self(), what); if (whom) whom->enqueue(self, what);
} }
template<class C> template<class C>
typename util::enable_if<std::is_base_of<channel, C>, intrusive_ptr<C>&>::type typename util::enable_if<std::is_base_of<channel, C>, intrusive_ptr<C>&>::type
operator<<(intrusive_ptr<C>& whom, const any_tuple& what) operator<<(intrusive_ptr<C>& whom, const any_tuple& what)
{ {
if (whom) whom->enqueue(self(), what); if (whom) whom->enqueue(self, what);
return whom; return whom;
} }
...@@ -752,7 +753,7 @@ typename util::enable_if<std::is_base_of<channel, C>, intrusive_ptr<C>>::type ...@@ -752,7 +753,7 @@ typename util::enable_if<std::is_base_of<channel, C>, intrusive_ptr<C>>::type
operator<<(intrusive_ptr<C>&& whom, const any_tuple& what) operator<<(intrusive_ptr<C>&& whom, const any_tuple& what)
{ {
intrusive_ptr<C> tmp(std::move(whom)); intrusive_ptr<C> tmp(std::move(whom));
if (tmp) tmp->enqueue(self(), what); if (tmp) tmp->enqueue(self, what);
return std::move(tmp); return std::move(tmp);
} }
...@@ -760,7 +761,7 @@ template<class C> ...@@ -760,7 +761,7 @@ template<class C>
typename util::enable_if<std::is_base_of<channel, C>, intrusive_ptr<C>&>::type typename util::enable_if<std::is_base_of<channel, C>, intrusive_ptr<C>&>::type
operator<<(intrusive_ptr<C>& whom, any_tuple&& what) operator<<(intrusive_ptr<C>& whom, any_tuple&& what)
{ {
if (whom) whom->enqueue(self(), std::move(what)); if (whom) whom->enqueue(self, std::move(what));
return whom; return whom;
} }
...@@ -769,14 +770,14 @@ typename util::enable_if<std::is_base_of<channel, C>, intrusive_ptr<C>>::type ...@@ -769,14 +770,14 @@ typename util::enable_if<std::is_base_of<channel, C>, intrusive_ptr<C>>::type
operator<<(intrusive_ptr<C>&& whom, any_tuple&& what) operator<<(intrusive_ptr<C>&& whom, any_tuple&& what)
{ {
intrusive_ptr<C> tmp(std::move(whom)); intrusive_ptr<C> tmp(std::move(whom));
if (tmp) tmp->enqueue(self(), std::move(what)); if (tmp) tmp->enqueue(self, std::move(what));
return std::move(tmp); return std::move(tmp);
} }
// matches self() << make_tuple(...) // matches self << make_tuple(...)
local_actor* operator<<(local_actor* whom, const any_tuple& what); local_actor* operator<<(local_actor* whom, const any_tuple& what);
// matches self() << make_tuple(...) // matches self << make_tuple(...)
local_actor* operator<<(local_actor* whom, any_tuple&& what); local_actor* operator<<(local_actor* whom, any_tuple&& what);
#endif #endif
...@@ -784,12 +785,12 @@ local_actor* operator<<(local_actor* whom, any_tuple&& what); ...@@ -784,12 +785,12 @@ local_actor* operator<<(local_actor* whom, any_tuple&& what);
template<typename Arg0, typename... Args> template<typename Arg0, typename... Args>
void reply(const Arg0& arg0, const Args&... args) void reply(const Arg0& arg0, const Args&... args)
{ {
send(self()->last_sender(), arg0, args...); send(self->last_sender(), arg0, args...);
} }
inline void reply_tuple(const any_tuple& what) inline void reply_tuple(const any_tuple& what)
{ {
send_tuple(self()->last_sender(), what); send_tuple(self->last_sender(), what);
} }
/** /**
...@@ -812,7 +813,7 @@ void future_send(actor_ptr whom, const Duration& rel_time, const Data&... data) ...@@ -812,7 +813,7 @@ void future_send(actor_ptr whom, const Duration& rel_time, const Data&... data)
*/ */
inline void await_all_others_done() inline void await_all_others_done()
{ {
detail::actor_count_wait_until((unchecked_self() == nullptr) ? 0 : 1); detail::actor_count_wait_until((self.unchecked() == nullptr) ? 0 : 1);
} }
/** /**
......
...@@ -14,11 +14,11 @@ template<typename List, size_t Pos = 0> ...@@ -14,11 +14,11 @@ template<typename List, size_t Pos = 0>
struct serialize_tuple struct serialize_tuple
{ {
template<typename T> template<typename T>
inline static void _(serializer& s, const T* self) inline static void _(serializer& s, const T* tup)
{ {
s << uniform_typeid<typename List::head_type>()->name() s << uniform_typeid<typename List::head_type>()->name()
<< *reinterpret_cast<const typename List::head_type*>(self->at(Pos)); << *reinterpret_cast<const typename List::head_type*>(tup->at(Pos));
serialize_tuple<typename List::tail_type, Pos + 1>::_(s, self); serialize_tuple<typename List::tail_type, Pos + 1>::_(s, tup);
} }
}; };
......
...@@ -6,10 +6,20 @@ ...@@ -6,10 +6,20 @@
#include <stdexcept> #include <stdexcept>
#include <type_traits> #include <type_traits>
#include <cppa/util/comparable.hpp> #include "cppa/util/enable_if.hpp"
#include "cppa/util/comparable.hpp"
namespace cppa { namespace cppa {
template<class From, class To>
struct convertible
{
To convert() const
{
return static_cast<const From*>(this)->do_convert();
}
};
/** /**
* @brief An intrusive, reference counting smart pointer impelementation. * @brief An intrusive, reference counting smart pointer impelementation.
* @relates ref_counted * @relates ref_counted
...@@ -42,6 +52,12 @@ class intrusive_ptr : util::comparable<intrusive_ptr<T>, const T*>, ...@@ -42,6 +52,12 @@ class intrusive_ptr : util::comparable<intrusive_ptr<T>, const T*>,
{ {
} }
template<typename From>
intrusive_ptr(const convertible<From, T*>& from)
{
set_ptr(from.convert());
}
template<typename Y> template<typename Y>
intrusive_ptr(const intrusive_ptr<Y>& other) intrusive_ptr(const intrusive_ptr<Y>& other)
{ {
...@@ -87,12 +103,10 @@ class intrusive_ptr : util::comparable<intrusive_ptr<T>, const T*>, ...@@ -87,12 +103,10 @@ class intrusive_ptr : util::comparable<intrusive_ptr<T>, const T*>,
set_ptr(new_value); set_ptr(new_value);
} }
template<typename Y> intrusive_ptr& operator=(T* ptr)
void reset(Y* new_value)
{ {
static_assert(std::is_convertible<Y*, T*>::value, reset(ptr);
"Y* is not assignable to T*"); return *this;
reset(static_cast<T*>(new_value));
} }
intrusive_ptr& operator=(const intrusive_ptr& other) intrusive_ptr& operator=(const intrusive_ptr& other)
...@@ -112,11 +126,20 @@ class intrusive_ptr : util::comparable<intrusive_ptr<T>, const T*>, ...@@ -112,11 +126,20 @@ class intrusive_ptr : util::comparable<intrusive_ptr<T>, const T*>,
template<typename Y> template<typename Y>
intrusive_ptr& operator=(const intrusive_ptr<Y>& other) intrusive_ptr& operator=(const intrusive_ptr<Y>& other)
{ {
static_assert(std::is_convertible<Y*, T*>::value,
"Y* is not assignable to T*");
intrusive_ptr tmp(other); intrusive_ptr tmp(other);
swap(tmp); swap(tmp);
return *this; return *this;
} }
template<typename From>
intrusive_ptr& operator=(const convertible<From, T*>& from)
{
reset(from.convert());
return *this;
}
template<typename Y> template<typename Y>
intrusive_ptr& operator=(intrusive_ptr<Y>&& other) intrusive_ptr& operator=(intrusive_ptr<Y>&& other)
{ {
...@@ -147,20 +170,6 @@ class intrusive_ptr : util::comparable<intrusive_ptr<T>, const T*>, ...@@ -147,20 +170,6 @@ class intrusive_ptr : util::comparable<intrusive_ptr<T>, const T*>,
return compare(other.get()); return compare(other.get());
} }
template<class C>
intrusive_ptr<C> downcast() const
{
if (m_ptr) return dynamic_cast<C*>(const_cast<T*>(m_ptr));
return nullptr;
}
template<class C>
intrusive_ptr<C> upcast() const
{
if (m_ptr) return static_cast<C*>(const_cast<T*>(m_ptr));
return nullptr;
}
}; };
template<typename X, typename Y> template<typename X, typename Y>
......
...@@ -84,18 +84,7 @@ inline actor_ptr& local_actor::last_sender() ...@@ -84,18 +84,7 @@ inline actor_ptr& local_actor::last_sender()
return m_last_sender; return m_last_sender;
} }
typedef intrusive_ptr<local_actor> local_actor_ptr;
/**
* @brief Get a pointer to the current active context.
* @returns A pointer that identifies the calling actor.
*/
local_actor* self();
// "private" function
void set_self(local_actor*);
// "private" function, returns active context (without creating it if needed)
local_actor* unchecked_self();
} // namespace cppa } // namespace cppa
......
...@@ -102,13 +102,13 @@ class primitive_variant ...@@ -102,13 +102,13 @@ class primitive_variant
template<class Self, typename Fun> template<class Self, typename Fun>
struct applier struct applier
{ {
Self* m_self; Self* m_parent;
Fun& m_f; Fun& m_f;
applier(Self* self, Fun& f) : m_self(self), m_f(f) { } applier(Self* parent, Fun& f) : m_parent(parent), m_f(f) { }
template<primitive_type FT> template<primitive_type FT>
inline void operator()(util::pt_token<FT> token) inline void operator()(util::pt_token<FT> token)
{ {
m_f(m_self->get(token)); m_f(m_parent->get(token));
} }
}; };
......
#ifndef RECEIVE_HPP #ifndef RECEIVE_HPP
#define RECEIVE_HPP #define RECEIVE_HPP
#include "cppa/self.hpp"
#include "cppa/local_actor.hpp" #include "cppa/local_actor.hpp"
namespace cppa { namespace cppa {
...@@ -11,24 +12,24 @@ namespace cppa { ...@@ -11,24 +12,24 @@ namespace cppa {
*/ */
inline void receive(invoke_rules& rules) inline void receive(invoke_rules& rules)
{ {
self()->dequeue(rules); self->dequeue(rules);
} }
inline void receive(timed_invoke_rules& rules) inline void receive(timed_invoke_rules& rules)
{ {
self()->dequeue(rules); self->dequeue(rules);
} }
inline void receive(timed_invoke_rules&& rules) inline void receive(timed_invoke_rules&& rules)
{ {
timed_invoke_rules tmp(std::move(rules)); timed_invoke_rules tmp(std::move(rules));
self()->dequeue(tmp); self->dequeue(tmp);
} }
inline void receive(invoke_rules&& rules) inline void receive(invoke_rules&& rules)
{ {
invoke_rules tmp(std::move(rules)); invoke_rules tmp(std::move(rules));
self()->dequeue(tmp); self->dequeue(tmp);
} }
template<typename Head, typename... Tail> template<typename Head, typename... Tail>
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <memory> #include <memory>
#include <cstdint> #include <cstdint>
#include "cppa/self.hpp"
#include "cppa/atom.hpp" #include "cppa/atom.hpp"
#include "cppa/tuple.hpp" #include "cppa/tuple.hpp"
#include "cppa/actor.hpp" #include "cppa/actor.hpp"
...@@ -82,7 +83,7 @@ class scheduler ...@@ -82,7 +83,7 @@ class scheduler
{ {
static_assert(sizeof...(Data) > 0, "no message to send"); static_assert(sizeof...(Data) > 0, "no message to send");
any_tuple tup = make_tuple(util::duration(rel_time), to, data...); any_tuple tup = make_tuple(util::duration(rel_time), to, data...);
future_send_helper()->enqueue(self(), std::move(tup)); future_send_helper()->enqueue(self, std::move(tup));
} }
}; };
......
#ifndef SELF_HPP
#define SELF_HPP
#include "cppa/actor.hpp"
#include "cppa/local_actor.hpp"
#include "cppa/intrusive_ptr.hpp"
namespace cppa {
class self_type : public convertible<self_type, actor*>
{
static void set_impl(local_actor*);
static local_actor* get_unchecked_impl();
static local_actor* get_impl();
public:
inline local_actor* do_convert() const
{
return get_impl();
}
constexpr self_type() { }
inline operator local_actor*() const
{
return get_impl();
}
inline local_actor* operator->()
{
return get_impl();
}
// backward compatibility
inline local_actor* operator()() const
{
return get_impl();
}
// @pre get_unchecked() == nullptr
inline void set(local_actor* ptr)
{
set_impl(ptr);
}
// @returns The current value without converting the calling context
// to an actor on-the-fly.
inline local_actor* unchecked()
{
return get_unchecked_impl();
}
};
#ifdef CPPA_DOCUMENTATION
/**
* @brief Always points to the current actor. Similar to @c this in
* an object-oriented context.
*/
extern local_actor* self;
#else
extern self_type self;
#endif
} // namespace cppa
#endif // SELF_HPP
...@@ -62,7 +62,7 @@ const uniform_type_info* uniform_typeid(const std::type_info&); ...@@ -62,7 +62,7 @@ const uniform_type_info* uniform_typeid(const std::type_info&);
* *
* int main() * int main()
* { * {
* send(self(), foo{1,2}); * send(self, foo{1,2});
* return 0; * return 0;
* } * }
* @endcode * @endcode
......
...@@ -46,11 +46,11 @@ int main(int, char**) ...@@ -46,11 +46,11 @@ int main(int, char**)
assert(announce<foo_pair2>(&foo_pair2::first, &foo_pair2::second) == false); assert(announce<foo_pair2>(&foo_pair2::first, &foo_pair2::second) == false);
// send a foo to ourselves // send a foo to ourselves
send(self(), foo{ { 1, 2, 3, 4 }, 5 }); send(self, foo{ { 1, 2, 3, 4 }, 5 });
// send a foo_pair2 to ourselves // send a foo_pair2 to ourselves
send(self(), foo_pair2{3, 4}); send(self, foo_pair2{3, 4});
// quits the program // quits the program
send(self(), atom("done")); send(self, atom("done"));
// libcppa returns the same uniform_type_info // libcppa returns the same uniform_type_info
// instance for foo_pair and foo_pair2 // instance for foo_pair and foo_pair2
......
...@@ -51,7 +51,7 @@ int main(int, char**) ...@@ -51,7 +51,7 @@ int main(int, char**)
make_pair(&foo::b, &foo::set_b)); make_pair(&foo::b, &foo::set_b));
// send a foo to ourselves ... // send a foo to ourselves ...
send(self(), foo{1,2}); send(self, foo{1,2});
receive receive
( (
// ... and receive it // ... and receive it
......
...@@ -69,7 +69,7 @@ int main(int, char**) ...@@ -69,7 +69,7 @@ int main(int, char**)
static_cast<foo_setter>(&foo::b))); static_cast<foo_setter>(&foo::b)));
// send a foo to ourselves ... // send a foo to ourselves ...
send(self(), foo{1,2}); send(self, foo{1,2});
receive receive
( (
// ... and receive it // ... and receive it
......
...@@ -110,9 +110,9 @@ int main(int, char**) ...@@ -110,9 +110,9 @@ int main(int, char**)
&bar::i)); &bar::i));
// send a bar to ourselves // send a bar to ourselves
send(self(), bar{foo{1,2},3}); send(self, bar{foo{1,2},3});
// send a baz to ourselves // send a baz to ourselves
send(self(), baz{foo{1,2},bar{foo{3,4},5}}); send(self, baz{foo{1,2},bar{foo{3,4},5}});
// receive two messages // receive two messages
int i = 0; int i = 0;
......
...@@ -188,7 +188,7 @@ int main() ...@@ -188,7 +188,7 @@ int main()
*/ */
// send a tree to ourselves ... // send a tree to ourselves ...
send(self(), t); send(self, t);
// send a vector of trees to ourselves // send a vector of trees to ourselves
typedef std::vector<tree> tree_vector; typedef std::vector<tree> tree_vector;
...@@ -196,7 +196,7 @@ int main() ...@@ -196,7 +196,7 @@ int main()
tree_vector tvec; tree_vector tvec;
tvec.push_back(t); tvec.push_back(t);
tvec.push_back(t); tvec.push_back(t);
send(self(), tvec); send(self, tvec);
// receive both messages // receive both messages
int i = 0; int i = 0;
......
#include "cppa/self.hpp"
#include "cppa/detail/invokable.hpp" #include "cppa/detail/invokable.hpp"
#include "cppa/abstract_event_based_actor.hpp" #include "cppa/abstract_event_based_actor.hpp"
...@@ -61,7 +62,8 @@ void abstract_event_based_actor::handle_message(std::unique_ptr<queue_node>& nod ...@@ -61,7 +62,8 @@ void abstract_event_based_actor::handle_message(std::unique_ptr<queue_node>& nod
void abstract_event_based_actor::resume(util::fiber*, resume_callback* callback) void abstract_event_based_actor::resume(util::fiber*, resume_callback* callback)
{ {
set_self(this); self.set(this);
//set_self(this);
auto done_cb = [&]() auto done_cb = [&]()
{ {
m_state.store(abstract_scheduled_actor::done); m_state.store(abstract_scheduled_actor::done);
......
...@@ -22,33 +22,33 @@ namespace detail { ...@@ -22,33 +22,33 @@ namespace detail {
class binary_writer class binary_writer
{ {
binary_serializer* self; binary_serializer* m_serializer;
public: public:
binary_writer(binary_serializer* s) : self(s) { } binary_writer(binary_serializer* s) : m_serializer(s) { }
template<typename T> template<typename T>
inline static void write_int(binary_serializer* self, const T& value) inline static void write_int(binary_serializer* bs, const T& value)
{ {
memcpy(self->m_wr_pos, &value, sizeof(T)); memcpy(bs->m_wr_pos, &value, sizeof(T));
self->m_wr_pos += sizeof(T); bs->m_wr_pos += sizeof(T);
} }
inline static void write_string(binary_serializer* self, inline static void write_string(binary_serializer* bs,
const std::string& str) const std::string& str)
{ {
write_int(self, static_cast<std::uint32_t>(str.size())); write_int(bs, static_cast<std::uint32_t>(str.size()));
memcpy(self->m_wr_pos, str.c_str(), str.size()); memcpy(bs->m_wr_pos, str.c_str(), str.size());
self->m_wr_pos += str.size(); bs->m_wr_pos += str.size();
} }
template<typename T> template<typename T>
void operator()(const T& value, void operator()(const T& value,
typename enable_if< std::is_integral<T> >::type* = 0) typename enable_if< std::is_integral<T> >::type* = 0)
{ {
self->acquire(sizeof(T)); m_serializer->acquire(sizeof(T));
write_int(self, value); write_int(m_serializer, value);
} }
template<typename T> template<typename T>
...@@ -61,29 +61,29 @@ class binary_writer ...@@ -61,29 +61,29 @@ class binary_writer
void operator()(const std::string& str) void operator()(const std::string& str)
{ {
self->acquire(sizeof(std::uint32_t) + str.size()); m_serializer->acquire(sizeof(std::uint32_t) + str.size());
write_string(self, str); write_string(m_serializer, str);
} }
void operator()(const std::u16string& str) void operator()(const std::u16string& str)
{ {
self->acquire(sizeof(std::uint32_t) + str.size()); m_serializer->acquire(sizeof(std::uint32_t) + str.size());
write_int(self, static_cast<std::uint32_t>(str.size())); write_int(m_serializer, static_cast<std::uint32_t>(str.size()));
for (char16_t c : str) for (char16_t c : str)
{ {
// force writer to use exactly 16 bit // force writer to use exactly 16 bit
write_int(self, static_cast<std::uint16_t>(c)); write_int(m_serializer, static_cast<std::uint16_t>(c));
} }
} }
void operator()(const std::u32string& str) void operator()(const std::u32string& str)
{ {
self->acquire(sizeof(std::uint32_t) + str.size()); m_serializer->acquire(sizeof(std::uint32_t) + str.size());
write_int(self, static_cast<std::uint32_t>(str.size())); write_int(m_serializer, static_cast<std::uint32_t>(str.size()));
for (char32_t c : str) for (char32_t c : str)
{ {
// force writer to use exactly 32 bit // force writer to use exactly 32 bit
write_int(self, static_cast<std::uint32_t>(c)); write_int(m_serializer, static_cast<std::uint32_t>(c));
} }
} }
......
#include <memory> #include <memory>
#include <algorithm> #include <algorithm>
#include "cppa/self.hpp"
#include "cppa/exception.hpp" #include "cppa/exception.hpp"
#include "cppa/detail/invokable.hpp" #include "cppa/detail/invokable.hpp"
#include "cppa/detail/intermediate.hpp" #include "cppa/detail/intermediate.hpp"
...@@ -17,8 +18,9 @@ void converted_thread_context::quit(std::uint32_t reason) ...@@ -17,8 +18,9 @@ void converted_thread_context::quit(std::uint32_t reason)
{ {
try { super::cleanup(reason); } catch(...) { } try { super::cleanup(reason); } catch(...) { }
// actor_exited should not be catched, but if anyone does, // actor_exited should not be catched, but if anyone does,
// the next call to self() must return a newly created instance // self must point to a newly created instance
set_self(nullptr); self.set(nullptr);
//set_self(nullptr);
throw actor_exited(reason); throw actor_exited(reason);
} }
......
...@@ -15,7 +15,7 @@ class observer : public cppa::attachable ...@@ -15,7 +15,7 @@ class observer : public cppa::attachable
void detach(std::uint32_t reason) void detach(std::uint32_t reason)
{ {
using namespace cppa; using namespace cppa;
send(m_client, atom(":Down"), actor_ptr(self()), reason); send(m_client, atom(":Down"), actor_ptr(self), reason);
} }
bool matches(const cppa::attachable::token& match_token) bool matches(const cppa::attachable::token& match_token)
...@@ -36,20 +36,20 @@ namespace cppa { ...@@ -36,20 +36,20 @@ namespace cppa {
local_actor* operator<<(local_actor* whom, const any_tuple& what) local_actor* operator<<(local_actor* whom, const any_tuple& what)
{ {
if (whom) whom->enqueue(self(), what); if (whom) whom->enqueue(self, what);
return whom; return whom;
} }
// matches self() << make_tuple(...) // matches self << make_tuple(...)
local_actor* operator<<(local_actor* whom, any_tuple&& what) local_actor* operator<<(local_actor* whom, any_tuple&& what)
{ {
if (whom) whom->enqueue(self(), std::move(what)); if (whom) whom->enqueue(self, std::move(what));
return whom; return whom;
} }
void link(actor_ptr& other) void link(actor_ptr& other)
{ {
if (other) self()->link_to(other); if (other) self->link_to(other);
} }
void link(actor_ptr&& other) void link(actor_ptr&& other)
...@@ -89,7 +89,7 @@ void unlink(actor_ptr& lhs, actor_ptr& rhs) ...@@ -89,7 +89,7 @@ void unlink(actor_ptr& lhs, actor_ptr& rhs)
void monitor(actor_ptr& whom) void monitor(actor_ptr& whom)
{ {
if (whom) whom->attach(new observer(self())); if (whom) whom->attach(new observer(actor_ptr(self)));
} }
void monitor(actor_ptr&& whom) void monitor(actor_ptr&& whom)
...@@ -100,13 +100,13 @@ void monitor(actor_ptr&& whom) ...@@ -100,13 +100,13 @@ void monitor(actor_ptr&& whom)
void demonitor(actor_ptr& whom) void demonitor(actor_ptr& whom)
{ {
attachable::token mtoken(typeid(observer), self()); attachable::token mtoken(typeid(observer), self);
if (whom) whom->detach(mtoken); if (whom) whom->detach(mtoken);
} }
void receive_loop(invoke_rules& rules) void receive_loop(invoke_rules& rules)
{ {
auto sptr = self(); local_actor* sptr = self;
for (;;) for (;;)
{ {
sptr->dequeue(rules); sptr->dequeue(rules);
...@@ -115,7 +115,7 @@ void receive_loop(invoke_rules& rules) ...@@ -115,7 +115,7 @@ void receive_loop(invoke_rules& rules)
void receive_loop(timed_invoke_rules& rules) void receive_loop(timed_invoke_rules& rules)
{ {
auto sptr = self(); local_actor* sptr = self;
for (;;) for (;;)
{ {
sptr->dequeue(rules); sptr->dequeue(rules);
......
// for thread_specific_ptr
// needed unless the new keyword "thread_local" works in GCC
#include <boost/thread/tss.hpp>
#include "cppa/local_actor.hpp" #include "cppa/local_actor.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/scheduler.hpp"
#include "cppa/detail/converted_thread_context.hpp"
using cppa::detail::converted_thread_context;
namespace {
void cleanup_fun(cppa::local_actor* what)
{
auto ptr = dynamic_cast<converted_thread_context*>(what);
if (ptr)
{
// make sure "unspawned" actors quit properly
ptr->cleanup(cppa::exit_reason::normal);
}
if (what && !what->deref()) delete what;
}
boost::thread_specific_ptr<cppa::local_actor> t_this_context(cleanup_fun);
} // namespace <anonymous>
namespace cppa { namespace cppa {
...@@ -33,28 +6,4 @@ local_actor::local_actor() : m_trap_exit(false) ...@@ -33,28 +6,4 @@ local_actor::local_actor() : m_trap_exit(false)
{ {
} }
local_actor* unchecked_self()
{
return t_this_context.get();
}
local_actor* self()
{
local_actor* result = t_this_context.get();
if (result == nullptr)
{
result = new converted_thread_context;
result->ref();
get_scheduler()->register_converted_context(result);
t_this_context.reset(result);
}
return result;
}
void set_self(local_actor* ctx)
{
if (ctx) ctx->ref();
t_this_context.reset(ctx);
}
} // namespace cppa } // namespace cppa
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
#include <atomic> #include <atomic>
#include <iostream> #include <iostream>
#include "cppa/self.hpp"
#include "cppa/any_tuple.hpp" #include "cppa/any_tuple.hpp"
#include "cppa/local_actor.hpp" #include "cppa/local_actor.hpp"
#include "cppa/scheduler.hpp" #include "cppa/scheduler.hpp"
...@@ -25,7 +25,8 @@ namespace { ...@@ -25,7 +25,8 @@ namespace {
void run_actor(cppa::intrusive_ptr<cppa::local_actor> m_self, void run_actor(cppa::intrusive_ptr<cppa::local_actor> m_self,
cppa::scheduled_actor* behavior) cppa::scheduled_actor* behavior)
{ {
cppa::set_self(m_self.get()); cppa::self.set(m_self.get());
//cppa::set_self(m_self.get());
if (behavior) if (behavior)
{ {
try { behavior->act(); } try { behavior->act(); }
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#include <iostream> #include <iostream>
#include "cppa/on.hpp" #include "cppa/on.hpp"
#include "cppa/self.hpp"
#include "cppa/anything.hpp" #include "cppa/anything.hpp"
#include "cppa/to_string.hpp" #include "cppa/to_string.hpp"
#include "cppa/scheduler.hpp" #include "cppa/scheduler.hpp"
...@@ -69,7 +70,8 @@ struct scheduler_helper ...@@ -69,7 +70,8 @@ struct scheduler_helper
void scheduler_helper::time_emitter(scheduler_helper::ptr_type m_self) void scheduler_helper::time_emitter(scheduler_helper::ptr_type m_self)
{ {
// setup & local variables // setup & local variables
set_self(m_self.get()); self.set(m_self.get());
//set_self(m_self.get());
auto& queue = m_self->mailbox(); auto& queue = m_self->mailbox();
//typedef std::pair<cppa::actor_ptr, decltype(queue.pop())> future_msg; //typedef std::pair<cppa::actor_ptr, decltype(queue.pop())> future_msg;
std::multimap<decltype(detail::now()), decltype(queue.pop())> messages; std::multimap<decltype(detail::now()), decltype(queue.pop())> messages;
......
// for thread_specific_ptr
// needed unless the new keyword "thread_local" works in GCC
#include <boost/thread/tss.hpp>
#include "cppa/self.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/scheduler.hpp"
#include "cppa/local_actor.hpp"
#include "cppa/detail/converted_thread_context.hpp"
using cppa::detail::converted_thread_context;
namespace {
void cleanup_fun(cppa::local_actor* what)
{
auto ptr = dynamic_cast<converted_thread_context*>(what);
if (ptr)
{
// make sure "unspawned" actors quit properly
ptr->cleanup(cppa::exit_reason::normal);
}
if (what && !what->deref()) delete what;
}
boost::thread_specific_ptr<cppa::local_actor> t_this_context(cleanup_fun);
} // namespace <anonymous>
namespace cppa {
self_type self;
void self_type::set_impl(local_actor* ptr)
{
if (ptr) ptr->ref();
t_this_context.reset(ptr);
}
local_actor* self_type::get_impl()
{
auto result = t_this_context.get();
if (result == nullptr)
{
result = new converted_thread_context;
result->ref();
get_scheduler()->register_converted_context(result);
t_this_context.reset(result);
}
return result;
}
local_actor* self_type::get_unchecked_impl()
{
return t_this_context.get();
}
} // namespace cppa
...@@ -50,11 +50,11 @@ struct singleton_container ...@@ -50,11 +50,11 @@ struct singleton_container
delete m_network_manager; delete m_network_manager;
} }
// run actor specific cleanup if needed // run actor specific cleanup if needed
if (unchecked_self() != nullptr) if (self.unchecked() != nullptr)
{ {
try try
{ {
unchecked_self()->quit(exit_reason::normal); self.unchecked()->quit(exit_reason::normal);
} }
catch (actor_exited&) catch (actor_exited&)
{ {
......
#include "cppa/cppa.hpp" #include "cppa/cppa.hpp"
#include "cppa/self.hpp"
#include "cppa/detail/invokable.hpp" #include "cppa/detail/invokable.hpp"
#include "cppa/detail/intermediate.hpp" #include "cppa/detail/intermediate.hpp"
#include "cppa/detail/yielding_actor.hpp" #include "cppa/detail/yielding_actor.hpp"
...@@ -101,7 +102,8 @@ void yielding_actor::dequeue(timed_invoke_rules& rules) ...@@ -101,7 +102,8 @@ void yielding_actor::dequeue(timed_invoke_rules& rules)
void yielding_actor::resume(util::fiber* from, resume_callback* callback) void yielding_actor::resume(util::fiber* from, resume_callback* callback)
{ {
set_self(this); self.set(this);
//set_self(this);
for (;;) for (;;)
{ {
call(&m_fiber, from); call(&m_fiber, from);
......
...@@ -32,7 +32,7 @@ size_t test__atom() ...@@ -32,7 +32,7 @@ size_t test__atom()
bool matched_pattern[3] = { false, false, false }; bool matched_pattern[3] = { false, false, false };
CPPA_TEST(test__atom); CPPA_TEST(test__atom);
CPPA_CHECK_EQUAL(to_string(s_foo), "FooBar"); CPPA_CHECK_EQUAL(to_string(s_foo), "FooBar");
self() << make_tuple(atom("foo"), static_cast<std::uint32_t>(42)) self << make_tuple(atom("foo"), static_cast<std::uint32_t>(42))
<< make_tuple(atom(":Attach"), atom(":Baz"), "cstring") << make_tuple(atom(":Attach"), atom(":Baz"), "cstring")
<< make_tuple(atom("b"), atom("a"), atom("c"), 23.f) << make_tuple(atom("b"), atom("a"), atom("c"), 23.f)
<< make_tuple(atom("a"), atom("b"), atom("c"), 23.f); << make_tuple(atom("a"), atom("b"), atom("c"), 23.f);
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "hash_of.hpp" #include "hash_of.hpp"
#include "cppa/on.hpp" #include "cppa/on.hpp"
#include "cppa/self.hpp"
#include "cppa/cppa.hpp" #include "cppa/cppa.hpp"
#include "cppa/actor.hpp" #include "cppa/actor.hpp"
#include "cppa/group.hpp" #include "cppa/group.hpp"
...@@ -26,7 +27,7 @@ size_t test__local_group() ...@@ -26,7 +27,7 @@ size_t test__local_group()
{ {
CPPA_TEST(test__local_group); CPPA_TEST(test__local_group);
auto foo_group = group::get("local", "foo"); auto foo_group = group::get("local", "foo");
actor_ptr master = self(); actor_ptr master = self;
for (int i = 0; i < 5; ++i) for (int i = 0; i < 5; ++i)
{ {
// spawn five workers and let them join local/foo // spawn five workers and let them join local/foo
......
...@@ -22,7 +22,6 @@ void client_part(const std::map<std::string, std::string>& args) ...@@ -22,7 +22,6 @@ void client_part(const std::map<std::string, std::string>& args)
{ {
throw std::runtime_error("no port specified"); throw std::runtime_error("no port specified");
} }
//(void) self();
std::istringstream iss(i->second); std::istringstream iss(i->second);
std::uint16_t port; std::uint16_t port;
iss >> port; iss >> port;
......
...@@ -30,7 +30,7 @@ struct event_testee : public fsm_actor<event_testee> ...@@ -30,7 +30,7 @@ struct event_testee : public fsm_actor<event_testee>
invoke_rules wait4string = invoke_rules wait4string =
( (
on<std::string>() >> [=]() on<std::string>() >> [this]()
{ {
become(&init_state); become(&init_state);
}, },
...@@ -248,7 +248,7 @@ void testee2(actor_ptr other) ...@@ -248,7 +248,7 @@ void testee2(actor_ptr other)
void testee3(actor_ptr parent) void testee3(actor_ptr parent)
{ {
// test a future_send / delayed_reply based loop // test a future_send / delayed_reply based loop
future_send(self(), std::chrono::milliseconds(50), atom("Poll")); future_send(self, std::chrono::milliseconds(50), atom("Poll"));
int polls = 0; int polls = 0;
receive_while([&polls]() { return ++polls <= 5; }) receive_while([&polls]() { return ++polls <= 5; })
( (
...@@ -326,7 +326,7 @@ size_t test__spawn() ...@@ -326,7 +326,7 @@ size_t test__spawn()
// monitor(spawn(testee2, spawn(testee1))); // monitor(spawn(testee2, spawn(testee1)));
int i = 0; int i = 0;
int flags = 0; int flags = 0;
future_send(self(), std::chrono::seconds(1), atom("FooBar")); future_send(self, std::chrono::seconds(1), atom("FooBar"));
// wait for :Down and :Exit messages of pong // wait for :Down and :Exit messages of pong
receive_while([&i]() { return ++i <= 3 /*4*/; }) receive_while([&i]() { return ++i <= 3 /*4*/; })
( (
...@@ -367,7 +367,7 @@ size_t test__spawn() ...@@ -367,7 +367,7 @@ size_t test__spawn()
// verify pong messages // verify pong messages
CPPA_CHECK_EQUAL(pongs(), 5); CPPA_CHECK_EQUAL(pongs(), 5);
/* /*
spawn(testee3, self()); spawn(testee3, self);
i = 0; i = 0;
// testee3 sends 5 { "Push", int } messages in a 50 milliseconds interval; // testee3 sends 5 { "Push", int } messages in a 50 milliseconds interval;
// allow for a maximum error of 5ms // allow for a maximum error of 5ms
......
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