delay_lock_the_protocol_scheme_registry.patch 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
  2. From: Andy Locascio <[email protected]>
  3. Date: Tue, 18 Feb 2020 14:35:04 -0800
  4. Subject: content: allow embedder to prevent locking scheme registry
  5. The //content layer requires all schemes to be registered during startup,
  6. because Add*Scheme aren't threadsafe. However, Electron exposes the option to
  7. register additional schemes via JavaScript in the main process before the app
  8. is ready, but after the //content layer has already locked the registry.
  9. This allows embedders to optionally keep the scheme registry unlocked, and it
  10. is their responsibility to ensure that it is not accessed in a way that would
  11. cause potential thread-safety issues.
  12. Previously upstreamed patch: https://chromium-review.googlesource.com/c/chromium/src/+/1637040
  13. This change was lost during upstream refactor in
  14. https://chromium-review.googlesource.com/c/chromium/src/+/1901591, we should try
  15. re-submitting the patch.
  16. diff --git a/content/app/content_main_runner_impl.cc b/content/app/content_main_runner_impl.cc
  17. index 7fe69095589d1f12b12ca2e91cf30f89aaf3d986..57d230c76ae5d28bff0bd2eb4be01880189b20bd 100644
  18. --- a/content/app/content_main_runner_impl.cc
  19. +++ b/content/app/content_main_runner_impl.cc
  20. @@ -738,7 +738,7 @@ int ContentMainRunnerImpl::Initialize(const ContentMainParams& params) {
  21. }
  22. #endif
  23. - RegisterContentSchemes();
  24. + RegisterContentSchemes(delegate_->ShouldLockSchemeRegistry());
  25. ContentClientInitializer::Set(process_type, delegate_);
  26. #if !defined(OS_ANDROID)
  27. diff --git a/content/common/url_schemes.cc b/content/common/url_schemes.cc
  28. index dc37f121130d83e200d73dd1ad566847548ac0fd..63080c1bc486a488841fc5d2081f4d5d4a00bde3 100644
  29. --- a/content/common/url_schemes.cc
  30. +++ b/content/common/url_schemes.cc
  31. @@ -49,7 +49,7 @@ std::vector<std::string>& GetMutableServiceWorkerSchemes() {
  32. } // namespace
  33. -void RegisterContentSchemes() {
  34. +void RegisterContentSchemes(bool should_lock_registry) {
  35. // On Android and in tests, schemes may have been registered already.
  36. if (g_registered_url_schemes)
  37. return;
  38. @@ -106,7 +106,8 @@ void RegisterContentSchemes() {
  39. // threadsafe so must be called when GURL isn't used on any other thread. This
  40. // is really easy to mess up, so we say that all calls to Add*Scheme in Chrome
  41. // must be inside this function.
  42. - url::LockSchemeRegistries();
  43. + if (should_lock_registry)
  44. + url::LockSchemeRegistries();
  45. // Combine the default savable schemes with the additional ones given.
  46. GetMutableSavableSchemes().assign(std::begin(kDefaultSavableSchemes),
  47. diff --git a/content/common/url_schemes.h b/content/common/url_schemes.h
  48. index 3038f9d25798f36811b6398f8cc0e7d83ecc41b0..68189c36c47ef85b345b0ccc40c456f889977bee 100644
  49. --- a/content/common/url_schemes.h
  50. +++ b/content/common/url_schemes.h
  51. @@ -16,7 +16,7 @@ namespace content {
  52. // parsed as "standard" or "referrer" with the src/url/ library, then locks the
  53. // sets of schemes down. The embedder can add additional schemes by
  54. // overriding the ContentClient::AddAdditionalSchemes method.
  55. -CONTENT_EXPORT void RegisterContentSchemes();
  56. +CONTENT_EXPORT void RegisterContentSchemes(bool should_lock_registry = true);
  57. // Re-initializes schemes for tests.
  58. CONTENT_EXPORT void ReRegisterContentSchemesForTests();
  59. diff --git a/content/public/app/content_main_delegate.cc b/content/public/app/content_main_delegate.cc
  60. index 8c71a579ee69d77547698c2135e3b4453c126b97..9b7fd8949b13d97982a100a36d9f73c9947b8853 100644
  61. --- a/content/public/app/content_main_delegate.cc
  62. +++ b/content/public/app/content_main_delegate.cc
  63. @@ -42,6 +42,10 @@ bool ContentMainDelegate::ShouldHandleConsoleControlEvents() {
  64. }
  65. #endif
  66. +bool ContentMainDelegate::ShouldLockSchemeRegistry() {
  67. + return true;
  68. +}
  69. +
  70. bool ContentMainDelegate::ShouldCreateFeatureList() {
  71. return true;
  72. }
  73. diff --git a/content/public/app/content_main_delegate.h b/content/public/app/content_main_delegate.h
  74. index 5e45724edf07ac33c9a423ecb6b6077f19e13b04..84f77390772828554e446d1e6f99198b76e9f835 100644
  75. --- a/content/public/app/content_main_delegate.h
  76. +++ b/content/public/app/content_main_delegate.h
  77. @@ -69,6 +69,20 @@ class CONTENT_EXPORT ContentMainDelegate {
  78. // returning initialization error code. Default behavior is CHECK(false).
  79. virtual int TerminateForFatalInitializationError();
  80. + // Allows the embedder to prevent locking the scheme registry. The scheme
  81. + // registry is the list of URL schemes we recognize, with some additional
  82. + // information about each scheme such as whether it expects a host. The
  83. + // scheme registry is not thread-safe, so by default it is locked before any
  84. + // threads are created to ensure single-threaded access. An embedder can
  85. + // override this to prevent the scheme registry from being locked during
  86. + // startup, but if they do so then they are responsible for making sure that
  87. + // the registry is only accessed in a thread-safe way, and for calling
  88. + // url::LockSchemeRegistries() when initialization is complete. If possible,
  89. + // prefer registering additional schemes through
  90. + // ContentClient::AddAdditionalSchemes over preventing the scheme registry
  91. + // from being locked.
  92. + virtual bool ShouldLockSchemeRegistry();
  93. +
  94. // Allows the embedder to perform platform-specific initialization before
  95. // BrowserMain() is invoked (i.e. before BrowserMainRunner, BrowserMainLoop,
  96. // BrowserMainParts, etc. are created).