2 * Copyright (c) 2000-2008, Ingo Weinhold <ingo_weinhold@gmx.de>,
3 * Copyright (c) 2000-2008, Stephan Aßmus <superstippi@gmx.de>,
4 * All Rights Reserved. Distributed under the terms of the MIT license.
11 #include "EventQueue.h"
16 EventQueue::EventQueue()
24 fThreadControl
= create_sem(0, "event queue control");
25 if (fThreadControl
>= B_OK
)
28 fStatus
= fThreadControl
;
29 if (fStatus
== B_OK
) {
30 fEventExecutor
= spawn_thread(_execute_events_
, "event queue runner",
31 B_NORMAL_PRIORITY
, this);
32 if (fEventExecutor
>= B_OK
) {
34 resume_thread(fEventExecutor
);
36 fStatus
= fEventExecutor
;
41 EventQueue::~EventQueue()
43 if (delete_sem(fThreadControl
) == B_OK
)
44 wait_for_thread(fEventExecutor
, &fEventExecutor
);
45 while (Event
*event
= (Event
*)fEvents
.RemoveItem((int32
)0)) {
46 if (event
->AutoDelete())
53 EventQueue::InitCheck()
60 EventQueue::CreateDefault()
63 fDefaultQueue
= new(nothrow
) EventQueue
;
64 if (fDefaultQueue
&& fDefaultQueue
->InitCheck() != B_OK
)
72 EventQueue::DeleteDefault()
84 return *fDefaultQueue
;
89 EventQueue::AddEvent(Event
* event
)
99 EventQueue::RemoveEvent(Event
* event
)
103 if ((result
= fEvents
.RemoveItem(event
)))
111 EventQueue::ChangeEvent(Event
* event
, bigtime_t newTime
)
114 if (fEvents
.RemoveItem(event
)) {
115 event
->SetTime(newTime
);
123 // PRE: The object must be locked.
125 EventQueue::_AddEvent(Event
* event
)
127 // find the insertion index
129 int32 upper
= fEvents
.CountItems();
130 while (lower
< upper
) {
131 int32 mid
= (lower
+ upper
) / 2;
132 Event
* midEvent
= _EventAt(mid
);
133 if (event
->Time() < midEvent
->Time())
138 fEvents
.AddItem(event
, lower
);
143 EventQueue::_EventAt(int32 index
) const
145 return (Event
*)fEvents
.ItemAtFast(index
);
150 EventQueue::_execute_events_(void* cookie
)
152 EventQueue
*gc
= (EventQueue
*)cookie
;
153 return gc
->_ExecuteEvents();
158 EventQueue::_ExecuteEvents()
162 bigtime_t waitUntil
= B_INFINITE_TIMEOUT
;
164 if (!fEvents
.IsEmpty())
165 waitUntil
= _EventAt(0)->Time();
166 fNextEventTime
= waitUntil
;
169 status_t err
= acquire_sem_etc(fThreadControl
, 1, B_ABSOLUTE_TIMEOUT
,
173 // execute events, that are supposed to go off
175 while (!fEvents
.IsEmpty()
176 && system_time() >= _EventAt(0)->Time()) {
177 Event
* event
= (Event
*)fEvents
.RemoveItem((int32
)0);
178 bool deleteEvent
= event
->AutoDelete();
198 // PRE: The object must be locked.
200 EventQueue::_Reschedule()
202 if (fStatus
== B_OK
) {
203 if (!fEvents
.IsEmpty() && _EventAt(0)->Time() < fNextEventTime
)
204 release_sem(fThreadControl
);
211 EventQueue
* EventQueue::fDefaultQueue
= NULL
;