diff --git a/change/react-native-windows-2019-07-25-19-36-19-users-stecrain-fixBrokeredFileAccess.json b/change/react-native-windows-2019-07-25-19-36-19-users-stecrain-fixBrokeredFileAccess.json new file mode 100644 index 00000000000..2d3ae0be01b --- /dev/null +++ b/change/react-native-windows-2019-07-25-19-36-19-users-stecrain-fixBrokeredFileAccess.json @@ -0,0 +1,8 @@ +{ + "comment": "use win32 file api to avoid runtime broker slowing us down", + "type": "prerelease", + "packageName": "react-native-windows", + "email": "stecrain@microsoft.com", + "commit": "6a9d6e7e6112f6b963b9a5c0079defbad4272f06", + "date": "2019-07-26T02:36:19.282Z" +} \ No newline at end of file diff --git a/vnext/ReactUWP/Utils/UwpPreparedScriptStore.cpp b/vnext/ReactUWP/Utils/UwpPreparedScriptStore.cpp index 7f3930d36a4..61c96eb17cb 100644 --- a/vnext/ReactUWP/Utils/UwpPreparedScriptStore.cpp +++ b/vnext/ReactUWP/Utils/UwpPreparedScriptStore.cpp @@ -3,6 +3,7 @@ #include #include #include "Utils/UwpPreparedScriptStore.h" +#include "Utils/UwpScriptStore.h" #include "jsi/jsi.h" #include "unicode.h" @@ -93,9 +94,9 @@ winrt::StorageFile UwpPreparedScriptStore::TryGetByteCodeFileSync( try { if (m_byteCodeFileAsync != nullptr) { auto file = m_byteCodeFileAsync.get(); - auto fileprops = file.GetBasicPropertiesAsync().get(); - facebook::jsi::ScriptVersion_t byteCodeVersion = - fileprops.DateModified().time_since_epoch().count(); + auto byteCodeVersion = + UwpScriptStore::GetFileVersion(file.Path().c_str()); + if (byteCodeVersion >= scriptSignature.version) { return file; } @@ -113,9 +114,8 @@ winrt::StorageFile UwpPreparedScriptStore::TryGetByteCodeFileSync( .LocalCacheFolder() .GetFileAsync(fileName) .get(); - auto fileprops = file.GetBasicPropertiesAsync().get(); - facebook::jsi::ScriptVersion_t byteCodeVersion = - fileprops.DateModified().time_since_epoch().count(); + + auto byteCodeVersion = UwpScriptStore::GetFileVersion(file.Path().c_str()); return byteCodeVersion > scriptSignature.version ? file : nullptr; } diff --git a/vnext/ReactUWP/Utils/UwpScriptStore.cpp b/vnext/ReactUWP/Utils/UwpScriptStore.cpp index 19bea02784a..65bcb8bf105 100644 --- a/vnext/ReactUWP/Utils/UwpScriptStore.cpp +++ b/vnext/ReactUWP/Utils/UwpScriptStore.cpp @@ -17,6 +17,22 @@ namespace uwp { UwpScriptStore::UwpScriptStore() {} +/* static */ facebook::jsi::ScriptVersion_t UwpScriptStore::GetFileVersion( + const std::wstring &filePath) { + // append prefix to allow long file paths. + auto longFilePath = L"\\\\?\\" + filePath; + WIN32_FILE_ATTRIBUTE_DATA fileData; + if (GetFileAttributesEx( + longFilePath.c_str(), GetFileExInfoStandard, &fileData)) { + return ((facebook::jsi::ScriptVersion_t) + fileData.ftLastWriteTime.dwHighDateTime + << 32) | + fileData.ftLastWriteTime.dwLowDateTime; + } + + return 0; +} + facebook::jsi::VersionedBuffer UwpScriptStore::getVersionedScript( const std::string &url) noexcept { facebook::jsi::VersionedBuffer versionedBuffer_; @@ -29,27 +45,22 @@ facebook::jsi::VersionedBuffer UwpScriptStore::getVersionedScript( // Script version = timestamp of bundle file last created facebook::jsi::ScriptVersion_t UwpScriptStore::getScriptVersion( const std::string &url) noexcept { - const std::string bundleUrl = "ms-appx:///Bundle/" + url + ".bundle"; - const winrt::DateTime bundleModifiedTime = - getBundleModifiedDate(bundleUrl).get(); - const std::uint64_t timestamp = bundleModifiedTime.time_since_epoch().count(); - return timestamp; + auto version = getScriptVersionAsync(url).get(); + + return version; } -std::future UwpScriptStore::getBundleModifiedDate( - const std::string &bundleUri) { - winrt::hstring str(facebook::react::unicode::utf8ToUtf16(bundleUri)); - winrt::Windows::Foundation::Uri uri(str); - - try { - auto file = - co_await winrt::StorageFile::GetFileFromApplicationUriAsync(uri); - auto props = file.GetBasicPropertiesAsync().get(); - return props.DateModified(); - } catch (winrt::hresult_error const &ex) { - winrt::DateTime date; - return date; - } +std::future +UwpScriptStore::getScriptVersionAsync(const std::string &bundleUri) { + co_await winrt::resume_background(); + + const winrt::hstring fileUrl(facebook::react::unicode::utf8ToUtf16( + "ms-appx:///Bundle/" + bundleUri + ".bundle")); + + auto file = co_await winrt::StorageFile::GetFileFromApplicationUriAsync( + winrt::Windows::Foundation::Uri{fileUrl}); + + co_return GetFileVersion(file.Path().c_str()); } } // namespace uwp diff --git a/vnext/ReactUWP/Utils/UwpScriptStore.h b/vnext/ReactUWP/Utils/UwpScriptStore.h index 6a66bc8d07e..4b66305e1bc 100644 --- a/vnext/ReactUWP/Utils/UwpScriptStore.h +++ b/vnext/ReactUWP/Utils/UwpScriptStore.h @@ -15,9 +15,13 @@ class UwpScriptStore : public facebook::jsi::ScriptStore { UwpScriptStore(const UwpScriptStore &) = delete; void operator=(const UwpScriptStore &) = delete; + public: + static facebook::jsi::ScriptVersion_t GetFileVersion( + const std::wstring &filePath); + private: - std::future getBundleModifiedDate( - const std::string &bundlePath); + std::future getScriptVersionAsync( + const std::string &bundleUri); }; } // namespace uwp