[amarok] src: Prevent hang in testmetamultitrack.
Matěj Laitl
matej at laitl.cz
Thu Jul 12 11:13:46 UTC 2012
On 11. 7. 2012 Ralf Engels wrote:
> Git commit 115cb80f9bd94b23640ca9245c97d6c8e25d2c97 by Ralf Engels.
> Committed on 11/07/2012 at 16:25.
> Pushed by rengels into branch 'master'.
>
> Prevent hang in testmetamultitrack.
>
> The class variable mutex had problems in the destructor.
> The function static mutex should not have the problem and I also
> can't see problems with initialization.
This is wrong. C++98 standard doesn't guarantee that initialization of
function-static variables happens in a thread-safe way [1] (C++11 does [2], so
does gcc even in C++98 [3]) Initialization of static _class_ variables doesn't
suffer from this problem.
This can lead to nasty things like initializing the mutex from 2 threads
simultaneously which will probably lead to incorrect operation of it, e.g. you
effectively circumvent the purpose of the mutex.
I introduced the class mutex in commit 8db5599d in order to fix bug 300659.
This change must be reverted, else it will reintroduce bug 300659 with non-gcc
compilers or with -fno-threadsafe-statics.
Because I'm the author of the original change, I'll take responsibility to fix
the test that is broken by it.
[1] http://blogs.msdn.com/b/oldnewthing/archive/2004/03/08/85901.aspx
[2] http://stackoverflow.com/questions/8102125
[3] http://stackoverflow.com/questions/1270927
Regards,
Matěj
> M +3 -3 src/EngineController.cpp
> M +0 -2 src/EngineController.h
>
> http://commits.kde.org/amarok/115cb80f9bd94b23640ca9245c97d6c8e25d2c97
>
> diff --git a/src/EngineController.cpp b/src/EngineController.cpp
> index ed55687..736fa12 100644
> --- a/src/EngineController.cpp
> +++ b/src/EngineController.cpp
> @@ -58,8 +58,6 @@ namespace The {
> EngineController* engineController() { return
> EngineController::instance(); } }
>
> -QMutex EngineController::s_supportedMimeTypesMutex;
> -
> EngineController*
> EngineController::instance()
> {
> @@ -264,13 +262,15 @@ EngineController::supportedMimeTypes() //static
> {
> //NOTE this function must be thread-safe
>
> + // mutex to protect the mimetable and the mimeTableAlreadyFilled status
> + static QMutex supportedMimeTypesMutex;
> // Filter the available mime types to only include audio and video, as
> amarok does not intend to play photos static QStringList mimeTable;
> // theoretically not needed, but static initialization of mimeTable may
> have threading // issues, so rather use boolean flag for it:
> static bool mimeTableAlreadyFilled = false;
>
> - QMutexLocker locker( &s_supportedMimeTypesMutex );
> + QMutexLocker locker( &supportedMimeTypesMutex );
> if( mimeTableAlreadyFilled )
> return mimeTable;
>
> diff --git a/src/EngineController.h b/src/EngineController.h
> index ad2e0c4..3da2f23 100644
> --- a/src/EngineController.h
> +++ b/src/EngineController.h
> @@ -538,8 +538,6 @@ private:
>
> Q_DISABLE_COPY( EngineController )
>
> - static QMutex s_supportedMimeTypesMutex; // guards access to
> supportedMimeTypes()::mimeTable
> -
> QWeakPointer<Phonon::MediaObject> m_media;
> QWeakPointer<Phonon::VolumeFaderEffect> m_preamp;
> QWeakPointer<Phonon::Effect> m_equalizer;
More information about the Amarok-devel
mailing list