3 * Author: Lukas Krejci <krejci.l@centrum.cz>, (C) 2008
4 * Copyright: See COPYING file that comes with this distribution
7 #include <beacons/event_queue.hpp>
8 #include <beacons/detail/quick_wait.hpp>
15 //used by dequeue method to decide whether to remove an invokable from the queue
16 bool token_not_equal(invokable::token_ptr
& token
, event_queue::ev_ptr inv
) {
17 return token
.get() != inv
->token().get();
20 void invoke_and_delete(event_queue::ev_ptr inv
) {
22 invokable::token_ptr
const & token
= inv
->token();
24 invokable::token_type::lock_t
lock(token
->guard());
31 //TODO figure out what to do here
36 void delete_invokable(event_queue::ev_ptr inv
) {
40 event_queue::~event_queue() {
41 detail::wait(_queue_guard
);
43 std::for_each(_events
.begin(), _events
.end(), &invoke_and_delete
);
46 std::for_each(_dequeued
.begin(), _dequeued
.end(), &delete_invokable
);
49 //don't unlock the queue so that nothing can modify it anymore...
52 void event_queue::enqueue(ev_ptr inv
) {
53 //enter the critical section
54 detail::wait(_queue_guard
);
56 _events
.push_back(inv
);
58 //leave the critical section
59 detail::notify(_queue_guard
);
62 void event_queue::dequeue(invokable::token_ptr token
) {
63 //enter the critical section
64 detail::wait(_queue_guard
);
66 std::deque
<ev_ptr
>::iterator end
= _events
.end();
68 std::deque
<ev_ptr
>::iterator first_bad
=
69 stable_partition(_events
.begin(), end
,
70 boost::bind(&token_not_equal
, token
, _1
));
72 _dequeued
.insert(first_bad
, end
);
74 _events
.erase(first_bad
, end
);
76 //leave the critical section
77 detail::notify(_queue_guard
);
80 void event_queue::invoke_enqueued() {
81 detail::wait(_queue_guard
);
83 std::deque
<ev_ptr
> evs_cpy
;
84 std::set
<ev_ptr
> deq_cpy
;
86 unsigned evs
= _events
.size();
87 unsigned des
= _dequeued
.size();
89 //check if there's anything to do at all...
90 if ((evs
| des
) == 0) {
91 detail::notify(_queue_guard
);
95 //copy the current events... this is to block the enquing as little
107 detail::notify(_queue_guard
);
110 std::for_each(evs_cpy
.begin(), evs_cpy
.end(), &invoke_and_delete
);
114 std::for_each(deq_cpy
.begin(), deq_cpy
.end(), &delete_invokable
);
118 void event_queue::invoke_synchronously() {
119 detail::wait(_queue_guard
);
121 std::for_each(_events
.begin(), _events
.end(), &invoke_and_delete
);
124 std::for_each(_dequeued
.begin(), _dequeued
.end(), &delete_invokable
);
127 detail::notify(_queue_guard
);
130 } //namespace beacons