3 * Author: Lukas Krejci <krejci.l@centrum.cz>, (C) 2008
4 * Copyright: See COPYING file that comes with this distribution
7 #ifndef BEACON_EVENT_LOOP_H
8 #define BEACON_EVENT_LOOP_H
10 #include <beacon/invokable.hpp>
11 #include <beacon/detail/in_loop_invoke.hpp>
12 #include <beacon/detail/quick_wait.hpp>
13 #include <boost/thread.hpp>
14 #include <boost/bind.hpp>
15 #include <boost/type_traits/add_pointer.hpp>
19 #include <atomic_ops.h>
25 * Event loop is a thread that invokes slots for signals.
26 * When connecting a slot to signal::signal
27 * one can specify an event loop that the slot will be invoked
29 * This is to support thread-safe signals&slots mechanism.
30 * The invocations are thread safe as long as all the signals
31 * are connected to a slot with the same event loop and
32 * all the arguments of the signal are copy-constructible (with deep
33 * copying semantics). Care must be taken when the arguments are
34 * references or pointers as it is not guaranteed when the slots
35 * will actually be invoked after the signal has been emitted.
39 typedef invokable
* ev_type
;
42 * A new thread is started to handle this event loop.
45 _queue_guard(AO_TS_INITIALIZER
),
51 * This call does NOT block until the underlying thread finishes.
52 * It just destroys the event_loop object without stopping
53 * the underlying thread. Be sure to call @link join method before
54 * the event_loop is destroyed.
57 if (_thread
) delete _thread
;
61 * Enqueues given invokable to be executed in the event loop thread at some
62 * point in the future.
64 * The event loop takes over the ownership of the invokable once it is passed
65 * to this method. Therefore the invokable must not be destroyed by the user code
66 * once passed to this method.
68 * @param invokable the invokable object to put into the event loop queue.
70 void enqueue(ev_type invokable
);
73 * Removes invokables identified by given token from the event loop queue.
75 * @param token the token of the invokable to remove from the queue.
77 * @return how many invokables have been removed from the queue.
79 unsigned dequeue(invokable::token_type token
);
82 * Starts the event loop. The events can be enqueued and dequeued before
83 * the event loop is started but they won't be processed until it is.
86 _thread
= new boost::thread(boost::bind(&event_loop::run
, this));
90 * Joins the event loop thread. If the thread is started using the {@link start} method
91 * while another thread is executing this method, the result is undefined.
95 //list of events to process
96 std::deque
<ev_type
> _events
;
98 //list of recently dequeued events that need destroyed
99 std::deque
<ev_type
> _dequeued
;
101 //the thread we're executing the events in
102 boost::thread
* _thread
;
104 //the queue modification guard
105 volatile AO_TS_t _queue_guard
;
107 //controlling the thread alive-state
116 * A helper class to enqueue function calls in the event loop.
118 template<typename Signature
>
122 * A helper structure to represent the return type of the enqueue::invoke method
127 typedef typename
detail::in_loop_wrapper_future_pointer
<F
, typename
boost::add_pointer
<Signature
>::type
> type
;
131 * A helper structure to represent the return type of the enqueue::call method
136 typedef typename
detail::in_loop_wrapper_no_future
<F
, typename
boost::add_pointer
<Signature
>::type
> type
;
140 * Using this function one can obtain a function object that
141 * when invoked enqueues the actual computation in the provided
142 * event loop and returns a pointer to a future object that can be used
143 * to obtain the return value. The receiver is responsible for destroying
144 * that future object afterwards.
145 * @param el the event_loop to be used
146 * @param f the function to be called in event_loop
147 * @param token a token uniquely identifying the function. This token is
148 * then used in event_loop disconnect method.
149 * @return a function object with operator () defined as:
150 * \c beacon::future<R> * operator()(ARGS)
151 * \endcode, where R is the
152 * return type of the supplied function and ARGS are its argument types.
155 static typename invokable
<F
>::type
invoke(event_loop
& el
, F
const & f
, beacon::invokable::token_type token
) {
156 return typename invokable
<F
>::type(el
, &f
, token
);
160 * Using this function one can obtain a function object that
161 * when invoked enqueues the actual computation in the provided
162 * event loop and is not able to query the result in any manner.
163 * Note that this is by far the fastest method and should be used
165 * @param el the event_loop to be used
166 * @param f the function to be called in event_loop
167 * @param token a token uniquely identifying the function. This token is
168 * then used in event_loop disconnect method.
169 * @return a function object with operator () defined as:
170 * \c void * operator()(ARGS)
171 * \endcode, where ARGS are argument types of the supplied function f.
174 static typename callable
<F
>::type
call(event_loop
& el
, F
const & f
, beacon::invokable::token_type token
) {
175 return typename callable
<F
>::type(el
, &f
, token
);