diff options
author | ananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-24 01:29:20 +0000 |
---|---|---|
committer | ananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-24 01:29:20 +0000 |
commit | 5778de6e6bfbc0439f49a245a75efa44e4f9a771 (patch) | |
tree | 7596aff0328ee022a23a9a0e84c28f94ee40ea30 /chrome_frame/chrome_frame_activex_base.h | |
parent | b5be3f53d7af0037dbc634beb550752de56ad840 (diff) | |
download | chromium_src-5778de6e6bfbc0439f49a245a75efa44e4f9a771.zip chromium_src-5778de6e6bfbc0439f49a245a75efa44e4f9a771.tar.gz chromium_src-5778de6e6bfbc0439f49a245a75efa44e4f9a771.tar.bz2 |
Currently the host network stack in IE which uses Urlmon interfaces to initiate
and complete URL downloads requested by ChromeFrame, executes in the UI thread of IE.
While this works fine in most cases for large data sizes, the IE UI thread ends up being
busy pulling the data in our IBindStatusCallback::OnDataAvailable implementation. As a result
the browser hangs until all data is pulled out.
The fix is to handle Urlmon requests on a separate thread.
This fixes http://code.google.com/p/chromium/issues/detail?id=24007
Changes to plugin_url_request.cc/.h are to set the LF property on these files.
Bug=24007
Review URL: http://codereview.chromium.org/292035
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@29986 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome_frame/chrome_frame_activex_base.h')
-rw-r--r-- | chrome_frame/chrome_frame_activex_base.h | 55 |
1 files changed, 46 insertions, 9 deletions
diff --git a/chrome_frame/chrome_frame_activex_base.h b/chrome_frame/chrome_frame_activex_base.h index 651ecbf..bbd88dc 100644 --- a/chrome_frame/chrome_frame_activex_base.h +++ b/chrome_frame/chrome_frame_activex_base.h @@ -150,13 +150,19 @@ class ATL_NO_VTABLE ChromeFrameActivexBase : public IPropertyNotifySinkCP<T>, public CComCoClass<T, &class_id>, public CComControl<T>, - public ChromeFramePlugin<T> { + public ChromeFramePlugin<T>, + public TaskMarshallerThroughWindowsMessages< + ChromeFrameActivexBase<T, class_id> > { protected: typedef std::set<ScopedComPtr<IDispatch> > EventHandlers; + typedef TaskMarshallerThroughWindowsMessages< + ChromeFrameActivexBase<T, class_id> > TaskMarshaller; + typedef ChromeFrameActivexBase<T, class_id> Base; public: ChromeFrameActivexBase() - : ready_state_(READYSTATE_UNINITIALIZED) { + : ready_state_(READYSTATE_UNINITIALIZED), + worker_thread_("ChromeFrameWorker_Thread") { m_bWindowOnly = TRUE; } @@ -197,6 +203,7 @@ BEGIN_MSG_MAP(ChromeFrameActivexBase) MESSAGE_HANDLER(WM_CREATE, OnCreate) CHAIN_MSG_MAP(ChromeFramePlugin<T>) CHAIN_MSG_MAP(CComControl<T>) + CHAIN_MSG_MAP(TaskMarshaller) DEFAULT_REFLECTION_HANDLER() END_MSG_MAP() @@ -231,6 +238,12 @@ END_MSG_MAP() IE_8, IE_8 + 1); } + + base::Thread::Options options; + options.message_loop_type = MessageLoop::TYPE_UI; + worker_thread_.StartWithOptions(options); + worker_thread_.message_loop()->PostTask( + FROM_HERE, NewRunnableMethod(this, &Base::OnWorkerStart)); return S_OK; } @@ -302,10 +315,21 @@ END_MSG_MAP() // of this template should implement this method based on how // it "feels" from a security perspective. If it's hosted in another // scriptable document, return true, else false. - virtual bool is_frame_busting_enabled() const { + bool is_frame_busting_enabled() const { return true; } + // Needed to support PostTask. + static bool ImplementsThreadSafeReferenceCounting() { + return true; + } + + virtual void OnFinalMessage(HWND) { + worker_thread_.message_loop()->PostTask( + FROM_HERE, NewRunnableMethod(this, &Base::OnWorkerStop)); + worker_thread_.Stop(); + } + protected: virtual void OnTabbedOut(int tab_handle, bool reverse) { DCHECK(m_bInPlaceActive); @@ -419,12 +443,13 @@ END_MSG_MAP() DCHECK(request.get() != NULL); - if (request->Initialize(automation_client_.get(), tab_handle, request_id, - request_info.url, request_info.method, - request_info.referrer, - request_info.extra_request_headers, - request_info.upload_data.get(), - static_cast<T*>(this)->is_frame_busting_enabled())) { + if (request->Initialize( + automation_client_.get(), tab_handle, request_id, request_info.url, + request_info.method, request_info.referrer, + request_info.extra_request_headers, request_info.upload_data.get(), + static_cast<T*>(this)->is_frame_busting_enabled())) { + request->set_worker_thread(&worker_thread_); + request->set_task_marshaller(this); // If Start is successful, it will add a self reference. request->Start(); request->set_parent_window(m_hWnd); @@ -941,6 +966,16 @@ END_MSG_MAP() } protected: + // The following functions are called to initialize and uninitialize the + // worker thread. + void OnWorkerStart() { + CoInitialize(NULL); + } + + void OnWorkerStop() { + CoUninitialize(); + } + ScopedBstr url_; ScopedComPtr<IOleDocumentSite> doc_site_; @@ -963,6 +998,8 @@ END_MSG_MAP() // The UrlmonUrlRequest instance instantiated for downloading the base URL. scoped_refptr<CComObject<UrlmonUrlRequest> > base_url_request_; + + base::Thread worker_thread_; }; #endif // CHROME_FRAME_CHROME_FRAME_ACTIVEX_BASE_H_ |