Error ModuleCache::GetAndPut(const FileSpec &root_dir_spec, const char *hostname, const ModuleSpec &module_spec, const ModuleDownloader &module_downloader, const SymfileDownloader &symfile_downloader, lldb::ModuleSP &cached_module_sp, bool *did_create_ptr) { const auto module_spec_dir = GetModuleDirectory(root_dir_spec, module_spec.GetUUID()); auto error = MakeDirectory(module_spec_dir); if (error.Fail()) return error; ModuleLock lock(root_dir_spec, module_spec.GetUUID(), error); if (error.Fail()) return Error("Failed to lock module %s: %s", module_spec.GetUUID().GetAsString().c_str(), error.AsCString()); const auto escaped_hostname(GetEscapedHostname(hostname)); // Check local cache for a module. error = Get(root_dir_spec, escaped_hostname.c_str(), module_spec, cached_module_sp, did_create_ptr); if (error.Success()) return error; const auto tmp_download_file_spec = JoinPath(module_spec_dir, kTempFileName); error = module_downloader(module_spec, tmp_download_file_spec); llvm::FileRemover tmp_file_remover(tmp_download_file_spec.GetPath().c_str()); if (error.Fail()) return Error("Failed to download module: %s", error.AsCString()); // Put downloaded file into local module cache. error = Put(root_dir_spec, escaped_hostname.c_str(), module_spec, tmp_download_file_spec, module_spec.GetFileSpec()); if (error.Fail()) return Error("Failed to put module into cache: %s", error.AsCString()); tmp_file_remover.releaseFile(); error = Get(root_dir_spec, escaped_hostname.c_str(), module_spec, cached_module_sp, did_create_ptr); if (error.Fail()) return error; // Fetching a symbol file for the module const auto tmp_download_sym_file_spec = JoinPath(module_spec_dir, kTempSymFileName); error = symfile_downloader(cached_module_sp, tmp_download_sym_file_spec); llvm::FileRemover tmp_symfile_remover( tmp_download_sym_file_spec.GetPath().c_str()); if (error.Fail()) // Failed to download a symfile but fetching the module was successful. The // module might // contain the necessary symbols and the debugging is also possible without // a symfile. return Error(); error = Put(root_dir_spec, escaped_hostname.c_str(), module_spec, tmp_download_sym_file_spec, GetSymbolFileSpec(module_spec.GetFileSpec())); if (error.Fail()) return Error("Failed to put symbol file into cache: %s", error.AsCString()); tmp_symfile_remover.releaseFile(); FileSpec symfile_spec = GetSymbolFileSpec(cached_module_sp->GetFileSpec()); cached_module_sp->SetSymbolFileFileSpec(symfile_spec); return Error(); }
Error ModuleCache::GetAndPut (const FileSpec &root_dir_spec, const char *hostname, const ModuleSpec &module_spec, const ModuleDownloader &module_downloader, const SymfileDownloader &symfile_downloader, lldb::ModuleSP &cached_module_sp, bool *did_create_ptr) { const auto module_spec_dir = GetModuleDirectory (root_dir_spec, module_spec.GetUUID ()); auto error = MakeDirectory (module_spec_dir); if (error.Fail ()) return error; // Open lock file. const auto lock_file_spec = JoinPath (module_spec_dir, kLockFileName); File lock_file (lock_file_spec, File::eOpenOptionWrite | File::eOpenOptionCanCreate | File::eOpenOptionCloseOnExec); if (!lock_file) { error.SetErrorToErrno (); return Error("Failed to open lock file %s: %s", lock_file_spec.GetPath ().c_str (), error.AsCString ()); } LockFile lock (lock_file.GetDescriptor ()); error = lock.WriteLock (0, 1); if (error.Fail ()) return Error("Failed to lock file %s:%s", lock_file_spec.GetPath ().c_str (), error.AsCString ()); // Check local cache for a module. error = Get (root_dir_spec, hostname, module_spec, cached_module_sp, did_create_ptr); if (error.Success ()) return error; const auto tmp_download_file_spec = JoinPath (module_spec_dir, kTempFileName); error = module_downloader (module_spec, tmp_download_file_spec); llvm::FileRemover tmp_file_remover (tmp_download_file_spec.GetPath ().c_str ()); if (error.Fail ()) return Error("Failed to download module: %s", error.AsCString ()); // Put downloaded file into local module cache. error = Put (root_dir_spec, hostname, module_spec, tmp_download_file_spec, module_spec.GetFileSpec ()); if (error.Fail ()) return Error ("Failed to put module into cache: %s", error.AsCString ()); tmp_file_remover.releaseFile (); error = Get (root_dir_spec, hostname, module_spec, cached_module_sp, did_create_ptr); if (error.Fail ()) return error; // Fetching a symbol file for the module const auto tmp_download_sym_file_spec = JoinPath (module_spec_dir, kTempSymFileName); error = symfile_downloader (cached_module_sp, tmp_download_sym_file_spec); llvm::FileRemover tmp_symfile_remover (tmp_download_sym_file_spec.GetPath ().c_str ()); if (error.Fail ()) // Failed to download a symfile but fetching the module was successful. The module might // contain the neccessary symbols and the debugging is also possible without a symfile. return Error (); FileSpec symfile_spec = GetSymbolFileSpec (cached_module_sp->GetFileSpec ()); error = Put (root_dir_spec, hostname, module_spec, tmp_download_sym_file_spec, symfile_spec); if (error.Fail ()) return Error ("Failed to put symbol file into cache: %s", error.AsCString ()); tmp_symfile_remover.releaseFile(); cached_module_sp->SetSymbolFileFileSpec (symfile_spec); return Error (); }