summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--win8/viewer/metro_viewer_process_host.cc40
-rw-r--r--win8/viewer/metro_viewer_process_host.h1
2 files changed, 32 insertions, 9 deletions
diff --git a/win8/viewer/metro_viewer_process_host.cc b/win8/viewer/metro_viewer_process_host.cc
index 4fa5194..a44ea3c 100644
--- a/win8/viewer/metro_viewer_process_host.cc
+++ b/win8/viewer/metro_viewer_process_host.cc
@@ -11,6 +11,7 @@
#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
#include "base/process/process.h"
+#include "base/process/process_handle.h"
#include "base/strings/string16.h"
#include "base/synchronization/waitable_event.h"
#include "base/time/time.h"
@@ -21,6 +22,12 @@
#include "ui/metro_viewer/metro_viewer_messages.h"
#include "win8/viewer/metro_viewer_constants.h"
+namespace {
+
+const int kViewerProcessConnectionTimeoutSecs = 60;
+
+} // namespace
+
namespace win8 {
MetroViewerProcessHost::InternalMessageFilter::InternalMessageFilter(
@@ -43,6 +50,26 @@ MetroViewerProcessHost::MetroViewerProcessHost(
}
MetroViewerProcessHost::~MetroViewerProcessHost() {
+ if (!channel_)
+ return;
+
+ base::ProcessId viewer_process_id = GetViewerProcessId();
+ channel_->Close();
+ if (message_filter_) {
+ // Wait for the viewer process to go away.
+ if (viewer_process_id != base::kNullProcessId) {
+ base::ProcessHandle viewer_process = NULL;
+ base::OpenProcessHandleWithAccess(
+ viewer_process_id,
+ PROCESS_QUERY_INFORMATION | SYNCHRONIZE,
+ &viewer_process);
+ if (viewer_process) {
+ ::WaitForSingleObject(viewer_process, INFINITE);
+ ::CloseHandle(viewer_process);
+ }
+ }
+ channel_->RemoveFilter(message_filter_);
+ }
}
base::ProcessId MetroViewerProcessHost::GetViewerProcessId() {
@@ -57,9 +84,8 @@ bool MetroViewerProcessHost::LaunchViewerAndWaitForConnection(
channel_connected_event_.reset(new base::WaitableEvent(false, false));
- scoped_refptr<InternalMessageFilter> message_filter(
- new InternalMessageFilter(this));
- channel_->AddFilter(message_filter);
+ message_filter_ = new InternalMessageFilter(this);
+ channel_->AddFilter(message_filter_);
base::win::ScopedComPtr<IApplicationActivationManager> activator;
HRESULT hr = activator.CreateInstance(CLSID_ApplicationActivationManager);
@@ -75,13 +101,9 @@ bool MetroViewerProcessHost::LaunchViewerAndWaitForConnection(
// Having launched the viewer process, now we wait for it to connect.
bool success =
- channel_connected_event_->TimedWait(base::TimeDelta::FromSeconds(60));
+ channel_connected_event_->TimedWait(base::TimeDelta::FromSeconds(
+ kViewerProcessConnectionTimeoutSecs));
channel_connected_event_.reset();
-
- // |message_filter| is only used to signal |channel_connected_event_| above
- // and can thus be removed after |channel_connected_event_| is no longer
- // waiting.
- channel_->RemoveFilter(message_filter);
return success;
}
diff --git a/win8/viewer/metro_viewer_process_host.h b/win8/viewer/metro_viewer_process_host.h
index e156226..209a94c 100644
--- a/win8/viewer/metro_viewer_process_host.h
+++ b/win8/viewer/metro_viewer_process_host.h
@@ -96,6 +96,7 @@ class MetroViewerProcessHost : public IPC::Listener,
scoped_ptr<IPC::ChannelProxy> channel_;
scoped_ptr<base::WaitableEvent> channel_connected_event_;
+ scoped_refptr<InternalMessageFilter> message_filter_;
DISALLOW_COPY_AND_ASSIGN(MetroViewerProcessHost);
};