Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(395)

Side by Side Diff: remoting/host/desktop_process.cc

Issue 11272036: Fixing threading issues in remoting::DesktopProcess. The UI thread is now owned by the caller of re… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: CR feedback. Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « remoting/host/desktop_process.h ('k') | remoting/host/desktop_process_main.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 // 4 //
5 // This file implements the Windows service controlling Me2Me host processes 5 // This file implements the Windows service controlling Me2Me host processes
6 // running within user sessions. 6 // running within user sessions.
7 7
8 #include "remoting/host/desktop_process.h" 8 #include "remoting/host/desktop_process.h"
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/bind_helpers.h" 11 #include "base/bind_helpers.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/memory/ref_counted.h" 13 #include "base/memory/ref_counted.h"
14 #include "base/message_loop.h" 14 #include "base/message_loop.h"
15 #include "base/run_loop.h"
16 #include "ipc/ipc_channel_proxy.h" 15 #include "ipc/ipc_channel_proxy.h"
17 #include "remoting/base/auto_thread.h" 16 #include "remoting/base/auto_thread.h"
18 #include "remoting/base/auto_thread_task_runner.h" 17 #include "remoting/base/auto_thread_task_runner.h"
19 #include "remoting/host/chromoting_messages.h" 18 #include "remoting/host/chromoting_messages.h"
20 #include "remoting/host/desktop_session_agent.h" 19 #include "remoting/host/desktop_session_agent.h"
21 #include "remoting/host/host_exit_codes.h"
22 20
23 const char kIoThreadName[] = "I/O thread"; 21 const char kIoThreadName[] = "I/O thread";
24 22
25 namespace remoting { 23 namespace remoting {
26 24
27 DesktopProcess::DesktopProcess(const std::string& daemon_channel_name) 25 DesktopProcess::DesktopProcess(
28 : daemon_channel_name_(daemon_channel_name) { 26 scoped_refptr<AutoThreadTaskRunner> caller_task_runner,
27 const std::string& daemon_channel_name)
28 : caller_task_runner_(caller_task_runner),
29 daemon_channel_name_(daemon_channel_name) {
30 DCHECK(caller_task_runner_->BelongsToCurrentThread());
31 DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI);
29 } 32 }
30 33
31 DesktopProcess::~DesktopProcess() { 34 DesktopProcess::~DesktopProcess() {
35 DCHECK(!daemon_channel_);
36 DCHECK(!desktop_agent_);
32 } 37 }
33 38
34 bool DesktopProcess::OnMessageReceived(const IPC::Message& message) { 39 bool DesktopProcess::OnMessageReceived(const IPC::Message& message) {
40 DCHECK(caller_task_runner_->BelongsToCurrentThread());
41
35 bool handled = true; 42 bool handled = true;
36 IPC_BEGIN_MESSAGE_MAP(DesktopProcess, message) 43 IPC_BEGIN_MESSAGE_MAP(DesktopProcess, message)
37 IPC_MESSAGE_HANDLER(ChromotingDaemonDesktopMsg_Crash, OnCrash) 44 IPC_MESSAGE_HANDLER(ChromotingDaemonDesktopMsg_Crash, OnCrash)
38 IPC_MESSAGE_UNHANDLED(handled = false) 45 IPC_MESSAGE_UNHANDLED(handled = false)
39 IPC_END_MESSAGE_MAP() 46 IPC_END_MESSAGE_MAP()
40 return handled; 47 return handled;
41 } 48 }
42 49
43 void DesktopProcess::OnChannelConnected(int32 peer_pid) { 50 void DesktopProcess::OnChannelConnected(int32 peer_pid) {
51 DCHECK(caller_task_runner_->BelongsToCurrentThread());
52
44 VLOG(1) << "IPC: desktop <- daemon (" << peer_pid << ")"; 53 VLOG(1) << "IPC: desktop <- daemon (" << peer_pid << ")";
45 54
46 NOTIMPLEMENTED(); 55 NOTIMPLEMENTED();
47 } 56 }
48 57
49 void DesktopProcess::OnChannelError() { 58 void DesktopProcess::OnChannelError() {
59 DCHECK(caller_task_runner_->BelongsToCurrentThread());
60
50 // Shutdown the desktop process. 61 // Shutdown the desktop process.
51 daemon_channel_.reset(); 62 daemon_channel_.reset();
52 desktop_agent_.reset(); 63 desktop_agent_.reset();
64 caller_task_runner_ = NULL;
53 } 65 }
54 66
55 int DesktopProcess::Run() { 67 bool DesktopProcess::Start() {
56 DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); 68 DCHECK(caller_task_runner_->BelongsToCurrentThread());
57 69
58 { 70 // Launch the I/O thread.
59 scoped_refptr<AutoThreadTaskRunner> ui_task_runner = 71 scoped_refptr<AutoThreadTaskRunner> io_task_runner =
60 new remoting::AutoThreadTaskRunner( 72 AutoThread::CreateWithType(kIoThreadName, caller_task_runner_,
61 MessageLoop::current()->message_loop_proxy(), 73 MessageLoop::TYPE_IO);
62 MessageLoop::QuitClosure());
63 74
64 // Launch the I/O thread. 75 // Create a desktop agent.
65 scoped_refptr<AutoThreadTaskRunner> io_task_runner = 76 desktop_agent_ = DesktopSessionAgent::Create(caller_task_runner_,
66 AutoThread::CreateWithType(kIoThreadName, ui_task_runner, 77 io_task_runner);
67 MessageLoop::TYPE_IO);
68 78
69 // Create a desktop agent. 79 // Start the agent and create an IPC channel to talk to it. It is safe to
70 desktop_agent_ = DesktopSessionAgent::Create(ui_task_runner, 80 // use base::Unretained(this) here because the message loop below will run
71 io_task_runner); 81 // until |desktop_agent_| is completely destroyed.
72 82 IPC::PlatformFileForTransit desktop_pipe;
73 // Start the agent and create an IPC channel to talk to it. It is safe to 83 if (!desktop_agent_->Start(base::Bind(&DesktopProcess::OnChannelError,
74 // use base::Unretained(this) here because the message loop below will run 84 base::Unretained(this)),
75 // until |desktop_agent_| is completely destroyed. 85 &desktop_pipe)) {
76 IPC::PlatformFileForTransit desktop_pipe; 86 desktop_agent_.reset();
77 if (!desktop_agent_->Start(base::Bind(&DesktopProcess::OnChannelError, 87 return false;
78 base::Unretained(this)),
79 &desktop_pipe)) {
80 desktop_agent_.reset();
81 return kInitializationFailed;
82 }
83
84 // Connect to the daemon.
85 daemon_channel_.reset(new IPC::ChannelProxy(daemon_channel_name_,
86 IPC::Channel::MODE_CLIENT,
87 this,
88 io_task_runner));
89
90 // Pass |desktop_pipe| to the daemon.
91 daemon_channel_->Send(
92 new ChromotingDesktopDaemonMsg_DesktopAttached(desktop_pipe));
93 } 88 }
94 89
95 // Run the UI message loop. 90 // Connect to the daemon.
96 base::RunLoop run_loop; 91 daemon_channel_.reset(new IPC::ChannelProxy(daemon_channel_name_,
97 run_loop.Run(); 92 IPC::Channel::MODE_CLIENT,
93 this,
94 io_task_runner));
98 95
99 DCHECK(!daemon_channel_); 96 // Pass |desktop_pipe| to the daemon.
100 DCHECK(!desktop_agent_); 97 daemon_channel_->Send(
101 return kSuccessExitCode; 98 new ChromotingDesktopDaemonMsg_DesktopAttached(desktop_pipe));
99
100 return true;
102 } 101 }
103 102
104 void DesktopProcess::OnCrash(const std::string& function_name, 103 void DesktopProcess::OnCrash(const std::string& function_name,
105 const std::string& file_name, 104 const std::string& file_name,
106 const int& line_number) { 105 const int& line_number) {
107 // The daemon requested us to crash the process. 106 // The daemon requested us to crash the process.
108 CHECK(false); 107 CHECK(false);
109 } 108 }
110 109
111 } // namespace remoting 110 } // namespace remoting
OLDNEW
« no previous file with comments | « remoting/host/desktop_process.h ('k') | remoting/host/desktop_process_main.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698