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
67a958a3
Commit
67a958a3
authored
Feb 09, 2017
by
Max Kellermann
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'v0.20.x'
parents
38507165
7372c931
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
83 additions
and
18 deletions
+83
-18
NEWS
NEWS
+4
-0
configure.ac
configure.ac
+1
-1
Call.cxx
src/event/Call.cxx
+1
-1
Loop.cxx
src/event/Loop.cxx
+2
-1
Loop.hxx
src/event/Loop.hxx
+6
-2
MultiSocketMonitor.cxx
src/event/MultiSocketMonitor.cxx
+9
-3
MultiSocketMonitor.hxx
src/event/MultiSocketMonitor.hxx
+50
-3
AlsaInputPlugin.cxx
src/input/plugins/AlsaInputPlugin.cxx
+2
-6
AlsaMixerPlugin.cxx
src/mixer/plugins/AlsaMixerPlugin.cxx
+8
-1
No files found.
NEWS
View file @
67a958a3
...
...
@@ -6,6 +6,10 @@ ver 0.21 (not yet released)
ver 0.20.5 (not yet released)
* tags
- id3: fix memory leak on corrupt ID3 tags
* decoder
- sidplay: don't require libsidutils when building with libsidplayfp
* mixer
- alsa: fix crash bug
ver 0.20.4 (2017/02/01)
* input
...
...
configure.ac
View file @
67a958a3
...
...
@@ -988,7 +988,7 @@ AM_CONDITIONAL(ENABLE_VORBIS_DECODER, test x$enable_vorbis = xyes || test x$enab
dnl --------------------------------- sidplay ---------------------------------
if test x$enable_sidplay != xno; then
dnl Check for libsidplayfp first
PKG_CHECK_MODULES([SIDPLAY], [libsidplayfp
libsidutils
],
PKG_CHECK_MODULES([SIDPLAY], [libsidplayfp],
[found_sidplayfp=yes],
[found_sidplayfp=no])
found_sidplay=$found_sidplayfp
...
...
src/event/Call.cxx
View file @
67a958a3
...
...
@@ -79,7 +79,7 @@ private:
void
BlockingCall
(
EventLoop
&
loop
,
std
::
function
<
void
()
>
&&
f
)
{
if
(
loop
.
IsInside
())
{
if
(
loop
.
IsInside
OrNull
())
{
/* we're already inside the loop - we can simply call
the function */
f
();
...
...
src/event/Loop.cxx
View file @
67a958a3
...
...
@@ -222,8 +222,9 @@ EventLoop::Run()
#ifndef NDEBUG
assert
(
busy
);
assert
(
thread
.
IsInside
());
thread
=
ThreadId
::
Null
();
#endif
thread
=
ThreadId
::
Null
();
}
void
...
...
src/event/Loop.hxx
View file @
67a958a3
...
...
@@ -212,12 +212,16 @@ public:
}
#endif
#ifndef NDEBUG
/**
* Like IsInside(), but also returns true if the thread has
* already ended (or was not started yet). This is useful for
* code which may run during startup or shutdown, when events
* are not yet/anymore handled.
*/
gcc_pure
bool
IsInsideOrNull
()
const
{
return
thread
.
IsNull
()
||
thread
.
IsInside
();
}
#endif
};
#endif
/* MAIN_NOTIFY_H */
src/event/MultiSocketMonitor.cxx
View file @
67a958a3
...
...
@@ -28,12 +28,18 @@
#endif
MultiSocketMonitor
::
MultiSocketMonitor
(
EventLoop
&
_loop
)
:
IdleMonitor
(
_loop
),
TimeoutMonitor
(
_loop
)
,
ready
(
false
)
{
:
IdleMonitor
(
_loop
),
TimeoutMonitor
(
_loop
)
{
}
MultiSocketMonitor
::~
MultiSocketMonitor
()
void
MultiSocketMonitor
::
Reset
()
{
// TODO
assert
(
GetEventLoop
().
IsInsideOrNull
());
fds
.
clear
();
IdleMonitor
::
Cancel
();
TimeoutMonitor
::
Cancel
();
ready
=
refresh
=
false
;
}
void
...
...
src/event/MultiSocketMonitor.hxx
View file @
67a958a3
...
...
@@ -96,7 +96,19 @@ class MultiSocketMonitor : IdleMonitor, TimeoutMonitor
friend
class
SingleFD
;
bool
ready
,
refresh
;
/**
* DispatchSockets() should be called.
*/
bool
ready
=
false
;
/**
* PrepareSockets() should be called.
*
* Note that this doesn't need to be initialized by the
* constructor; this class is activated with the first
* InvalidateSockets() call, which initializes this flag.
*/
bool
refresh
;
std
::
forward_list
<
SingleFD
>
fds
;
...
...
@@ -107,11 +119,26 @@ public:
static
constexpr
unsigned
HANGUP
=
SocketMonitor
::
HANGUP
;
MultiSocketMonitor
(
EventLoop
&
_loop
);
~
MultiSocketMonitor
();
using
IdleMonitor
::
GetEventLoop
;
public
:
/**
* Clear the socket list and disable all #EventLoop
* registrations. Run this in the #EventLoop thread before
* destroying this object.
*
* Later, this object can be reused and reactivated by calling
* InvalidateSockets().
*
* Note that this class doesn't have a destructor which calls
* this method, because this would be racy and thus pointless:
* at the time ~MultiSocketMonitor() is called, our virtual
* methods have been morphed to be pure again, and in the
* meantime the #EventLoop thread could invoke those pure
* methods.
*/
void
Reset
();
/**
* Invalidate the socket list. A call to PrepareSockets() is
* scheduled which will then update the list.
...
...
@@ -121,12 +148,19 @@ public:
IdleMonitor
::
Schedule
();
}
/**
* Add one socket to the list of monitored sockets.
*
* May only be called from PrepareSockets().
*/
void
AddSocket
(
int
fd
,
unsigned
events
)
{
fds
.
emplace_front
(
*
this
,
fd
,
events
);
}
/**
* Remove all sockets.
*
* May only be called from PrepareSockets().
*/
void
ClearSocketList
();
...
...
@@ -135,6 +169,8 @@ public:
* each one; its return value is the events bit mask. A
* return value of 0 means the socket will be removed from the
* list.
*
* May only be called from PrepareSockets().
*/
template
<
typename
E
>
void
UpdateSocketList
(
E
&&
e
)
{
...
...
@@ -157,15 +193,26 @@ public:
/**
* Replace the socket list with the given file descriptors.
* The given pollfd array will be modified by this method.
*
* May only be called from PrepareSockets().
*/
void
ReplaceSocketList
(
pollfd
*
pfds
,
unsigned
n
);
#endif
protected
:
/**
* Override this method and update the socket registrations.
* To do that, call AddSocket(), ClearSocketList(),
* UpdateSocketList() and ReplaceSocketList().
*
* @return timeout or a negative value for no timeout
*/
virtual
std
::
chrono
::
steady_clock
::
duration
PrepareSockets
()
=
0
;
/**
* At least one socket is ready or the timeout has expired.
* This method should be used to perform I/O.
*/
virtual
void
DispatchSockets
()
=
0
;
private
:
...
...
src/input/plugins/AlsaInputPlugin.cxx
View file @
67a958a3
...
...
@@ -99,12 +99,8 @@ public:
}
~
AlsaInputStream
()
{
/* ClearSocketList must be called from within the
IOThread; if we don't do it manually here, the
~MultiSocketMonitor() will do it in the current
thread */
BlockingCall
(
MultiSocketMonitor
::
GetEventLoop
(),
[
this
](){
ClearSocketLis
t
();
MultiSocketMonitor
::
Rese
t
();
});
snd_pcm_close
(
capture_handle
);
...
...
@@ -182,7 +178,7 @@ AlsaInputStream::PrepareSockets()
}
int
count
=
snd_pcm_poll_descriptors_count
(
capture_handle
);
if
(
count
<
0
)
{
if
(
count
<
=
0
)
{
ClearSocketList
();
return
std
::
chrono
::
steady_clock
::
duration
(
-
1
);
}
...
...
src/mixer/plugins/AlsaMixerPlugin.cxx
View file @
67a958a3
...
...
@@ -23,6 +23,7 @@
#include "output/OutputAPI.hxx"
#include "event/MultiSocketMonitor.hxx"
#include "event/DeferredMonitor.hxx"
#include "event/Call.hxx"
#include "util/ASCII.hxx"
#include "util/ReusableArray.hxx"
#include "util/Domain.hxx"
...
...
@@ -53,6 +54,12 @@ public:
DeferredMonitor
::
Schedule
();
}
~
AlsaMixerMonitor
()
{
BlockingCall
(
MultiSocketMonitor
::
GetEventLoop
(),
[
this
](){
MultiSocketMonitor
::
Reset
();
});
}
private
:
virtual
void
RunDeferred
()
override
{
InvalidateSockets
();
...
...
@@ -102,7 +109,7 @@ AlsaMixerMonitor::PrepareSockets()
}
int
count
=
snd_mixer_poll_descriptors_count
(
mixer
);
if
(
count
<
0
)
if
(
count
<
=
0
)
count
=
0
;
struct
pollfd
*
pfds
=
pfd_buffer
.
Get
(
count
);
...
...
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