Commit 38ccd8c1 authored by Kevin Babbitt's avatar Kevin Babbitt Committed by Commit Bot

Mark Windows print API calls as blocking

https://crrev.com/c/2135054 resolved a threading issue by moving print
operations to the browser UI thread on Windows. Prior to that CL, the
work being done was marked as blocking at the task level, rather than
at the individual API level. The blocking annotations were removed in
order to not have a ScopedBlockingCall immediately preceded by a
ScopedAllowBlocking.

This CL reintroduces the ScopedBlockingCall marks at the point where
potentially blocking APIs are actually called. Existing callers also
gain ScopedAllowBlocking as needed.

Bug: 1067666
Change-Id: Ifb96feb96f0e6ba38ac06f09f0aa9640c547dba2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2128690
Commit-Queue: Kevin Babbitt <kbabbitt@microsoft.com>
Reviewed-by: default avatarLei Zhang <thestig@chromium.org>
Reviewed-by: default avatarRaymes Khoury <raymes@chromium.org>
Cr-Commit-Position: refs/heads/master@{#756910}
parent 823675ef
...@@ -147,6 +147,7 @@ class CategorizedWorkerPool; ...@@ -147,6 +147,7 @@ class CategorizedWorkerPool;
class DesktopCaptureDevice; class DesktopCaptureDevice;
class InProcessUtilityThread; class InProcessUtilityThread;
class NestedMessagePumpAndroid; class NestedMessagePumpAndroid;
class PepperPrintSettingsManagerImpl;
class RenderProcessHostImpl; class RenderProcessHostImpl;
class RenderWidgetHostViewMac; class RenderWidgetHostViewMac;
class RTCVideoDecoder; class RTCVideoDecoder;
...@@ -365,6 +366,7 @@ class BASE_EXPORT ScopedAllowBlocking { ...@@ -365,6 +366,7 @@ class BASE_EXPORT ScopedAllowBlocking {
friend class android_webview::ScopedAllowInitGLBindings; friend class android_webview::ScopedAllowInitGLBindings;
friend class chromeos::MojoUtils; // http://crbug.com/1055467 friend class chromeos::MojoUtils; // http://crbug.com/1055467
friend class content::BrowserProcessSubThread; friend class content::BrowserProcessSubThread;
friend class content::PepperPrintSettingsManagerImpl;
friend class content::RenderProcessHostImpl; friend class content::RenderProcessHostImpl;
friend class content::RenderWidgetHostViewMac; // http://crbug.com/121917 friend class content::RenderWidgetHostViewMac; // http://crbug.com/121917
friend class content::WebContentsViewMac; friend class content::WebContentsViewMac;
......
...@@ -222,8 +222,15 @@ void PrintJobWorker::UpdatePrintSettings(base::Value new_settings, ...@@ -222,8 +222,15 @@ void PrintJobWorker::UpdatePrintSettings(base::Value new_settings,
print_backend->GetPrinterDriverInfo(printer_name)); print_backend->GetPrinterDriverInfo(printer_name));
} }
PrintingContext::Result result = PrintingContext::Result result;
printing_context_->UpdatePrintSettings(std::move(new_settings)); {
#if defined(OS_WIN)
// Blocking is needed here because Windows printer drivers are oftentimes
// not thread-safe and have to be accessed on the UI thread.
base::ScopedAllowBlocking allow_blocking;
#endif
result = printing_context_->UpdatePrintSettings(std::move(new_settings));
}
GetSettingsDone(std::move(callback), result); GetSettingsDone(std::move(callback), result);
} }
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "content/browser/renderer_host/pepper/pepper_print_settings_manager.h" #include "content/browser/renderer_host/pepper/pepper_print_settings_manager.h"
#include "base/task/post_task.h" #include "base/task/post_task.h"
#include "build/build_config.h"
#include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h" #include "content/public/browser/content_browser_client.h"
...@@ -12,6 +13,10 @@ ...@@ -12,6 +13,10 @@
#include "ppapi/c/pp_errors.h" #include "ppapi/c/pp_errors.h"
#include "printing/buildflags/buildflags.h" #include "printing/buildflags/buildflags.h"
#if defined(OS_WIN)
#include "base/threading/thread_restrictions.h"
#endif
#if BUILDFLAG(ENABLE_PRINT_PREVIEW) #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
#include "printing/printing_context.h" // nogncheck #include "printing/printing_context.h" // nogncheck
#include "printing/units.h" // nogncheck #include "printing/units.h" // nogncheck
...@@ -59,11 +64,23 @@ class PrintingContextDelegate : public printing::PrintingContext::Delegate { ...@@ -59,11 +64,23 @@ class PrintingContextDelegate : public printing::PrintingContext::Delegate {
} }
}; };
PepperPrintSettingsManager::Result ComputeDefaultPrintSettings() { #endif
} // namespace
PepperPrintSettingsManager::Result
PepperPrintSettingsManagerImpl::ComputeDefaultPrintSettings() {
#if BUILDFLAG(ENABLE_PRINT_PREVIEW)
// This function should run on the UI thread because |PrintingContext| methods // This function should run on the UI thread because |PrintingContext| methods
// call into platform APIs. // call into platform APIs.
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
#if defined(OS_WIN)
// Blocking is needed here because Windows printer drivers are oftentimes
// not thread-safe and have to be accessed on the UI thread.
base::ScopedAllowBlocking allow_blocking;
#endif
PrintingContextDelegate delegate; PrintingContextDelegate delegate;
std::unique_ptr<printing::PrintingContext> context( std::unique_ptr<printing::PrintingContext> context(
printing::PrintingContext::Create(&delegate)); printing::PrintingContext::Create(&delegate));
...@@ -101,15 +118,11 @@ PepperPrintSettingsManager::Result ComputeDefaultPrintSettings() { ...@@ -101,15 +118,11 @@ PepperPrintSettingsManager::Result ComputeDefaultPrintSettings() {
// so just make it the default. // so just make it the default.
settings.format = PP_PRINTOUTPUTFORMAT_PDF; settings.format = PP_PRINTOUTPUTFORMAT_PDF;
return PepperPrintSettingsManager::Result(settings, PP_OK); return PepperPrintSettingsManager::Result(settings, PP_OK);
}
#else #else
PepperPrintSettingsManager::Result ComputeDefaultPrintSettings() {
return PepperPrintSettingsManager::Result(PP_PrintSettings_Dev(), return PepperPrintSettingsManager::Result(PP_PrintSettings_Dev(),
PP_ERROR_NOTSUPPORTED); PP_ERROR_NOTSUPPORTED);
}
#endif #endif
}
} // namespace
void PepperPrintSettingsManagerImpl::GetDefaultPrintSettings( void PepperPrintSettingsManagerImpl::GetDefaultPrintSettings(
PepperPrintSettingsManager::Callback callback) { PepperPrintSettingsManager::Callback callback) {
......
...@@ -42,6 +42,8 @@ class CONTENT_EXPORT PepperPrintSettingsManagerImpl ...@@ -42,6 +42,8 @@ class CONTENT_EXPORT PepperPrintSettingsManagerImpl
PepperPrintSettingsManager::Callback callback) override; PepperPrintSettingsManager::Callback callback) override;
private: private:
static PepperPrintSettingsManager::Result ComputeDefaultPrintSettings();
DISALLOW_COPY_AND_ASSIGN(PepperPrintSettingsManagerImpl); DISALLOW_COPY_AND_ASSIGN(PepperPrintSettingsManagerImpl);
}; };
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h" #include "base/strings/string_piece.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/threading/scoped_blocking_call.h"
#include "base/win/scoped_bstr.h" #include "base/win/scoped_bstr.h"
#include "base/win/scoped_hglobal.h" #include "base/win/scoped_hglobal.h"
#include "printing/backend/print_backend_consts.h" #include "printing/backend/print_backend_consts.h"
...@@ -222,6 +223,8 @@ std::string PrintBackendWin::GetDefaultPrinterName() { ...@@ -222,6 +223,8 @@ std::string PrintBackendWin::GetDefaultPrinterName() {
DWORD size = MAX_PATH; DWORD size = MAX_PATH;
TCHAR default_printer_name[MAX_PATH]; TCHAR default_printer_name[MAX_PATH];
std::string ret; std::string ret;
base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
base::BlockingType::MAY_BLOCK);
if (::GetDefaultPrinter(default_printer_name, &size)) if (::GetDefaultPrinter(default_printer_name, &size))
ret = base::WideToUTF8(default_printer_name); ret = base::WideToUTF8(default_printer_name);
return ret; return ret;
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/threading/scoped_blocking_call.h"
#include "base/win/windows_version.h" #include "base/win/windows_version.h"
#include "printing/backend/print_backend.h" #include "printing/backend/print_backend.h"
#include "printing/backend/print_backend_consts.h" #include "printing/backend/print_backend_consts.h"
...@@ -212,6 +213,8 @@ bool XPSModule::InitImpl() { ...@@ -212,6 +213,8 @@ bool XPSModule::InitImpl() {
HRESULT XPSModule::OpenProvider(const base::string16& printer_name, HRESULT XPSModule::OpenProvider(const base::string16& printer_name,
DWORD version, DWORD version,
HPTPROVIDER* provider) { HPTPROVIDER* provider) {
base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
base::BlockingType::MAY_BLOCK);
return g_open_provider_proc(printer_name.c_str(), version, provider); return g_open_provider_proc(printer_name.c_str(), version, provider);
} }
...@@ -219,6 +222,8 @@ HRESULT XPSModule::GetPrintCapabilities(HPTPROVIDER provider, ...@@ -219,6 +222,8 @@ HRESULT XPSModule::GetPrintCapabilities(HPTPROVIDER provider,
IStream* print_ticket, IStream* print_ticket,
IStream* capabilities, IStream* capabilities,
BSTR* error_message) { BSTR* error_message) {
base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
base::BlockingType::MAY_BLOCK);
return g_get_print_capabilities_proc(provider, print_ticket, capabilities, return g_get_print_capabilities_proc(provider, print_ticket, capabilities,
error_message); error_message);
} }
...@@ -228,6 +233,8 @@ HRESULT XPSModule::ConvertDevModeToPrintTicket(HPTPROVIDER provider, ...@@ -228,6 +233,8 @@ HRESULT XPSModule::ConvertDevModeToPrintTicket(HPTPROVIDER provider,
PDEVMODE devmode, PDEVMODE devmode,
EPrintTicketScope scope, EPrintTicketScope scope,
IStream* print_ticket) { IStream* print_ticket) {
base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
base::BlockingType::MAY_BLOCK);
return g_convert_devmode_to_print_ticket_proc(provider, devmode_size_in_bytes, return g_convert_devmode_to_print_ticket_proc(provider, devmode_size_in_bytes,
devmode, scope, print_ticket); devmode, scope, print_ticket);
} }
...@@ -240,6 +247,8 @@ HRESULT XPSModule::ConvertPrintTicketToDevMode( ...@@ -240,6 +247,8 @@ HRESULT XPSModule::ConvertPrintTicketToDevMode(
ULONG* devmode_byte_count, ULONG* devmode_byte_count,
PDEVMODE* devmode, PDEVMODE* devmode,
BSTR* error_message) { BSTR* error_message) {
base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
base::BlockingType::MAY_BLOCK);
return g_convert_print_ticket_to_devmode_proc( return g_convert_print_ticket_to_devmode_proc(
provider, print_ticket, base_devmode_type, scope, devmode_byte_count, provider, print_ticket, base_devmode_type, scope, devmode_byte_count,
devmode, error_message); devmode, error_message);
...@@ -251,15 +260,21 @@ HRESULT XPSModule::MergeAndValidatePrintTicket(HPTPROVIDER provider, ...@@ -251,15 +260,21 @@ HRESULT XPSModule::MergeAndValidatePrintTicket(HPTPROVIDER provider,
EPrintTicketScope scope, EPrintTicketScope scope,
IStream* result_ticket, IStream* result_ticket,
BSTR* error_message) { BSTR* error_message) {
base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
base::BlockingType::MAY_BLOCK);
return g_merge_and_validate_print_ticket_proc( return g_merge_and_validate_print_ticket_proc(
provider, base_ticket, delta_ticket, scope, result_ticket, error_message); provider, base_ticket, delta_ticket, scope, result_ticket, error_message);
} }
HRESULT XPSModule::ReleaseMemory(PVOID buffer) { HRESULT XPSModule::ReleaseMemory(PVOID buffer) {
base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
base::BlockingType::MAY_BLOCK);
return g_release_memory_proc(buffer); return g_release_memory_proc(buffer);
} }
HRESULT XPSModule::CloseProvider(HPTPROVIDER provider) { HRESULT XPSModule::CloseProvider(HPTPROVIDER provider) {
base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
base::BlockingType::MAY_BLOCK);
return g_close_provider_proc(provider); return g_close_provider_proc(provider);
} }
...@@ -489,14 +504,21 @@ std::unique_ptr<DEVMODE, base::FreeDeleter> CreateDevModeWithColor( ...@@ -489,14 +504,21 @@ std::unique_ptr<DEVMODE, base::FreeDeleter> CreateDevModeWithColor(
} }
bool PrinterHasValidPaperSize(const wchar_t* name, const wchar_t* port) { bool PrinterHasValidPaperSize(const wchar_t* name, const wchar_t* port) {
base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
base::BlockingType::MAY_BLOCK);
return DeviceCapabilities(name, port, DC_PAPERSIZE, nullptr, nullptr) > 0; return DeviceCapabilities(name, port, DC_PAPERSIZE, nullptr, nullptr) > 0;
} }
std::unique_ptr<DEVMODE, base::FreeDeleter> CreateDevMode(HANDLE printer, std::unique_ptr<DEVMODE, base::FreeDeleter> CreateDevMode(HANDLE printer,
DEVMODE* in) { DEVMODE* in) {
wchar_t* device_name_ptr = const_cast<wchar_t*>(L""); wchar_t* device_name_ptr = const_cast<wchar_t*>(L"");
LONG buffer_size = DocumentProperties(nullptr, printer, device_name_ptr, LONG buffer_size;
nullptr, nullptr, 0); {
base::ScopedBlockingCall scoped_blocking_call(
FROM_HERE, base::BlockingType::MAY_BLOCK);
buffer_size = DocumentProperties(nullptr, printer, device_name_ptr, nullptr,
nullptr, 0);
}
if (buffer_size < static_cast<int>(sizeof(DEVMODE))) if (buffer_size < static_cast<int>(sizeof(DEVMODE)))
return nullptr; return nullptr;
...@@ -521,9 +543,13 @@ std::unique_ptr<DEVMODE, base::FreeDeleter> CreateDevMode(HANDLE printer, ...@@ -521,9 +543,13 @@ std::unique_ptr<DEVMODE, base::FreeDeleter> CreateDevMode(HANDLE printer,
return nullptr; return nullptr;
} }
if (DocumentProperties(nullptr, printer, device_name_ptr, out.get(), in, {
flags) != IDOK) { base::ScopedBlockingCall scoped_blocking_call(
return nullptr; FROM_HERE, base::BlockingType::MAY_BLOCK);
if (DocumentProperties(nullptr, printer, device_name_ptr, out.get(), in,
flags) != IDOK) {
return nullptr;
}
} }
int size = out->dmSize; int size = out->dmSize;
...@@ -559,8 +585,14 @@ std::unique_ptr<DEVMODE, base::FreeDeleter> PromptDevMode( ...@@ -559,8 +585,14 @@ std::unique_ptr<DEVMODE, base::FreeDeleter> PromptDevMode(
std::unique_ptr<DEVMODE, base::FreeDeleter> out( std::unique_ptr<DEVMODE, base::FreeDeleter> out(
reinterpret_cast<DEVMODE*>(calloc(buffer_size, 1))); reinterpret_cast<DEVMODE*>(calloc(buffer_size, 1)));
DWORD flags = (in ? (DM_IN_BUFFER) : 0) | DM_OUT_BUFFER | DM_IN_PROMPT; DWORD flags = (in ? (DM_IN_BUFFER) : 0) | DM_OUT_BUFFER | DM_IN_PROMPT;
LONG result = DocumentProperties(window, printer, printer_name_ptr, out.get(), LONG result;
in, flags); {
base::ScopedBlockingCall scoped_blocking_call(
FROM_HERE, base::BlockingType::MAY_BLOCK);
result = DocumentProperties(window, printer, printer_name_ptr, out.get(),
in, flags);
}
if (canceled) if (canceled)
*canceled = (result == IDCANCEL); *canceled = (result == IDCANCEL);
if (result != IDOK) if (result != IDOK)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment