mirror of
https://github.com/genodelabs/genode.git
synced 2025-04-10 21:01:49 +00:00
parent
de7d4a5523
commit
60106ac2c8
@ -171,7 +171,8 @@ class Genode::Timeout : private Noncopyable
|
||||
|
||||
Mutex _dispatch_mutex { };
|
||||
Raw _raw { };
|
||||
int _active { 0 };
|
||||
short _active { 0 };
|
||||
bool _delete { false };
|
||||
Alarm *_next { nullptr };
|
||||
Alarm_timeout_scheduler *_scheduler { nullptr };
|
||||
|
||||
|
@ -76,6 +76,8 @@ struct Timer::Periodic_timeout : private Genode::Noncopyable
|
||||
{
|
||||
_timeout.schedule_periodic(duration, _handler);
|
||||
}
|
||||
|
||||
~Periodic_timeout() { _timeout.discard(); }
|
||||
};
|
||||
|
||||
|
||||
@ -121,6 +123,8 @@ class Timer::One_shot_timeout : private Genode::Noncopyable
|
||||
Handler_method method)
|
||||
: _timeout(timeout_scheduler), _handler(object, method) { }
|
||||
|
||||
~One_shot_timeout() { _timeout.discard(); }
|
||||
|
||||
void schedule(Microseconds duration) {
|
||||
_timeout.schedule_one_shot(duration, _handler); }
|
||||
|
||||
|
@ -236,24 +236,30 @@ Timeout::Alarm *Alarm_timeout_scheduler::_alarm_get_pending_alarm()
|
||||
{
|
||||
Mutex::Guard mutex_guard(_mutex);
|
||||
|
||||
if (!_active_head || !_active_head->_raw.is_pending_at(_now, _now_period)) {
|
||||
return nullptr; }
|
||||
do {
|
||||
if (!_active_head || !_active_head->_raw.is_pending_at(_now, _now_period)) {
|
||||
return nullptr; }
|
||||
|
||||
/* remove alarm from head of the list */
|
||||
Alarm *pending_alarm = _active_head;
|
||||
_active_head = _active_head->_next;
|
||||
/* remove alarm from head of the list */
|
||||
Alarm *pending_alarm = _active_head;
|
||||
_active_head = _active_head->_next;
|
||||
|
||||
/*
|
||||
* Acquire dispatch mutex to defer destruction until the call of '_on_alarm'
|
||||
* is finished
|
||||
*/
|
||||
pending_alarm->_dispatch_mutex.acquire();
|
||||
/*
|
||||
* Acquire dispatch mutex to defer destruction until the call of '_on_alarm'
|
||||
* is finished
|
||||
*/
|
||||
pending_alarm->_dispatch_mutex.acquire();
|
||||
|
||||
/* reset alarm object */
|
||||
pending_alarm->_next = nullptr;
|
||||
pending_alarm->_active--;
|
||||
/* reset alarm object */
|
||||
pending_alarm->_next = nullptr;
|
||||
pending_alarm->_active--;
|
||||
|
||||
return pending_alarm;
|
||||
if (pending_alarm->_delete) {
|
||||
pending_alarm->_dispatch_mutex.release();
|
||||
continue;
|
||||
}
|
||||
return pending_alarm;
|
||||
} while (true);
|
||||
}
|
||||
|
||||
|
||||
@ -399,11 +405,19 @@ void Alarm_timeout_scheduler::_alarm_discard(Alarm *alarm)
|
||||
* is finished, '_alarm_get_pending_alarm' would proceed with operating on
|
||||
* a dangling pointer.
|
||||
*/
|
||||
Mutex::Guard alarm_list_guard(_mutex);
|
||||
|
||||
if (alarm) {
|
||||
{
|
||||
/* inform that this object is going to be deleted */
|
||||
Mutex::Guard alarm_guard(alarm->_dispatch_mutex);
|
||||
alarm->_delete = true;
|
||||
}
|
||||
{
|
||||
Mutex::Guard alarm_list_guard(_mutex);
|
||||
_alarm_unsynchronized_dequeue(alarm);
|
||||
}
|
||||
|
||||
/* get anyone using this out of '_alarm_get_pending_alarm'() finally */
|
||||
Mutex::Guard alarm_guard(alarm->_dispatch_mutex);
|
||||
_alarm_unsynchronized_dequeue(alarm);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user