From 3a4e2523ddd7c86954c4f0944cf929447d6bf78c Mon Sep 17 00:00:00 2001 From: Deluan Date: Sat, 5 Sep 2020 19:49:28 -0400 Subject: [PATCH] Fix possible concurrency issue --- scanner/metadata/taglib/audiotags.cpp | 2 +- scanner/metadata/taglib/audiotags.go | 55 +++++++++++++-------------- scanner/metadata/taglib/audiotags.h | 4 +- 3 files changed, 30 insertions(+), 31 deletions(-) diff --git a/scanner/metadata/taglib/audiotags.cpp b/scanner/metadata/taglib/audiotags.cpp index 372f2f3da..b0a56d407 100644 --- a/scanner/metadata/taglib/audiotags.cpp +++ b/scanner/metadata/taglib/audiotags.cpp @@ -59,7 +59,7 @@ void audiotags_file_close(TagLib_File *file) delete reinterpret_cast(file); } -void audiotags_file_properties(const TagLib_File *file, int id) +void audiotags_file_properties(const TagLib_File *file, unsigned long id) { const TagLib::File *f = reinterpret_cast(file); TagLib::PropertyMap tags = f->properties(); diff --git a/scanner/metadata/taglib/audiotags.go b/scanner/metadata/taglib/audiotags.go index f6828ee9e..48cc6d18f 100644 --- a/scanner/metadata/taglib/audiotags.go +++ b/scanner/metadata/taglib/audiotags.go @@ -30,6 +30,7 @@ package taglib import "C" import ( "strings" + "sync" "unsafe" ) @@ -60,35 +61,14 @@ func Read(filename string) (map[string]string, *AudioProperties, error) { return f.ReadTags(), f.ReadAudioProperties(), nil } -func ReadTags(filename string) (map[string]string, error) { - f, err := Open(filename) - if err != nil { - return nil, err - } - defer f.Close() - return f.ReadTags(), nil -} - -func ReadAudioProperties(filename string) (*AudioProperties, error) { - f, err := Open(filename) - if err != nil { - return nil, err - } - defer f.Close() - return f.ReadAudioProperties(), nil -} - func (f *File) Close() { C.audiotags_file_close((*C.TagLib_File)(f)) } func (f *File) ReadTags() map[string]string { - id := mapsNextId - mapsNextId++ - m := make(map[string]string) - maps[id] = m - C.audiotags_file_properties((*C.TagLib_File)(f), C.int(id)) - delete(maps, id) + id, m := newMap() + defer deleteMap(id) + C.audiotags_file_properties((*C.TagLib_File)(f), C.ulong(id)) return m } @@ -105,12 +85,31 @@ func (f *File) ReadAudioProperties() *AudioProperties { return &p } -var maps = make(map[int]map[string]string) -var mapsNextId = 0 +var lock sync.RWMutex +var maps = make(map[uint32]map[string]string) +var mapsNextId uint32 + +func newMap() (id uint32, m map[string]string) { + lock.Lock() + defer lock.Unlock() + id = mapsNextId + mapsNextId++ + m = make(map[string]string) + maps[id] = m + return +} + +func deleteMap(id uint32) { + lock.Lock() + defer lock.Unlock() + delete(maps, id) +} //export go_map_put -func go_map_put(id C.int, key *C.char, val *C.char) { - m := maps[int(id)] +func go_map_put(id C.ulong, key *C.char, val *C.char) { + lock.RLock() + defer lock.RUnlock() + m := maps[uint32(id)] k := strings.ToLower(C.GoString(key)) v := C.GoString(val) m[k] = v diff --git a/scanner/metadata/taglib/audiotags.h b/scanner/metadata/taglib/audiotags.h index d38b06b7f..5172b5686 100644 --- a/scanner/metadata/taglib/audiotags.h +++ b/scanner/metadata/taglib/audiotags.h @@ -31,12 +31,12 @@ extern "C" { typedef struct { int dummy; } TagLib_File; typedef struct { int dummy; } TagLib_AudioProperties; -extern void go_map_put(int id, char *key, char *val); +extern void go_map_put(unsigned long id, char *key, char *val); void audiotags_free(void* pointer); TagLib_File *audiotags_file_new(const char *filename); void audiotags_file_close(TagLib_File *file); -void audiotags_file_properties(const TagLib_File *file, int id); +void audiotags_file_properties(const TagLib_File *file, unsigned long id); const TagLib_AudioProperties *audiotags_file_audioproperties(const TagLib_File *file); int audiotags_audioproperties_length(const TagLib_AudioProperties *audioProperties);