diff options
-rw-r--r-- | win8/viewer/metro_viewer_process_host.cc | 40 | ||||
-rw-r--r-- | win8/viewer/metro_viewer_process_host.h | 1 |
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); }; |