3 * Author: Lukas Krejci <krejci.l@centrum.cz>, (C) 2008
4 * Copyright: See COPYING file that comes with this distribution
7 #include <beacon/event_loop.hpp>
13 //used by dequeue method to decide whether to remove an invokable from the queue
14 bool token_compare(void const * token
, invokable
* inv
) {
15 return token
== inv
->token();
18 void invoke_and_delete(invokable
* inv
) {
22 //TODO figure out what to do here
27 void delete_invokable(invokable
* inv
) {
31 void event_loop::enqueue(ev_type inv
) {
33 //enter the critical section
34 detail::wait(_queue_guard
);
36 _events
.push_back(inv
);
38 //leave the critical section
39 detail::notify(_queue_guard
);
43 unsigned event_loop::dequeue(void const * token
) {
44 //enter the critical section
45 detail::wait(_queue_guard
);
47 std::deque
<ev_type
>::iterator
const & first_bad
=
48 remove_if(_events
.begin(), _events
.end(),
49 boost::bind(&token_compare
, token
, _1
));
51 _dequeued
.assign(first_bad
, _events
.end());
53 _events
.erase(first_bad
, _events
.end());
55 unsigned size
= _dequeued
.size();
57 //leave the critical section
58 detail::notify(_queue_guard
);
63 void event_loop::join() {
67 while(!_finished
) boost::thread::yield();
73 void event_loop::run() {
74 std::deque
<ev_type
> evs_cpy
;
75 std::deque
<ev_type
> deq_cpy
;
78 detail::wait(_queue_guard
);
80 unsigned evs
= _events
.size();
81 unsigned des
= _dequeued
.size();
83 //check if there's anything to do at all...
84 if ((evs
| des
) == 0) {
85 detail::notify(_queue_guard
);
86 boost::thread::yield();
90 //copy the current events... this is to block the enquing as little
102 detail::notify(_queue_guard
);
104 //a little bit weird situation might occur here.
105 //when an event is added to the queue while the processing
106 //thread is in this code segment, it won't be processed
107 //until the processing thread is woken up again when another
108 //event is enqued or it is dying.
111 std::for_each(evs_cpy
.begin(), evs_cpy
.end(), &invoke_and_delete
);
115 std::for_each(deq_cpy
.begin(), deq_cpy
.end(), &delete_invokable
);
118 boost::thread::yield();
121 //flush the rest of the events before we die...
123 detail::wait(_queue_guard
);
125 std::for_each(_events
.begin(), _events
.end(), &invoke_and_delete
);
128 std::for_each(_dequeued
.begin(), _dequeued
.end(), &delete_invokable
);
133 detail::notify(_queue_guard
);