diff options
author | stoyan@chromium.org <stoyan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-28 21:00:54 +0000 |
---|---|---|
committer | stoyan@chromium.org <stoyan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-28 21:00:54 +0000 |
commit | 5cec0eb314bb4936e29d9138d259a4706aeacf4f (patch) | |
tree | 5137905e86b6acfd6c9b1c3c5516c144c3ccd2ab | |
parent | dcdcfa08eabd39a5efd01eb32e47b261805abf4b (diff) | |
download | chromium_src-5cec0eb314bb4936e29d9138d259a4706aeacf4f.zip chromium_src-5cec0eb314bb4936e29d9138d259a4706aeacf4f.tar.gz chromium_src-5cec0eb314bb4936e29d9138d259a4706aeacf4f.tar.bz2 |
Nicely steal moniker and bind context from the urlmon url request.
BUG=42104
Review URL: http://codereview.chromium.org/1811001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@45860 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome_frame/urlmon_url_request.cc | 53 | ||||
-rw-r--r-- | chrome_frame/urlmon_url_request.h | 5 | ||||
-rw-r--r-- | chrome_frame/urlmon_url_request_private.h | 10 |
3 files changed, 49 insertions, 19 deletions
diff --git a/chrome_frame/urlmon_url_request.cc b/chrome_frame/urlmon_url_request.cc index 2a1d28d..fb937bf 100644 --- a/chrome_frame/urlmon_url_request.cc +++ b/chrome_frame/urlmon_url_request.cc @@ -138,13 +138,21 @@ HRESULT UrlmonUrlRequest::InitPending(const GURL& url, IMoniker* moniker, return S_OK; } -void UrlmonUrlRequest::StealMoniker(IMoniker** moniker, IBindCtx** bctx) { - // Could be called in any thread. There should be no race - // since moniker_ is not released while we are in manager's request map. +void UrlmonUrlRequest::TerminateBind(TerminateBindCallback* callback) { + DCHECK_EQ(thread_, PlatformThread::CurrentId()); DLOG(INFO) << __FUNCTION__ << " id: " << id(); - DLOG_IF(WARNING, moniker == NULL) << __FUNCTION__ << " no moniker"; - *moniker = moniker_.Detach(); - *bctx = bind_context_.Detach(); + + if (status_.get_state() == Status::DONE) { + // Binding is stopped. Note result could be an error. + callback->Run(moniker_, bind_context_); + delete callback; + } else { + // WORKING (ABORTING?). Save the callback. + // Now we will return INET_TERMINATE_BIND from ::OnDataAvailable() and in + // ::OnStopBinding will invoke the callback passing our moniker and + // bind context. + terminate_bind_callback_.reset(callback); + } } size_t UrlmonUrlRequest::SendDataToDelegate(size_t bytes_to_read) { @@ -272,6 +280,10 @@ STDMETHODIMP UrlmonUrlRequest::OnStopBinding(HRESULT result, LPCWSTR error) { // Mark we a are done. status_.Done(); + if (result == INET_E_TERMINATED_BIND && terminate_requested()) { + terminate_bind_callback_->Run(moniker_, bind_context_); + } + // We always return INET_E_TERMINATED_BIND from OnDataAvailable if (result == INET_E_TERMINATED_BIND) result = S_OK; @@ -396,6 +408,9 @@ STDMETHODIMP UrlmonUrlRequest::OnDataAvailable(DWORD flags, DWORD size, DLOG(INFO) << StringPrintf("URL: %s Obj: %X - Bytes available: %d", url().c_str(), this, size); + if (terminate_requested()) + return INET_E_TERMINATED_BIND; + if (!storage || (storage->tymed != TYMED_ISTREAM)) { NOTREACHED(); return E_INVALIDARG; @@ -1025,18 +1040,9 @@ void UrlmonUrlRequestManager::DownloadRequestInHost(int request_id) { if (IsWindow(notification_window_)) { scoped_refptr<UrlmonUrlRequest> request(LookupRequest(request_id)); if (request) { - ScopedComPtr<IMoniker> moniker; - ScopedComPtr<IBindCtx> bind_context; - request->StealMoniker(moniker.Receive(), bind_context.Receive()); - DLOG_IF(ERROR, moniker == NULL) << __FUNCTION__ << " No moniker!"; - if (moniker) { - // We use SendMessage and not PostMessage to make sure that if the - // notification window does not handle the message we won't leak - // the moniker. - ::SendMessage(notification_window_, WM_DOWNLOAD_IN_HOST, - reinterpret_cast<WPARAM>(bind_context.get()), - reinterpret_cast<LPARAM>(moniker.get())); - } + UrlmonUrlRequest::TerminateBindCallback* callback = NewCallback(this, + &UrlmonUrlRequestManager::BindTerminated); + request->TerminateBind(callback); } } else { NOTREACHED() @@ -1044,6 +1050,17 @@ void UrlmonUrlRequestManager::DownloadRequestInHost(int request_id) { } } +void UrlmonUrlRequestManager::BindTerminated(IMoniker* moniker, + IBindCtx* bind_ctx) { + // We use SendMessage and not PostMessage to make sure that if the + // notification window does not handle the message we won't leak + // the moniker. + ::SendMessage(notification_window_, WM_DOWNLOAD_IN_HOST, + reinterpret_cast<WPARAM>(bind_ctx), + reinterpret_cast<LPARAM>(moniker)); +} + + void UrlmonUrlRequestManager::GetCookiesForUrl(const GURL& url, int cookie_id) { DWORD cookie_size = 0; bool success = true; diff --git a/chrome_frame/urlmon_url_request.h b/chrome_frame/urlmon_url_request.h index 9ace8dc..676aa3b 100644 --- a/chrome_frame/urlmon_url_request.h +++ b/chrome_frame/urlmon_url_request.h @@ -101,6 +101,11 @@ class UrlmonUrlRequestManager const std::string& cookie_string, int cookie_id); + // This method is passed as a callback to UrlmonUrlRequest::TerminateBind. + // We simply forward moniker and bind_ctx to host ActiveX/ActiveDocument, + // so it may start NavigateWithBindContext. + void BindTerminated(IMoniker* moniker, IBindCtx* bind_ctx); + // Map for (request_id <-> UrlmonUrlRequest) typedef std::map<int, scoped_refptr<UrlmonUrlRequest> > RequestMap; RequestMap request_map_; diff --git a/chrome_frame/urlmon_url_request_private.h b/chrome_frame/urlmon_url_request_private.h index ad7aa5a..f8c3561 100644 --- a/chrome_frame/urlmon_url_request_private.h +++ b/chrome_frame/urlmon_url_request_private.h @@ -36,7 +36,10 @@ class UrlmonUrlRequest HWND notification_window, IStream* cache); // Used from "DownloadRequestInHost". - void StealMoniker(IMoniker** moniker, IBindCtx** bctx); + // Callback will be invoked either right away (if operation is finished) or + // from inside ::OnStopBinding() when it is safe to reuse the bind_context. + typedef Callback2<IMoniker*, IBindCtx*>::Type TerminateBindCallback; + void TerminateBind(TerminateBindCallback* callback); // Parent Window for UrlMon error dialogs void set_parent_window(HWND parent_window) { @@ -110,6 +113,10 @@ class UrlmonUrlRequest return pending_; } + bool terminate_requested() const { + return terminate_bind_callback_.get() != NULL; + } + std::string response_headers() { return response_headers_; } @@ -271,6 +278,7 @@ class UrlmonUrlRequest // Set to true if the ChromeFrame instance is running in privileged mode. bool privileged_mode_; bool pending_; + scoped_ptr<TerminateBindCallback> terminate_bind_callback_; std::string response_headers_; DISALLOW_COPY_AND_ASSIGN(UrlmonUrlRequest); }; |