Commit 16480f78 authored by alexeypa@chromium.org's avatar alexeypa@chromium.org

Introducing the DaemonProcess class that will implements core of the daemon...

Introducing the DaemonProcess class that will implements core of the daemon process functionality. It will manage the networking process running at lower privileges and maintains the list of virtual terminals.

BUG=134694


Review URL: https://chromiumcodereview.appspot.com/10823062

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@149347 0039d316-1c4b-4281-b951-d872f2087c98
parent 4d82fad4
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "remoting/host/daemon_process.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread.h"
namespace {
const char kIpcThreadName[] = "Daemon process IPC";
} // namespace
namespace remoting {
DaemonProcess::~DaemonProcess() {
}
bool DaemonProcess::OnMessageReceived(const IPC::Message& message) {
return true;
}
DaemonProcess::DaemonProcess(
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
const base::Closure& stopped_callback)
: Stoppable(main_task_runner, stopped_callback),
main_task_runner_(main_task_runner) {
// Initialize on the same thread that will be used for shutting down.
main_task_runner_->PostTask(
FROM_HERE,
base::Bind(&DaemonProcess::Init, base::Unretained(this)));
}
void DaemonProcess::Init() {
DCHECK(main_task_runner_->BelongsToCurrentThread());
// Launch the IPC thread.
ipc_thread_.reset(new base::Thread(kIpcThreadName));
base::Thread::Options io_thread_options(MessageLoop::TYPE_IO, 0);
if (!ipc_thread_->StartWithOptions(io_thread_options)) {
LOG(ERROR) << "Failed to start the Daemon process IPC thread.";
Stop();
return;
}
if (!LaunchNetworkProcess()) {
LOG(ERROR) << "Failed to launch the networking process.";
Stop();
return;
}
}
void DaemonProcess::DoStop() {
DCHECK(main_task_runner_->BelongsToCurrentThread());
if (ipc_thread_.get()) {
ipc_thread_->Stop();
}
CompleteStopping();
}
} // namespace remoting
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef REMOTING_HOST_DAEMON_PROCESS_H_
#define REMOTING_HOST_DAEMON_PROCESS_H_
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "ipc/ipc_channel.h"
#include "ipc/ipc_channel_proxy.h"
#include "remoting/base/stoppable.h"
namespace base {
class SingleThreadTaskRunner;
class Thread;
} // namespace base
namespace IPC {
class Message;
} // namespace IPC
namespace remoting {
// This class implements core of the daemon process. It manages the networking
// process running at lower privileges and maintains the list of virtual
// terminals.
class DaemonProcess : public Stoppable, public IPC::Listener {
public:
virtual ~DaemonProcess();
// Creates a platform-specific implementation of the daemon process object.
static scoped_ptr<DaemonProcess> Create(
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
const base::Closure& stopped_callback);
// IPC::Listener implementation.
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
protected:
DaemonProcess(scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
const base::Closure& stopped_callback);
// Reads the host configuration and launches the networking process.
void Init();
// Stoppable implementation.
virtual void DoStop() OVERRIDE;
// Launches the network process and establishes an IPC channel with it.
virtual bool LaunchNetworkProcess() = 0;
private:
// The main task runner. Typically it is the UI message loop.
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
// A dedicated thread for handling IPC requests.
scoped_ptr<base::Thread> ipc_thread_;
// The IPC channel connecting the daemon process to the networking process.
scoped_ptr<IPC::ChannelProxy> network_process_channel_;
DISALLOW_COPY_AND_ASSIGN(DaemonProcess);
};
} // namespace remoting
#endif // REMOTING_HOST_DAEMON_PROCESS_H_
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "remoting/host/daemon_process.h"
#include "base/logging.h"
#include "base/single_thread_task_runner.h"
namespace remoting {
class DaemonProcessWin : public DaemonProcess {
public:
DaemonProcessWin(scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
const base::Closure& stopped_callback);
virtual ~DaemonProcessWin();
// DaemonProcess implementation.
virtual bool LaunchNetworkProcess() OVERRIDE;
private:
DISALLOW_COPY_AND_ASSIGN(DaemonProcessWin);
};
DaemonProcessWin::DaemonProcessWin(
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
const base::Closure& stopped_callback)
: DaemonProcess(main_task_runner, stopped_callback) {
}
DaemonProcessWin::~DaemonProcessWin() {
}
bool DaemonProcessWin::LaunchNetworkProcess() {
NOTIMPLEMENTED();
return false;
}
scoped_ptr<DaemonProcess> DaemonProcess::Create(
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
const base::Closure& stopped_callback) {
scoped_ptr<DaemonProcessWin> daemon_process(
new DaemonProcessWin(main_task_runner, stopped_callback));
return daemon_process.PassAs<DaemonProcess>();
}
} // namespace remoting
...@@ -27,15 +27,26 @@ ...@@ -27,15 +27,26 @@
#include "remoting/base/scoped_sc_handle_win.h" #include "remoting/base/scoped_sc_handle_win.h"
#include "remoting/base/stoppable.h" #include "remoting/base/stoppable.h"
#include "remoting/host/branding.h" #include "remoting/host/branding.h"
#if defined(REMOTING_MULTI_PROCESS)
#include "remoting/host/daemon_process.h"
#endif // defined(REMOTING_MULTI_PROCESS)
#include "remoting/host/usage_stats_consent.h" #include "remoting/host/usage_stats_consent.h"
#include "remoting/host/win/host_service_resource.h" #include "remoting/host/win/host_service_resource.h"
#include "remoting/host/win/wts_console_observer.h" #include "remoting/host/win/wts_console_observer.h"
#if !defined(REMOTING_MULTI_PROCESS)
#include "remoting/host/win/wts_session_process_launcher.h" #include "remoting/host/win/wts_session_process_launcher.h"
#endif // !defined(REMOTING_MULTI_PROCESS)
using base::StringPrintf; using base::StringPrintf;
namespace { namespace {
// Session id that does not represent any session.
const uint32 kInvalidSessionId = 0xffffffffu;
const char kIoThreadName[] = "I/O thread"; const char kIoThreadName[] = "I/O thread";
// A window class for the session change notifications window. // A window class for the session change notifications window.
...@@ -100,8 +111,8 @@ void HostService::RemoveWtsConsoleObserver(WtsConsoleObserver* observer) { ...@@ -100,8 +111,8 @@ void HostService::RemoveWtsConsoleObserver(WtsConsoleObserver* observer) {
console_observers_.RemoveObserver(observer); console_observers_.RemoveObserver(observer);
} }
void HostService::OnLauncherShutdown() { void HostService::OnChildStopped() {
launcher_.reset(NULL); child_.reset(NULL);
main_task_runner_->PostTask(FROM_HERE, MessageLoop::QuitClosure()); main_task_runner_->PostTask(FROM_HERE, MessageLoop::QuitClosure());
} }
...@@ -138,8 +149,7 @@ BOOL WINAPI HostService::ConsoleControlHandler(DWORD event) { ...@@ -138,8 +149,7 @@ BOOL WINAPI HostService::ConsoleControlHandler(DWORD event) {
case CTRL_LOGOFF_EVENT: case CTRL_LOGOFF_EVENT:
case CTRL_SHUTDOWN_EVENT: case CTRL_SHUTDOWN_EVENT:
self->main_task_runner_->PostTask(FROM_HERE, base::Bind( self->main_task_runner_->PostTask(FROM_HERE, base::Bind(
&WtsSessionProcessLauncher::Stop, &Stoppable::Stop, base::Unretained(self->child_.get())));
base::Unretained(self->launcher_.get())));
self->stopped_event_.Wait(); self->stopped_event_.Wait();
return TRUE; return TRUE;
...@@ -182,22 +192,33 @@ int HostService::Run() { ...@@ -182,22 +192,33 @@ int HostService::Run() {
} }
void HostService::RunMessageLoop(MessageLoop* message_loop) { void HostService::RunMessageLoop(MessageLoop* message_loop) {
#if defined(REMOTING_MULTI_PROCESS)
child_ = DaemonProcess::Create(
main_task_runner_,
base::Bind(&HostService::OnChildStopped,
base::Unretained(this))).PassAs<Stoppable>();
#else // !defined(REMOTING_MULTI_PROCESS)
// Launch the I/O thread. // Launch the I/O thread.
base::Thread io_thread(kIoThreadName); base::Thread io_thread(kIoThreadName);
base::Thread::Options io_thread_options(MessageLoop::TYPE_IO, 0); base::Thread::Options io_thread_options(MessageLoop::TYPE_IO, 0);
if (!io_thread.StartWithOptions(io_thread_options)) { if (!io_thread.StartWithOptions(io_thread_options)) {
LOG(FATAL) << "Failed to start the I/O thread"; LOG(ERROR) << "Failed to start the I/O thread";
stopped_event_.Signal(); stopped_event_.Signal();
return; return;
} }
// Create the session process launcher. // Create the session process launcher.
launcher_.reset(new WtsSessionProcessLauncher( child_.reset(new WtsSessionProcessLauncher(
base::Bind(&HostService::OnLauncherShutdown, base::Unretained(this)), base::Bind(&HostService::OnChildStopped, base::Unretained(this)),
this, this,
main_task_runner_, main_task_runner_,
io_thread.message_loop_proxy())); io_thread.message_loop_proxy()));
#endif // !defined(REMOTING_MULTI_PROCESS)
// Run the service. // Run the service.
message_loop->Run(); message_loop->Run();
...@@ -304,8 +325,7 @@ DWORD WINAPI HostService::ServiceControlHandler(DWORD control, ...@@ -304,8 +325,7 @@ DWORD WINAPI HostService::ServiceControlHandler(DWORD control,
case SERVICE_CONTROL_SHUTDOWN: case SERVICE_CONTROL_SHUTDOWN:
case SERVICE_CONTROL_STOP: case SERVICE_CONTROL_STOP:
self->main_task_runner_->PostTask(FROM_HERE, base::Bind( self->main_task_runner_->PostTask(FROM_HERE, base::Bind(
&WtsSessionProcessLauncher::Stop, &Stoppable::Stop, base::Unretained(self->child_.get())));
base::Unretained(self->launcher_.get())));
self->stopped_event_.Wait(); self->stopped_event_.Wait();
return NO_ERROR; return NO_ERROR;
......
...@@ -22,9 +22,16 @@ class SingleThreadTaskRunner; ...@@ -22,9 +22,16 @@ class SingleThreadTaskRunner;
namespace remoting { namespace remoting {
#if defined(REMOTING_MULTI_PROCESS)
class DaemonProcess;
#endif // defined(REMOTING_MULTI_PROCESS)
class Stoppable; class Stoppable;
class WtsConsoleObserver; class WtsConsoleObserver;
#if !defined(REMOTING_MULTI_PROCESS)
class WtsSessionProcessLauncher; class WtsSessionProcessLauncher;
#endif // !defined(REMOTING_MULTI_PROCESS)
class HostService : public WtsConsoleMonitor { class HostService : public WtsConsoleMonitor {
public: public:
...@@ -45,7 +52,7 @@ class HostService : public WtsConsoleMonitor { ...@@ -45,7 +52,7 @@ class HostService : public WtsConsoleMonitor {
HostService(); HostService();
~HostService(); ~HostService();
void OnLauncherShutdown(); void OnChildStopped();
// Notifies the service of changes in session state. // Notifies the service of changes in session state.
void OnSessionChange(); void OnSessionChange();
...@@ -85,7 +92,7 @@ class HostService : public WtsConsoleMonitor { ...@@ -85,7 +92,7 @@ class HostService : public WtsConsoleMonitor {
// to the physical console. // to the physical console.
ObserverList<WtsConsoleObserver> console_observers_; ObserverList<WtsConsoleObserver> console_observers_;
scoped_ptr<WtsSessionProcessLauncher> launcher_; scoped_ptr<Stoppable> child_;
// Service message loop. // Service message loop.
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
......
...@@ -214,9 +214,6 @@ bool CreatePipeForIpcChannel(void* instance, ...@@ -214,9 +214,6 @@ bool CreatePipeForIpcChannel(void* instance,
namespace remoting { namespace remoting {
// Session id that does not represent any session.
const uint32 kInvalidSessionId = 0xffffffff;
WtsSessionProcessLauncher::WtsSessionProcessLauncher( WtsSessionProcessLauncher::WtsSessionProcessLauncher(
const base::Closure& stopped_callback, const base::Closure& stopped_callback,
WtsConsoleMonitor* monitor, WtsConsoleMonitor* monitor,
......
...@@ -31,9 +31,6 @@ class Message; ...@@ -31,9 +31,6 @@ class Message;
namespace remoting { namespace remoting {
// Session id that does not represent any session.
extern const uint32 kInvalidSessionId;
class SasInjector; class SasInjector;
class WtsConsoleMonitor; class WtsConsoleMonitor;
......
...@@ -7,7 +7,10 @@ ...@@ -7,7 +7,10 @@
# TODO(dmaclach): can we pick this up some other way? Right now it's # TODO(dmaclach): can we pick this up some other way? Right now it's
# duplicated from chrome.gyp # duplicated from chrome.gyp
'chromium_code': 1, 'chromium_code': 1,
'remoting_audio': 0, 'remoting_audio': 0,
'remoting_multi_process%': 0,
# Use consistent strings across all platforms. Note that the plugin name # Use consistent strings across all platforms. Note that the plugin name
# is brand-dependent and is defined further down. # is brand-dependent and is defined further down.
# Must match host/plugin/constants.h # Must match host/plugin/constants.h
...@@ -204,6 +207,11 @@ ...@@ -204,6 +207,11 @@
'ENABLE_REMOTING_AUDIO', 'ENABLE_REMOTING_AUDIO',
], ],
}], }],
['remoting_multi_process == 1', {
'defines': [
'REMOTING_MULTI_PROCESS',
],
}],
], ],
}, },
...@@ -597,6 +605,9 @@ ...@@ -597,6 +605,9 @@
'host/chromoting_messages.h', 'host/chromoting_messages.h',
'host/constants.h', 'host/constants.h',
'host/constants_win.cc', 'host/constants_win.cc',
'host/daemon_process.cc',
'host/daemon_process.h',
'host/daemon_process_win.cc',
'host/sas_injector.h', 'host/sas_injector.h',
'host/sas_injector_win.cc', 'host/sas_injector_win.cc',
'host/usage_stats_consent.h', 'host/usage_stats_consent.h',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment