Commit 0f8c067e authored by Dominik Charousset's avatar Dominik Charousset

maintenance & documentation

parent b0fb47b1
This diff is collapsed.
...@@ -55,6 +55,20 @@ class scheduler_helper; ...@@ -55,6 +55,20 @@ class scheduler_helper;
typedef std::function<void()> void_function; typedef std::function<void()> void_function;
typedef std::function<void(local_actor*)> init_callback; typedef std::function<void(local_actor*)> init_callback;
namespace detail {
// forwards self_type as actor_ptr, otherwise equal to std::forward
template<typename T>
struct spawn_fwd_ {
static inline T&& _(T&& arg) { return std::move(arg); }
static inline T& _(T& arg) { return arg; }
static inline const T& _(const T& arg) { return arg; }
};
template<>
struct spawn_fwd_<self_type> {
static inline actor_ptr _(const self_type& s) { return s.get(); }
};
} // namespace detail
/** /**
* @brief * @brief
*/ */
...@@ -84,6 +98,31 @@ class scheduler { ...@@ -84,6 +98,31 @@ class scheduler {
virtual void enqueue(scheduled_actor*) = 0; virtual void enqueue(scheduled_actor*) = 0;
/**
* @brief Informs the scheduler about a converted context
* (a thread that acts as actor).
* @note Calls <tt>what->attach(...)</tt>.
*/
virtual void register_converted_context(local_actor* what);
/**
* @brief Informs the scheduler about a hidden (non-actor)
* context that should be counted by await_others_done().
* @returns An {@link attachable} that the hidden context has to destroy
* if his lifetime ends.
*/
virtual attachable* register_hidden_context();
template<typename Duration, typename... Data>
void delayed_send(const channel_ptr& to,
const Duration& rel_time,
Data&&... data) {
static_assert(sizeof...(Data) > 0, "no message to send");
auto sub = make_any_tuple(std::forward<Data>(data)...);
auto tup = make_any_tuple(util::duration{rel_time}, to, std::move(sub));
delayed_send_helper()->enqueue(self, std::move(tup));
}
/** /**
* @brief Spawns a new actor that executes <code>fun()</code> * @brief Spawns a new actor that executes <code>fun()</code>
* with the scheduling policy @p hint if possible. * with the scheduling policy @p hint if possible.
...@@ -112,31 +151,46 @@ class scheduler { ...@@ -112,31 +151,46 @@ class scheduler {
*/ */
virtual actor_ptr spawn(scheduled_actor* what, init_callback init_cb) = 0; virtual actor_ptr spawn(scheduled_actor* what, init_callback init_cb) = 0;
/** // hide implementation details for documentation
* @brief Informs the scheduler about a converted context # ifndef CPPA_DOCUMENTATION
* (a thread that acts as actor).
* @note Calls <tt>what->attach(...)</tt>. template<typename Fun, typename Arg0, typename... Args>
*/ actor_ptr spawn_impl(scheduling_hint hint, Fun&& fun, Arg0&& arg0, Args&&... args) {
virtual void register_converted_context(local_actor* what); return this->spawn(
std::bind(
std::forward<Fun>(fun),
detail::spawn_fwd_<typename util::rm_ref<Arg0>::type>::_(arg0),
detail::spawn_fwd_<typename util::rm_ref<Args>::type>::_(args)...),
hint);
}
/** template<typename Fun>
* @brief Informs the scheduler about a hidden (non-actor) actor_ptr spawn_impl(scheduling_hint hint, Fun&& fun) {
* context that should be counted by await_others_done(). return this->spawn(std::forward<Fun>(fun), hint);
* @returns An {@link attachable} that the hidden context has to destroy }
* if his lifetime ends.
*/
virtual attachable* register_hidden_context();
template<typename Duration, typename... Data> template<typename InitCallback, typename Fun, typename Arg0, typename... Args>
void delayed_send(const actor_ptr& to, actor_ptr spawn_cb_impl(scheduling_hint hint,
const Duration& rel_time, InitCallback&& init_cb,
Data&&... data) { Fun&& fun, Arg0&& arg0, Args&&... args) {
static_assert(sizeof...(Data) > 0, "no message to send"); return this->spawn(
auto sub = make_any_tuple(std::forward<Data>(data)...); std::bind(
auto tup = make_any_tuple(util::duration{rel_time}, to, std::move(sub)); std::forward<Fun>(fun),
delayed_send_helper()->enqueue(self, std::move(tup)); detail::spawn_fwd_<typename util::rm_ref<Arg0>::type>::_(arg0),
detail::spawn_fwd_<typename util::rm_ref<Args>::type>::_(args)...),
hint,
std::forward<InitCallback>(init_cb));
} }
template<typename InitCallback, typename Fun>
actor_ptr spawn_cb_impl(scheduling_hint hint, InitCallback&& init_cb, Fun&& fun) {
return this->spawn(std::forward<Fun>(fun),
hint,
std::forward<InitCallback>(init_cb));
}
# endif // CPPA_DOCUMENTATION
}; };
/** /**
......
...@@ -49,7 +49,8 @@ extern local_actor* self; ...@@ -49,7 +49,8 @@ extern local_actor* self;
class local_actor; class local_actor;
// convertible<...> enables "actor_ptr this_actor = self;" // convertible<...> enables "actor_ptr this_actor = self;"
class self_type : public convertible<self_type, actor*> { class self_type : public convertible<self_type, actor*>,
public convertible<self_type, channel*> {
self_type(const self_type&) = delete; self_type(const self_type&) = delete;
self_type& operator=(const self_type&) = delete; self_type& operator=(const self_type&) = delete;
......
...@@ -68,8 +68,7 @@ class down_observer : public attachable { ...@@ -68,8 +68,7 @@ class down_observer : public attachable {
} // namespace <anonymous> } // namespace <anonymous>
local_actor::local_actor(bool sflag) local_actor::local_actor(bool sflag)
: m_chaining(sflag), m_trap_exit(false), m_is_scheduled(sflag) { : m_chaining(sflag), m_trap_exit(false), m_is_scheduled(sflag) { }
}
void local_actor::monitor(actor_ptr whom) { void local_actor::monitor(actor_ptr whom) {
if (whom) whom->attach(new down_observer(this, whom)); if (whom) whom->attach(new down_observer(this, whom));
...@@ -85,14 +84,14 @@ void local_actor::on_exit() { } ...@@ -85,14 +84,14 @@ void local_actor::on_exit() { }
void local_actor::init() { } void local_actor::init() { }
void local_actor::join(const group_ptr& what) { void local_actor::join(const group_ptr& what) {
if (!what) return; if (what) attach(what->subscribe(this));
attach(what->subscribe(this));
} }
void local_actor::leave(const group_ptr& what) { void local_actor::leave(const group_ptr& what) {
if (!what) return; if (what) {
attachable::token group_token(typeid(group::unsubscriber), what.get()); attachable::token group_token(typeid(group::unsubscriber), what.get());
detach(group_token); detach(group_token);
}
} }
} // namespace cppa } // namespace cppa
...@@ -108,8 +108,8 @@ void scheduler_helper::time_emitter(scheduler_helper::ptr_type m_self) { ...@@ -108,8 +108,8 @@ void scheduler_helper::time_emitter(scheduler_helper::ptr_type m_self) {
bool done = false; bool done = false;
// message handling rules // message handling rules
auto mfun = ( auto mfun = (
on<util::duration,actor_ptr,anything>() >> [&](const util::duration& d, on<util::duration,channel_ptr,anything>() >> [&](const util::duration& d,
const actor_ptr&) { const channel_ptr&) {
// calculate timeout // calculate timeout
auto timeout = now(); auto timeout = now();
timeout += d; timeout += d;
......
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