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
4223657a
Commit
4223657a
authored
Aug 06, 2013
by
Max Kellermann
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
event/SignalMonitor: use signalfd() if available
parent
930128a7
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
194 additions
and
1 deletion
+194
-1
Makefile.am
Makefile.am
+1
-0
configure.ac
configure.ac
+1
-0
SignalMonitor.cxx
src/event/SignalMonitor.cxx
+72
-1
SignalFD.cxx
src/system/SignalFD.cxx
+58
-0
SignalFD.hxx
src/system/SignalFD.hxx
+62
-0
No files found.
Makefile.am
View file @
4223657a
...
...
@@ -288,6 +288,7 @@ libsystem_a_SOURCES = \
src/system/SocketUtil.cxx src/system/SocketUtil.hxx
\
src/system/SocketError.hxx
\
src/system/resolver.c src/system/resolver.h
\
src/system/SignalFD.cxx src/system/SignalFD.hxx
\
src/system/clock.c src/system/clock.h
# Event loop library
...
...
configure.ac
View file @
4223657a
...
...
@@ -141,6 +141,7 @@ AC_SEARCH_LIBS([gethostbyname], [nsl])
AC_CHECK_FUNCS(pipe2 accept4)
MPD_OPTIONAL_FUNC(eventfd, USE_EVENTFD)
MPD_OPTIONAL_FUNC(signalfd, USE_SIGNALFD)
AC_SEARCH_LIBS([exp], [m],,
[AC_MSG_ERROR([exp() not found])])
...
...
src/event/SignalMonitor.cxx
View file @
4223657a
...
...
@@ -27,27 +27,58 @@
#include "util/Manual.hxx"
#include "system/FatalError.hxx"
#ifdef USE_SIGNALFD
#include "system/SignalFD.hxx"
#else
#include "WakeFD.hxx"
#endif
#ifndef USE_SIGNALFD
#include <atomic>
#endif
#include <algorithm>
class
SignalMonitor
final
:
private
SocketMonitor
{
#ifdef USE_SIGNALFD
SignalFD
fd
;
#else
WakeFD
fd
;
#endif
public
:
SignalMonitor
(
EventLoop
&
_loop
)
:
SocketMonitor
(
_loop
)
{
#ifndef USE_SIGNALFD
SocketMonitor
::
Open
(
fd
.
Get
());
SocketMonitor
::
ScheduleRead
();
#endif
}
~
SignalMonitor
()
{
/* prevent the descriptor to be closed twice */
SocketMonitor
::
Steal
();
#ifdef USE_SIGNALFD
if
(
SocketMonitor
::
IsDefined
())
#endif
SocketMonitor
::
Steal
();
}
#ifdef USE_SIGNALFD
void
Update
(
sigset_t
&
mask
)
{
const
bool
was_open
=
SocketMonitor
::
IsDefined
();
fd
.
Create
(
mask
);
if
(
!
was_open
)
{
SocketMonitor
::
Open
(
fd
.
Get
());
SocketMonitor
::
ScheduleRead
();
}
}
#else
void
WakeUp
()
{
fd
.
Write
();
}
#endif
private
:
virtual
bool
OnSocketReady
(
unsigned
flags
)
override
;
...
...
@@ -57,10 +88,16 @@ private:
static
constexpr
unsigned
MAX_SIGNAL
=
64
;
static
SignalHandler
signal_handlers
[
MAX_SIGNAL
];
#ifdef USE_SIGNALFD
static
sigset_t
signal_mask
;
#else
static
std
::
atomic_bool
signal_pending
[
MAX_SIGNAL
];
#endif
static
Manual
<
SignalMonitor
>
monitor
;
#ifndef USE_SIGNALFD
static
void
SignalCallback
(
int
signo
)
{
...
...
@@ -69,13 +106,20 @@ SignalCallback(int signo)
if
(
!
signal_pending
[
signo
].
exchange
(
true
))
monitor
->
WakeUp
();
}
#endif
void
SignalMonitorInit
(
EventLoop
&
loop
)
{
#ifdef USE_SIGNALFD
sigemptyset
(
&
signal_mask
);
#endif
monitor
.
Construct
(
loop
);
}
#ifndef USE_SIGNALFD
static
void
x_sigaction
(
int
signum
,
const
struct
sigaction
&
act
)
{
...
...
@@ -83,9 +127,14 @@ x_sigaction(int signum, const struct sigaction &act)
FatalSystemError
(
"sigaction() failed"
);
}
#endif
void
SignalMonitorFinish
()
{
#ifdef USE_SIGNALFD
std
::
fill_n
(
signal_handlers
,
MAX_SIGNAL
,
nullptr
);
#else
struct
sigaction
sa
;
sa
.
sa_flags
=
0
;
sigemptyset
(
&
sa
.
sa_mask
);
...
...
@@ -99,6 +148,7 @@ SignalMonitorFinish()
}
std
::
fill_n
(
signal_pending
,
MAX_SIGNAL
,
false
);
#endif
monitor
.
Destruct
();
}
...
...
@@ -107,25 +157,46 @@ void
SignalMonitorRegister
(
int
signo
,
SignalHandler
handler
)
{
assert
(
signal_handlers
[
signo
]
==
nullptr
);
#ifndef USE_SIGNALFD
assert
(
!
signal_pending
[
signo
]);
#endif
signal_handlers
[
signo
]
=
handler
;
#ifdef USE_SIGNALFD
sigaddset
(
&
signal_mask
,
signo
);
if
(
sigprocmask
(
SIG_BLOCK
,
&
signal_mask
,
nullptr
)
<
0
)
FatalSystemError
(
"sigprocmask() failed"
);
monitor
->
Update
(
signal_mask
);
#else
struct
sigaction
sa
;
sa
.
sa_flags
=
0
;
sigemptyset
(
&
sa
.
sa_mask
);
sa
.
sa_handler
=
SignalCallback
;
x_sigaction
(
signo
,
sa
);
#endif
}
bool
SignalMonitor
::
OnSocketReady
(
unsigned
)
{
#ifdef USE_SIGNALFD
int
signo
;
while
((
signo
=
fd
.
Read
())
>=
0
)
{
assert
(
unsigned
(
signo
)
<
MAX_SIGNAL
);
assert
(
signal_handlers
[
signo
]
!=
nullptr
);
signal_handlers
[
signo
]();
}
#else
fd
.
Read
();
for
(
unsigned
i
=
0
;
i
<
MAX_SIGNAL
;
++
i
)
if
(
signal_pending
[
i
].
exchange
(
false
))
signal_handlers
[
i
]();
#endif
return
true
;
}
...
...
src/system/SignalFD.cxx
0 → 100644
View file @
4223657a
/*
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#ifdef USE_SIGNALFD
#include "SignalFD.hxx"
#include "fd_util.h"
#include "FatalError.hxx"
#include <assert.h>
#include <unistd.h>
#include <sys/signalfd.h>
void
SignalFD
::
Create
(
const
sigset_t
&
mask
)
{
fd
=
::
signalfd
(
fd
,
&
mask
,
SFD_NONBLOCK
|
SFD_CLOEXEC
);
if
(
fd
<
0
)
FatalSystemError
(
"signalfd() failed"
);
}
void
SignalFD
::
Close
()
{
if
(
fd
>=
0
)
{
::
close
(
fd
);
fd
=
-
1
;
}
}
int
SignalFD
::
Read
()
{
assert
(
fd
>=
0
);
signalfd_siginfo
info
;
return
read
(
fd
,
&
info
,
sizeof
(
info
))
>
0
?
info
.
ssi_signo
:
-
1
;
}
#endif
/* USE_SIGNALFD */
src/system/SignalFD.hxx
0 → 100644
View file @
4223657a
/*
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPD_SIGNAL_FD_HXX
#define MPD_SIGNAL_FD_HXX
#include "check.h"
#include <signal.h>
/**
* A class that wraps signalfd().
*/
class
SignalFD
{
int
fd
;
public
:
SignalFD
()
:
fd
(
-
1
)
{}
~
SignalFD
()
{
Close
();
}
SignalFD
(
const
SignalFD
&
other
)
=
delete
;
SignalFD
&
operator
=
(
const
SignalFD
&
other
)
=
delete
;
/**
* Create the signalfd or update its mask.
*
* All errors are fatal.
*/
void
Create
(
const
sigset_t
&
mask
);
void
Close
();
int
Get
()
const
{
return
fd
;
}
/**
* Read the next signal from the file descriptor. Returns the
* signal number on success or -1 if there are no more
* signals.
*/
int
Read
();
};
#endif
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