summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome_frame/chrome_frame_automation.cc26
-rw-r--r--chrome_frame/urlmon_url_request.cc17
2 files changed, 33 insertions, 10 deletions
diff --git a/chrome_frame/chrome_frame_automation.cc b/chrome_frame/chrome_frame_automation.cc
index 54e114d..1a4b763 100644
--- a/chrome_frame/chrome_frame_automation.cc
+++ b/chrome_frame/chrome_frame_automation.cc
@@ -1018,8 +1018,13 @@ bool ChromeFrameAutomationClient::ReadRequest(
void ChromeFrameAutomationClient::RemoveRequest(PluginUrlRequest* request) {
DCHECK_EQ(PlatformThread::CurrentId(), ui_thread_id_);
- DCHECK(request_map_.end() != request_map_.find(request->id()));
- request_map_.erase(request->id());
+
+ // We check if the request pointer passed in is actually present in the map
+ // before going ahead and deleting it. This avoids the issue where we would
+ // incorrectly delete a different request with the same request id.
+ if (IsValidRequest(request)) {
+ request_map_.erase(request->id());
+ }
}
void ChromeFrameAutomationClient::RemoveRequest(int request_id, bool abort) {
@@ -1081,17 +1086,23 @@ void ChromeFrameAutomationClient::CleanupRequests() {
void ChromeFrameAutomationClient::CleanupAsyncRequests() {
DCHECK_EQ(PlatformThread::CurrentId(), ui_thread_id_);
+
+ std::vector<scoped_refptr<PluginUrlRequest> > request_list;
+ // We copy the pending requests into a temporary vector as the Stop
+ // function in the request could also try to delete the request from
+ // the request map and the iterator could end up being invalid.
RequestMap::iterator index = request_map_.begin();
while (index != request_map_.end()) {
PluginUrlRequest* request = (*index).second;
- if (request) {
- int request_id = request->id();
- request->Stop();
- }
+ DCHECK(request != NULL);
+ request_list.push_back(request);
index++;
}
-
request_map_.clear();
+
+ for (unsigned int index = 0; index < request_list.size(); ++index) {
+ request_list[index]->Stop();
+ }
}
bool ChromeFrameAutomationClient::Reinitialize(
@@ -1108,6 +1119,7 @@ bool ChromeFrameAutomationClient::Reinitialize(
return false;
}
+ CleanupAsyncRequests();
chrome_frame_delegate_ = delegate;
SetParentWindow(NULL);
return true;
diff --git a/chrome_frame/urlmon_url_request.cc b/chrome_frame/urlmon_url_request.cc
index 1c71edb..560f4b8 100644
--- a/chrome_frame/urlmon_url_request.cc
+++ b/chrome_frame/urlmon_url_request.cc
@@ -46,13 +46,14 @@ bool UrlmonUrlRequest::Start() {
return false;
}
- worker_thread_->message_loop()->PostTask(
- FROM_HERE, NewRunnableMethod(this, &UrlmonUrlRequest::StartAsync));
-
// Take a self reference to maintain COM lifetime. This will be released
// in EndRequest
AddRef();
request_handler()->AddRequest(this);
+
+ worker_thread_->message_loop()->PostTask(
+ FROM_HERE, NewRunnableMethod(this, &UrlmonUrlRequest::StartAsync));
+
return true;
}
@@ -64,6 +65,11 @@ void UrlmonUrlRequest::Stop() {
return;
}
+ // We can remove the request from the map safely here if it is still valid.
+ // There is an additional reference on the UrlmonUrlRequest instance which
+ // is released when the task scheduled by the EndRequest function executes.
+ request_handler()->RemoveRequest(this);
+
worker_thread_->message_loop()->PostTask(
FROM_HERE, NewRunnableMethod(this, &UrlmonUrlRequest::StopAsync));
}
@@ -205,6 +211,8 @@ STDMETHODIMP UrlmonUrlRequest::OnStopBinding(HRESULT result, LPCWSTR error) {
status_.set_os_error(0);
}
+ DLOG(INFO) << "OnStopBinding received for request id: " << id();
+
// Release these variables after reporting EndRequest since we might need to
// access their state.
binding_ = NULL;
@@ -605,6 +613,9 @@ void UrlmonUrlRequest::EndRequest() {
}
void UrlmonUrlRequest::EndRequestInternal() {
+ // The request object could have been removed from the map in the
+ // OnRequestEnd callback which executes on receiving the
+ // AutomationMsg_RequestEnd IPC from Chrome.
request_handler()->RemoveRequest(this);
// Release the outstanding reference in the context of the UI thread to
// ensure that our instance gets deleted in the same thread which created it.