Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
mpd
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Иван Мажукин
mpd
Commits
010855a2
Commit
010855a2
authored
Aug 29, 2017
by
Max Kellermann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
event/Loop: use boost::intrusive::multiset to store TimeoutMonitors
By using an "intrusive" data structure, we can easily eliminate struct TimerRecord.
parent
71ed3ff9
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
31 additions
and
50 deletions
+31
-50
Loop.cxx
src/event/Loop.cxx
+4
-22
Loop.hxx
src/event/Loop.hxx
+16
-12
TimeoutMonitor.cxx
src/event/TimeoutMonitor.cxx
+1
-11
TimeoutMonitor.hxx
src/event/TimeoutMonitor.hxx
+10
-5
No files found.
src/event/Loop.cxx
View file @
010855a2
...
...
@@ -19,7 +19,6 @@
#include "config.h"
#include "Loop.hxx"
#include "TimeoutMonitor.hxx"
#include "SocketMonitor.hxx"
#include "IdleMonitor.hxx"
#include "DeferredMonitor.hxx"
...
...
@@ -27,18 +26,6 @@
#include <algorithm>
inline
std
::
chrono
::
steady_clock
::
time_point
EventLoop
::
TimerRecord
::
GetDue
()
const
noexcept
{
return
timer
.
due
;
}
inline
bool
EventLoop
::
TimerRecord
::
operator
<
(
const
TimerRecord
&
other
)
const
noexcept
{
return
timer
.
due
<
other
.
timer
.
due
;
}
EventLoop
::
EventLoop
(
ThreadId
_thread
)
:
SocketMonitor
(
*
this
),
thread
(
_thread
)
{
...
...
@@ -106,7 +93,7 @@ EventLoop::AddTimer(TimeoutMonitor &t, std::chrono::steady_clock::duration d)
assert
(
IsInside
());
t
.
due
=
now
+
d
;
timers
.
insert
(
TimerRecord
(
t
)
);
timers
.
insert
(
t
);
again
=
true
;
}
...
...
@@ -115,12 +102,7 @@ EventLoop::CancelTimer(TimeoutMonitor &t)
{
assert
(
IsInside
());
for
(
auto
i
=
timers
.
begin
(),
end
=
timers
.
end
();
i
!=
end
;
++
i
)
{
if
(
&
i
->
timer
==
&
t
)
{
timers
.
erase
(
i
);
return
;
}
}
timers
.
erase
(
timers
.
iterator_to
(
t
));
}
/**
...
...
@@ -163,11 +145,11 @@ EventLoop::Run()
break
;
}
timeout
=
i
->
GetDue
()
-
now
;
TimeoutMonitor
&
m
=
*
i
;
timeout
=
m
.
due
-
now
;
if
(
timeout
>
timeout
.
zero
())
break
;
TimeoutMonitor
&
m
=
i
->
timer
;
timers
.
erase
(
i
);
m
.
Run
();
...
...
src/event/Loop.hxx
View file @
010855a2
...
...
@@ -28,6 +28,9 @@
#include "thread/Mutex.hxx"
#include "WakeFD.hxx"
#include "SocketMonitor.hxx"
#include "TimeoutMonitor.hxx"
#include <boost/intrusive/set.hpp>
#include <chrono>
#include <list>
...
...
@@ -50,22 +53,23 @@ class DeferredMonitor;
*/
class
EventLoop
final
:
SocketMonitor
{
struct
TimerRecord
{
TimeoutMonitor
&
timer
;
explicit
constexpr
TimerRecord
(
TimeoutMonitor
&
_timer
)
:
timer
(
_timer
)
{}
gcc_pure
std
::
chrono
::
steady_clock
::
time_point
GetDue
()
const
noexcept
;
WakeFD
wake_fd
;
gcc_pure
bool
operator
<
(
const
TimerRecord
&
other
)
const
noexcept
;
struct
TimerCompare
{
constexpr
bool
operator
()(
const
TimeoutMonitor
&
a
,
const
TimeoutMonitor
&
b
)
const
{
return
a
.
due
<
b
.
due
;
}
};
WakeFD
wake_fd
;
typedef
boost
::
intrusive
::
multiset
<
TimeoutMonitor
,
boost
::
intrusive
::
member_hook
<
TimeoutMonitor
,
TimeoutMonitor
::
TimerSetHook
,
&
TimeoutMonitor
::
timer_set_hook
>
,
boost
::
intrusive
::
compare
<
TimerCompare
>
,
boost
::
intrusive
::
constant_time_size
<
false
>>
TimerSet
;
TimerSet
timers
;
std
::
multiset
<
TimerRecord
>
timers
;
std
::
list
<
IdleMonitor
*>
idle
;
Mutex
mutex
;
...
...
src/event/TimeoutMonitor.cxx
View file @
010855a2
...
...
@@ -24,10 +24,8 @@
void
TimeoutMonitor
::
Cancel
()
{
if
(
IsActive
())
{
active
=
false
;
if
(
IsActive
())
loop
.
CancelTimer
(
*
this
);
}
}
void
...
...
@@ -35,13 +33,5 @@ TimeoutMonitor::Schedule(std::chrono::steady_clock::duration d)
{
Cancel
();
active
=
true
;
loop
.
AddTimer
(
*
this
,
d
);
}
void
TimeoutMonitor
::
Run
()
{
active
=
false
;
OnTimeout
();
}
src/event/TimeoutMonitor.hxx
View file @
010855a2
...
...
@@ -22,6 +22,8 @@
#include "check.h"
#include <boost/intrusive/set_hook.hpp>
#include <chrono>
class
EventLoop
;
...
...
@@ -37,6 +39,9 @@ class EventLoop;
class
TimeoutMonitor
{
friend
class
EventLoop
;
typedef
boost
::
intrusive
::
set_member_hook
<>
TimerSetHook
;
TimerSetHook
timer_set_hook
;
EventLoop
&
loop
;
/**
...
...
@@ -45,11 +50,9 @@ class TimeoutMonitor {
*/
std
::
chrono
::
steady_clock
::
time_point
due
;
bool
active
;
public
:
TimeoutMonitor
(
EventLoop
&
_loop
)
:
loop
(
_loop
)
,
active
(
false
)
{
:
loop
(
_loop
)
{
}
~
TimeoutMonitor
()
{
...
...
@@ -61,7 +64,7 @@ public:
}
bool
IsActive
()
const
{
return
active
;
return
timer_set_hook
.
is_linked
()
;
}
void
Schedule
(
std
::
chrono
::
steady_clock
::
duration
d
);
...
...
@@ -71,7 +74,9 @@ protected:
virtual
void
OnTimeout
()
=
0
;
private
:
void
Run
();
void
Run
()
{
OnTimeout
();
}
};
#endif
/* MAIN_NOTIFY_H */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment