summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorstoyan@chromium.org <stoyan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-28 21:00:54 +0000
committerstoyan@chromium.org <stoyan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-28 21:00:54 +0000
commit5cec0eb314bb4936e29d9138d259a4706aeacf4f (patch)
tree5137905e86b6acfd6c9b1c3c5516c144c3ccd2ab
parentdcdcfa08eabd39a5efd01eb32e47b261805abf4b (diff)
downloadchromium_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.cc53
-rw-r--r--chrome_frame/urlmon_url_request.h5
-rw-r--r--chrome_frame/urlmon_url_request_private.h10
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);
};