| 78 | } |
| 79 | |
| 80 | static StringBox resolveSourceMapFilePath(const StringBox& modulePath) { |
| 81 | return modulePath.append(".map.json"); |
| 82 | } |
| 83 | |
| 84 | static int32_t parseApiVersion(const BytesView& bytes, ILogger& logger) { |
| 85 | TextParser parser(std::string_view(reinterpret_cast<const char*>(bytes.data()), bytes.size())); |
| 86 | |
| 87 | parser.tryParseWhitespaces(); |
| 88 | auto version = parser.parseUInt(); |
| 89 | parser.tryParseWhitespaces(); |
| 90 | |
| 91 | if (!version.has_value() || !parser.isAtEnd() || version.value() > std::numeric_limits<int32_t>::max()) { |
| 92 | VALDI_WARN(logger, "Invalid valdi_api_version resource content. Expected a non-negative integer."); |
| 93 | return 0; |
| 94 | } |
| 95 | |
| 96 | return static_cast<int32_t>(version.value()); |
| 97 | } |
| 98 | |
| 99 | int32_t ResourceManager::getApiVersion() { |
| 100 | { |
| 101 | std::lock_guard<Mutex> guard(_mutex); |
| 102 | if (_apiVersion.has_value()) { |
| 103 | return _apiVersion.value(); |
| 104 | } |
| 105 | } |
| 106 | |
| 107 | // Loaded outside _mutex: the resource loader crosses into the platform and on the first call can |
| 108 | // initialize the Dynamic Delivery archive, which waits on the content manager. Holding _mutex |
| 109 | // across it blocked the main thread in preloadForComponentPath for 10s+ (MUSIC-13144, |
| 110 | // SHARING-35215). Concurrent first callers may both reach the loader; the Dynamic Delivery |
| 111 | // archive init behind it is a std::call_once, so the heavy work still runs once. |
| 112 | auto content = _resourceLoader->loadModuleContent(STRING_LITERAL("valdi_api_version")); |
| 113 | int32_t apiVersion = content ? parseApiVersion(content.value(), _logger) : 0; |
| 114 | |
| 115 | std::lock_guard<Mutex> guard(_mutex); |
| 116 | if (!_apiVersion.has_value()) { |
| 117 | _apiVersion = apiVersion; |
| 118 | } |
| 119 | return _apiVersion.value(); |
| 120 | } |
| 121 | |
| 122 | Result<Ref<ValdiModuleArchive>> ResourceManager::getArchiveForModule(const StringBox& modulePath, |
| 123 | bool useMmap, |
| 124 | const Path& mmapCacheDir, |
| 125 | const Ref<Metrics>& metrics) { |
| 126 | auto bundleFilePath = resolveModuleArchiveFilePath(modulePath); |
| 127 | |
| 128 | auto bundleContent = _resourceLoader->loadModuleContent(bundleFilePath); |
| 129 | if (!bundleContent) { |
| 130 | // Fallback on .valdimodule for backward compatibility |
| 131 | auto bundleContentAlternative = _resourceLoader->loadModuleContent(modulePath.append(".valdimodule")); |
| 132 | if (!bundleContentAlternative) { |
| 133 | return bundleContent.error().rethrow(STRING_FORMAT("Unable to load module '{}'", modulePath)); |
| 134 | } else { |
| 135 | bundleContent = std::move(bundleContentAlternative); |
| 136 | } |
| 137 | } |
nothing calls this directly
no test coverage detected