Compare commits

...

4 Commits

Author SHA1 Message Date
Max Kellermann
8bfdb4ed0c release v0.18.11 2014-05-12 18:20:26 +02:00
Max Kellermann
70bd35abe2 decoder/OggUtil: allow skipping up to 32 kB after seek
Fixes missing song length on high-latency Opus files.

According to tests with 320 kbit/s opus files with 60ms packets, we
need to skip up to 29 kB.
2014-04-29 11:56:05 +02:00
Max Kellermann
0efb67b51e DeferredMonitor: fix race condition when using GLib event loop
Turns out the lock-free code using atomics was not thread-safe.  The
given callback could be invoked by GLib before the source_id attribute
was assigned.  This commit changes the DeferredMonitor class to use a
Mutex to block the event loop until source_id is assigned.  This bug
does not exist in the 0.19 branch because it does not use the GLib
main loop anymore.
2014-04-26 22:11:23 +02:00
Max Kellermann
54ebf2a699 configure.ac: prepare for 0.18.11 2014-04-26 22:08:08 +02:00
5 changed files with 29 additions and 13 deletions

5
NEWS

@@ -1,3 +1,8 @@
ver 0.18.11 (2014/05/12)
* decoder
- opus: fix missing song length on high-latency files
* fix race condition when using GLib event loop (non-Linux)
ver 0.18.10 (2014/04/10)
* decoder
- ffmpeg: fix seeking bug

@@ -1,6 +1,6 @@
AC_PREREQ(2.60)
AC_INIT(mpd, 0.18.10, mpd-devel@musicpd.org)
AC_INIT(mpd, 0.18.11, mpd-devel@musicpd.org)
VERSION_MAJOR=0
VERSION_MINOR=18

@@ -81,7 +81,7 @@ bool
OggExpectPageSeek(ogg_sync_state &oy, ogg_page &page,
Decoder *decoder, InputStream &input_stream)
{
size_t remaining_skipped = 16384;
size_t remaining_skipped = 32768;
while (true) {
int r = ogg_sync_pageseek(&oy, &page);

@@ -27,9 +27,11 @@ DeferredMonitor::Cancel()
#ifdef USE_EPOLL
pending = false;
#else
const auto id = source_id.exchange(0);
if (id != 0)
g_source_remove(id);
const ScopeLock protect(mutex);
if (source_id != 0) {
g_source_remove(source_id);
source_id = 0;
}
#endif
}
@@ -40,10 +42,9 @@ DeferredMonitor::Schedule()
if (!pending.exchange(true))
fd.Write();
#else
const unsigned id = loop.AddIdle(Callback, this);
const auto old_id = source_id.exchange(id);
if (old_id != 0)
g_source_remove(old_id);
const ScopeLock protect(mutex);
if (source_id == 0)
source_id = loop.AddIdle(Callback, this);
#endif
}
@@ -65,9 +66,16 @@ DeferredMonitor::OnSocketReady(unsigned)
void
DeferredMonitor::Run()
{
const auto id = source_id.exchange(0);
if (id != 0)
RunDeferred();
{
const ScopeLock protect(mutex);
if (source_id == 0)
/* cancelled */
return;
source_id = 0;
}
RunDeferred();
}
gboolean

@@ -27,6 +27,7 @@
#include "SocketMonitor.hxx"
#include "WakeFD.hxx"
#else
#include "thread/Mutex.hxx"
#include <glib.h>
#endif
@@ -48,7 +49,9 @@ class DeferredMonitor
#else
EventLoop &loop;
std::atomic<guint> source_id;
Mutex mutex;
guint source_id;
#endif
public: