diff --git a/taglib/mp4/mp4itemfactory.cpp b/taglib/mp4/mp4itemfactory.cpp index 56aec794..9e591ad3 100644 --- a/taglib/mp4/mp4itemfactory.cpp +++ b/taglib/mp4/mp4itemfactory.cpp @@ -25,6 +25,7 @@ #include "mp4itemfactory.h" +#include #include #include "tbytevector.h" @@ -47,6 +48,8 @@ public: NameHandlerMap handlerTypeForName; Map propertyKeyForName; Map nameForPropertyKey; + mutable std::once_flag handlerMapOnce; + mutable std::once_flag propertyMapsOnce; }; ItemFactory ItemFactory::factory; @@ -239,9 +242,11 @@ std::pair ItemFactory::itemToProperty( String ItemFactory::propertyKeyForName(const ByteVector &name) const { - if(d->propertyKeyForName.isEmpty()) { + std::call_once(d->propertyMapsOnce, [this] { d->propertyKeyForName = namePropertyMap(); - } + for(const auto &[k, t] : std::as_const(d->propertyKeyForName)) + d->nameForPropertyKey[t] = k; + }); String key = d->propertyKeyForName.value(name); if(key.isEmpty() && name.startsWith(freeFormPrefix)) { key = name.mid(std::size(freeFormPrefix) - 1); @@ -251,14 +256,11 @@ String ItemFactory::propertyKeyForName(const ByteVector &name) const ByteVector ItemFactory::nameForPropertyKey(const String &key) const { - if(d->nameForPropertyKey.isEmpty()) { - if(d->propertyKeyForName.isEmpty()) { - d->propertyKeyForName = namePropertyMap(); - } - for(const auto &[k, t] : std::as_const(d->propertyKeyForName)) { + std::call_once(d->propertyMapsOnce, [this] { + d->propertyKeyForName = namePropertyMap(); + for(const auto &[k, t] : std::as_const(d->propertyKeyForName)) d->nameForPropertyKey[t] = k; - } - } + }); ByteVector name = d->nameForPropertyKey.value(key); if(name.isEmpty() && !key.isEmpty()) { const auto &firstChar = key[0]; @@ -317,9 +319,9 @@ ItemFactory::NameHandlerMap ItemFactory::nameHandlerMap() const ItemFactory::ItemHandlerType ItemFactory::handlerTypeForName( const ByteVector &name) const { - if(d->handlerTypeForName.isEmpty()) { + std::call_once(d->handlerMapOnce, [this] { d->handlerTypeForName = nameHandlerMap(); - } + }); auto type = d->handlerTypeForName.value(name, ItemHandlerType::Unknown); if (type == ItemHandlerType::Unknown && name.size() == 4) { type = ItemHandlerType::Text;