[vlc-devel] [PATCH] Workaround #3958
Rafaël Carré
rafael.carre at gmail.com
Sun Oct 24 16:20:44 CEST 2010
Taglib doesn't seem to be thread safe
---
modules/meta_engine/taglib.cpp | 78 ++++++++++++++++++++++++++++++++-------
1 files changed, 64 insertions(+), 14 deletions(-)
diff --git a/modules/meta_engine/taglib.cpp b/modules/meta_engine/taglib.cpp
index 33866d0..b1f67c2 100644
--- a/modules/meta_engine/taglib.cpp
+++ b/modules/meta_engine/taglib.cpp
@@ -82,6 +82,13 @@
static int ReadMeta ( vlc_object_t * );
static int WriteMeta ( vlc_object_t * );
+static struct
+{
+ bool busy;
+ vlc_mutex_t lock;
+} entrant = { false, VLC_STATIC_MUTEX, };
+
+
vlc_module_begin ()
set_capability( "meta reader", 1000 )
set_callbacks( ReadMeta, NULL )
@@ -366,7 +373,8 @@ static int ReadMeta( vlc_object_t* p_this)
demux_meta_t* p_demux_meta = (demux_meta_t *)p_this;
demux_t* p_demux = p_demux_meta->p_demux;
vlc_meta_t* p_meta;
- FileRef f;
+ Tag* p_tag;
+ int ret = VLC_EGENERIC;
p_demux_meta->p_meta = NULL;
if( strcmp( p_demux->psz_access, "file" ) )
@@ -376,12 +384,24 @@ static int ReadMeta( vlc_object_t* p_this)
if( !psz_path )
return VLC_ENOMEM;
+ vlc_mutex_lock( &entrant.lock );
+ if( entrant.busy )
+ {
+ msg_Err( p_demux_meta, "taglib already active" );
+ vlc_mutex_unlock( &entrant.lock );
+ return VLC_EGENERIC;
+ }
+ entrant.busy = true;
+ vlc_mutex_unlock( &entrant.lock );
+
+ FileRef f;
+
#if defined(WIN32) || defined (UNDER_CE)
wchar_t wpath[MAX_PATH + 1];
if( !MultiByteToWideChar( CP_UTF8, 0, psz_path, -1, wpath, MAX_PATH) )
{
free( psz_path );
- return VLC_EGENERIC;
+ goto end;
}
wpath[MAX_PATH] = L'\0';
f = FileRef( wpath );
@@ -390,7 +410,7 @@ static int ReadMeta( vlc_object_t* p_this)
if( !local_name )
{
free( psz_path );
- return VLC_EGENERIC;
+ goto end;
}
f = FileRef( local_name );
LocaleFree( local_name );
@@ -398,17 +418,20 @@ static int ReadMeta( vlc_object_t* p_this)
free( psz_path );
if( f.isNull() )
- return VLC_EGENERIC;
+ goto end;
if( !f.tag() || f.tag()->isEmpty() )
- return VLC_EGENERIC;
+ goto end;
p_demux_meta->p_meta = p_meta = vlc_meta_New();
if( !p_meta )
- return VLC_ENOMEM;
+ {
+ ret = VLC_ENOMEM;
+ goto end;
+ }
// Read the tags from the file
- Tag* p_tag = f.tag();
+ p_tag = f.tag();
#define SET( tag, meta ) \
if( !p_tag->tag().isNull() && !p_tag->tag().isEmpty() ) \
@@ -489,7 +512,14 @@ static int ReadMeta( vlc_object_t* p_this)
ReadMetaFromAPE( wavpack->APETag(), p_demux, p_demux_meta, p_meta );
}
- return VLC_SUCCESS;
+ ret = VLC_SUCCESS;
+
+end:
+ vlc_mutex_lock( &entrant.lock );
+ entrant.busy = false;
+ vlc_mutex_unlock( &entrant.lock );
+
+ return ret;
}
@@ -587,7 +617,8 @@ static int WriteMeta( vlc_object_t *p_this )
{
meta_export_t *p_export = (meta_export_t *)p_this;
input_item_t *p_item = p_export->p_item;
- FileRef f;
+ Tag *p_tag;
+ int ret = VLC_EGENERIC;
if( !p_item )
{
@@ -595,16 +626,28 @@ static int WriteMeta( vlc_object_t *p_this )
return VLC_EGENERIC;
}
+ vlc_mutex_lock( &entrant.lock );
+ if( entrant.busy )
+ {
+ msg_Err( p_export, "taglib already active" );
+ vlc_mutex_unlock( &entrant.lock );
+ return VLC_EGENERIC;
+ }
+ entrant.busy = true;
+ vlc_mutex_unlock( &entrant.lock );
+
+ FileRef f;
+
#if defined(WIN32) || defined (UNDER_CE)
wchar_t wpath[MAX_PATH + 1];
if( !MultiByteToWideChar( CP_UTF8, 0, p_export->psz_file, -1, wpath, MAX_PATH) )
- return VLC_EGENERIC;
+ goto end;
wpath[MAX_PATH] = L'\0';
f = FileRef( wpath );
#else
const char* local_name = ToLocale( p_export->psz_file );
if( !local_name )
- return VLC_EGENERIC;
+ goto end;
f = FileRef( local_name );
LocaleFree( local_name );
#endif
@@ -613,12 +656,12 @@ static int WriteMeta( vlc_object_t *p_this )
{
msg_Err( p_this, "File %s can't be opened for tag writing",
p_export->psz_file );
- return VLC_EGENERIC;
+ goto end;
}
msg_Dbg( p_this, "Writing metadata for %s", p_export->psz_file );
- Tag *p_tag = f.tag();
+ p_tag = f.tag();
char *psz_meta;
@@ -702,6 +745,13 @@ static int WriteMeta( vlc_object_t *p_this )
// Save the meta data
f.save();
- return VLC_SUCCESS;
+ ret = VLC_SUCCESS;
+
+end:
+ vlc_mutex_lock( &entrant.lock );
+ entrant.busy = false;
+ vlc_mutex_unlock( &entrant.lock );
+
+ return ret;
}
--
1.7.3.2
More information about the vlc-devel
mailing list