summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--remoting/base/stoppable.cc43
-rw-r--r--remoting/base/stoppable.h63
-rw-r--r--remoting/host/daemon_process.cc35
-rw-r--r--remoting/host/daemon_process.h13
-rw-r--r--remoting/host/daemon_process_win.cc14
-rw-r--r--remoting/host/win/host_service.cc40
-rw-r--r--remoting/host/win/host_service.h17
-rw-r--r--remoting/remoting.gyp2
8 files changed, 60 insertions, 167 deletions
diff --git a/remoting/base/stoppable.cc b/remoting/base/stoppable.cc
deleted file mode 100644
index 99acba4..0000000
--- a/remoting/base/stoppable.cc
+++ /dev/null
@@ -1,43 +0,0 @@
-// 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/base/stoppable.h"
-
-#include "base/message_loop.h"
-#include "base/single_thread_task_runner.h"
-
-namespace remoting {
-
-Stoppable::Stoppable(
- scoped_refptr<base::SingleThreadTaskRunner> task_runner,
- const base::Closure& stopped_callback)
- : state_(kRunning),
- stopped_callback_(stopped_callback),
- task_runner_(task_runner) {
-}
-
-Stoppable::~Stoppable() {
- CHECK_EQ(state_, kStopped);
-}
-
-void Stoppable::Stop() {
- DCHECK(task_runner_->BelongsToCurrentThread());
-
- if (state_ == kRunning) {
- state_ = kStopping;
- }
-
- // DoStop() can be called multiple times.
- DoStop();
-}
-
-void Stoppable::CompleteStopping() {
- DCHECK(task_runner_->BelongsToCurrentThread());
- DCHECK_EQ(state_, kStopping);
-
- state_ = kStopped;
- task_runner_->PostTask(FROM_HERE, stopped_callback_);
-}
-
-} // namespace remoting
diff --git a/remoting/base/stoppable.h b/remoting/base/stoppable.h
deleted file mode 100644
index dddfcdae..0000000
--- a/remoting/base/stoppable.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// 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_BASE_STOPPABLE_H_
-#define REMOTING_BASE_STOPPABLE_H_
-
-#include "base/basictypes.h"
-#include "base/callback.h"
-#include "base/memory/ref_counted.h"
-
-namespace base {
-class SingleThreadTaskRunner;
-} // namespace base
-
-namespace remoting {
-
-// A helper base class that implements asynchronous shutdown on a specific
-// thread.
-class Stoppable {
- public:
- // Constructs an object and stores the callback to be posted to |task_runner|
- // once the object has been shutdown completely.
- Stoppable(scoped_refptr<base::SingleThreadTaskRunner> task_runner,
- const base::Closure& stopped_callback);
- virtual ~Stoppable();
-
- // Initiates shutdown. It can be called by both the owner of the object and
- // the object itself resulting in the same shutdown sequence.
- void Stop();
-
- protected:
- // Called by derived classes to notify about shutdown completion. Posts
- // the completion task on |task_runner_| message loop.
- void CompleteStopping();
-
- // Derived classes have to override this method to implement the shutdown
- // logic.
- virtual void DoStop() = 0;
-
- enum State {
- kRunning,
- kStopping,
- kStopped
- };
-
- State stoppable_state() const { return state_; }
-
- private:
- State state_;
-
- // A callback to be called when shutdown is completed.
- base::Closure stopped_callback_;
-
- // The target task runner where the shutdown notification will be posted.
- scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
-
- DISALLOW_COPY_AND_ASSIGN(Stoppable);
-};
-
-} // namespace remoting
-
-#endif // REMOTING_BASE_STOPPABLE_H_
diff --git a/remoting/host/daemon_process.cc b/remoting/host/daemon_process.cc
index b7a0336..d9d05b4 100644
--- a/remoting/host/daemon_process.cc
+++ b/remoting/host/daemon_process.cc
@@ -37,8 +37,13 @@ std::ostream& operator<<(std::ostream& os, const ScreenResolution& resolution) {
} // namespace
DaemonProcess::~DaemonProcess() {
- DCHECK(!config_watcher_.get());
- DCHECK(desktop_sessions_.empty());
+ DCHECK(caller_task_runner()->BelongsToCurrentThread());
+
+ host_event_logger_.reset();
+ weak_factory_.InvalidateWeakPtrs();
+
+ config_watcher_.reset();
+ DeleteAllDesktopSessions();
}
void DaemonProcess::OnConfigUpdated(const std::string& serialized_config) {
@@ -163,10 +168,10 @@ DaemonProcess::DaemonProcess(
scoped_refptr<AutoThreadTaskRunner> caller_task_runner,
scoped_refptr<AutoThreadTaskRunner> io_task_runner,
const base::Closure& stopped_callback)
- : Stoppable(caller_task_runner, stopped_callback),
- caller_task_runner_(caller_task_runner),
+ : caller_task_runner_(caller_task_runner),
io_task_runner_(io_task_runner),
next_terminal_id_(0),
+ stopped_callback_(stopped_callback),
weak_factory_(this) {
DCHECK(caller_task_runner->BelongsToCurrentThread());
}
@@ -270,6 +275,16 @@ void DaemonProcess::Initialize() {
LaunchNetworkProcess();
}
+void DaemonProcess::Stop() {
+ DCHECK(caller_task_runner()->BelongsToCurrentThread());
+
+ if (!stopped_callback_.is_null()) {
+ base::Closure stopped_callback = stopped_callback_;
+ stopped_callback_.Reset();
+ stopped_callback.Run();
+ }
+}
+
bool DaemonProcess::WasTerminalIdAllocated(int terminal_id) {
return terminal_id < next_terminal_id_;
}
@@ -352,18 +367,6 @@ void DaemonProcess::OnHostShutdown() {
FOR_EACH_OBSERVER(HostStatusObserver, status_observers_, OnShutdown());
}
-void DaemonProcess::DoStop() {
- DCHECK(caller_task_runner()->BelongsToCurrentThread());
-
- host_event_logger_.reset();
- weak_factory_.InvalidateWeakPtrs();
-
- config_watcher_.reset();
- DeleteAllDesktopSessions();
-
- CompleteStopping();
-}
-
void DaemonProcess::DeleteAllDesktopSessions() {
while (!desktop_sessions_.empty()) {
delete desktop_sessions_.front();
diff --git a/remoting/host/daemon_process.h b/remoting/host/daemon_process.h
index 99ddb2a..521d706 100644
--- a/remoting/host/daemon_process.h
+++ b/remoting/host/daemon_process.h
@@ -17,7 +17,6 @@
#include "ipc/ipc_channel.h"
#include "ipc/ipc_channel_proxy.h"
#include "ipc/ipc_platform_file.h"
-#include "remoting/base/stoppable.h"
#include "remoting/host/config_file_watcher.h"
#include "remoting/host/host_status_monitor.h"
#include "remoting/host/worker_process_ipc_delegate.h"
@@ -40,8 +39,7 @@ class ScreenResolution;
// process running at lower privileges and maintains the list of desktop
// sessions.
class DaemonProcess
- : public Stoppable,
- public ConfigFileWatcher::Delegate,
+ : public ConfigFileWatcher::Delegate,
public HostStatusMonitor,
public WorkerProcessIpcDelegate {
public:
@@ -107,6 +105,9 @@ class DaemonProcess
// Reads the host configuration and launches the network process.
void Initialize();
+ // Invokes |stopped_callback_| to ask the owner to delete |this|.
+ void Stop();
+
// Returns true if |terminal_id| is in the range of allocated IDs. I.e. it is
// less or equal to the highest ID we have seen so far.
bool WasTerminalIdAllocated(int terminal_id);
@@ -123,9 +124,6 @@ class DaemonProcess
void OnHostStarted(const std::string& xmpp_login);
void OnHostShutdown();
- // Stoppable implementation.
- virtual void DoStop() OVERRIDE;
-
// Creates a platform-specific desktop session and assigns a unique ID to it.
// An implementation should validate |params| as they are received via IPC.
virtual scoped_ptr<DesktopSession> DoCreateDesktopSession(
@@ -178,6 +176,9 @@ class DaemonProcess
// Keeps track of observers receiving host status notifications.
ObserverList<HostStatusObserver> status_observers_;
+ // Invoked to ask the owner to delete |this|.
+ base::Closure stopped_callback_;
+
// Writes host status updates to the system event log.
scoped_ptr<HostEventLogger> host_event_logger_;
diff --git a/remoting/host/daemon_process_win.cc b/remoting/host/daemon_process_win.cc
index e3f2b4d..5d2dc94 100644
--- a/remoting/host/daemon_process_win.cc
+++ b/remoting/host/daemon_process_win.cc
@@ -60,9 +60,6 @@ class DaemonProcessWin : public DaemonProcess {
IPC::PlatformFileForTransit desktop_pipe) OVERRIDE;
protected:
- // Stoppable implementation.
- virtual void DoStop() OVERRIDE;
-
// DaemonProcess implementation.
virtual scoped_ptr<DesktopSession> DoCreateDesktopSession(
int terminal_id,
@@ -89,10 +86,6 @@ DaemonProcessWin::DaemonProcessWin(
}
DaemonProcessWin::~DaemonProcessWin() {
- // Make sure that the object is completely stopped. The same check exists
- // in Stoppable::~Stoppable() but this one helps us to fail early and
- // predictably.
- CHECK_EQ(stoppable_state(), Stoppable::kStopped);
}
void DaemonProcessWin::OnChannelConnected(int32 peer_pid) {
@@ -138,13 +131,6 @@ bool DaemonProcessWin::OnDesktopSessionAgentAttached(
return true;
}
-void DaemonProcessWin::DoStop() {
- DCHECK(caller_task_runner()->BelongsToCurrentThread());
-
- network_launcher_.reset();
- DaemonProcess::DoStop();
-}
-
scoped_ptr<DesktopSession> DaemonProcessWin::DoCreateDesktopSession(
int terminal_id,
const ScreenResolution& resolution,
diff --git a/remoting/host/win/host_service.cc b/remoting/host/win/host_service.cc
index 42a8ed0..b3cf6b0 100644
--- a/remoting/host/win/host_service.cc
+++ b/remoting/host/win/host_service.cc
@@ -25,7 +25,6 @@
#include "base/win/windows_version.h"
#include "remoting/base/auto_thread.h"
#include "remoting/base/scoped_sc_handle_win.h"
-#include "remoting/base/stoppable.h"
#include "remoting/host/branding.h"
#include "remoting/host/daemon_process.h"
#include "remoting/host/host_exit_codes.h"
@@ -203,7 +202,8 @@ void HostService::RemoveWtsTerminalObserver(WtsTerminalObserver* observer) {
HostService::HostService() :
run_routine_(&HostService::RunAsService),
service_status_handle_(0),
- stopped_event_(true, false) {
+ stopped_event_(true, false),
+ weak_factory_(this) {
}
HostService::~HostService() {
@@ -275,17 +275,10 @@ void HostService::CreateLauncher(
return;
}
- child_ = DaemonProcess::Create(
+ daemon_process_ = DaemonProcess::Create(
task_runner,
io_task_runner,
- base::Bind(&HostService::OnChildStopped,
- base::Unretained(this))).PassAs<Stoppable>();
-}
-
-void HostService::OnChildStopped() {
- DCHECK(main_task_runner_->BelongsToCurrentThread());
-
- child_.reset(NULL);
+ base::Bind(&HostService::StopDaemonProcess, weak_ptr_));
}
int HostService::RunAsService() {
@@ -312,6 +305,7 @@ void HostService::RunAsServiceImpl() {
base::MessageLoop message_loop(base::MessageLoop::TYPE_UI);
base::RunLoop run_loop;
main_task_runner_ = message_loop.message_loop_proxy();
+ weak_ptr_ = weak_factory_.GetWeakPtr();
// Register the service control handler.
service_status_handle_ = RegisterServiceCtrlHandlerExW(
@@ -351,6 +345,7 @@ void HostService::RunAsServiceImpl() {
// Run the service.
run_loop.Run();
+ weak_factory_.InvalidateWeakPtrs();
// Tell SCM that the service is stopped.
service_status.dwCurrentState = SERVICE_STOPPED;
@@ -366,6 +361,7 @@ int HostService::RunInConsole() {
base::MessageLoop message_loop(base::MessageLoop::TYPE_UI);
base::RunLoop run_loop;
main_task_runner_ = message_loop.message_loop_proxy();
+ weak_ptr_ = weak_factory_.GetWeakPtr();
int result = kInitializationFailed;
@@ -410,6 +406,8 @@ int HostService::RunInConsole() {
}
cleanup:
+ weak_factory_.InvalidateWeakPtrs();
+
// Unsubscribe from console events. Ignore the exit code. There is nothing
// we can do about it now and the program is about to exit anyway. Even if
// it crashes nothing is going to be broken because of it.
@@ -418,6 +416,12 @@ cleanup:
return result;
}
+void HostService::StopDaemonProcess() {
+ DCHECK(main_task_runner_->BelongsToCurrentThread());
+
+ daemon_process_.reset();
+}
+
bool HostService::HandleMessage(
HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam, LRESULT* result) {
if (message == WM_WTSSESSION_CHANGE) {
@@ -438,9 +442,9 @@ BOOL WINAPI HostService::ConsoleControlHandler(DWORD event) {
case CTRL_CLOSE_EVENT:
case CTRL_LOGOFF_EVENT:
case CTRL_SHUTDOWN_EVENT:
- self->main_task_runner_->PostTask(FROM_HERE, base::Bind(
- &Stoppable::Stop, base::Unretained(self->child_.get())));
- self->stopped_event_.Wait();
+ self->main_task_runner_->PostTask(
+ FROM_HERE, base::Bind(&HostService::StopDaemonProcess,
+ self->weak_ptr_));
return TRUE;
default:
@@ -460,14 +464,14 @@ DWORD WINAPI HostService::ServiceControlHandler(DWORD control,
case SERVICE_CONTROL_SHUTDOWN:
case SERVICE_CONTROL_STOP:
- self->main_task_runner_->PostTask(FROM_HERE, base::Bind(
- &Stoppable::Stop, base::Unretained(self->child_.get())));
- self->stopped_event_.Wait();
+ self->main_task_runner_->PostTask(
+ FROM_HERE, base::Bind(&HostService::StopDaemonProcess,
+ self->weak_ptr_));
return NO_ERROR;
case SERVICE_CONTROL_SESSIONCHANGE:
self->main_task_runner_->PostTask(FROM_HERE, base::Bind(
- &HostService::OnSessionChange, base::Unretained(self), event_type,
+ &HostService::OnSessionChange, self->weak_ptr_, event_type,
reinterpret_cast<WTSSESSION_NOTIFICATION*>(event_data)->dwSessionId));
return NO_ERROR;
diff --git a/remoting/host/win/host_service.h b/remoting/host/win/host_service.h
index aa1d9ab..a591071 100644
--- a/remoting/host/win/host_service.h
+++ b/remoting/host/win/host_service.h
@@ -11,6 +11,7 @@
#include "base/memory/ref_counted.h"
#include "base/memory/singleton.h"
+#include "base/memory/weak_ptr.h"
#include "base/synchronization/waitable_event.h"
#include "net/base/ip_endpoint.h"
#include "remoting/host/win/message_window.h"
@@ -25,7 +26,7 @@ class SingleThreadTaskRunner;
namespace remoting {
class AutoThreadTaskRunner;
-class Stoppable;
+class DaemonProcess;
class WtsTerminalObserver;
class HostService : public win::MessageWindow::Delegate,
@@ -55,8 +56,6 @@ class HostService : public win::MessageWindow::Delegate,
// Creates the process launcher.
void CreateLauncher(scoped_refptr<AutoThreadTaskRunner> task_runner);
- void OnChildStopped();
-
// This function handshakes with the service control manager and starts
// the service.
int RunAsService();
@@ -70,6 +69,9 @@ class HostService : public win::MessageWindow::Delegate,
// console application).
int RunInConsole();
+ // Stops and deletes |daemon_process_|.
+ void StopDaemonProcess();
+
// win::MessageWindow::Delegate interface.
virtual bool HandleMessage(HWND hwnd,
UINT message,
@@ -105,9 +107,10 @@ class HostService : public win::MessageWindow::Delegate,
// The list of observers receiving session notifications.
std::list<RegisteredObserver> observers_;
- scoped_ptr<Stoppable> child_;
+ scoped_ptr<DaemonProcess> daemon_process_;
- // Service message loop.
+ // Service message loop. |main_task_runner_| must be valid as long as the
+ // Control+C or service notification handler is registered.
scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
// The action routine to be executed.
@@ -119,6 +122,10 @@ class HostService : public win::MessageWindow::Delegate,
// A waitable event that is used to wait until the service is stopped.
base::WaitableEvent stopped_event_;
+ // Used to post session change notifications and control events.
+ base::WeakPtrFactory<HostService> weak_factory_;
+ base::WeakPtr<HostService> weak_ptr_;
+
// Singleton.
friend struct DefaultSingletonTraits<HostService>;
diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp
index 9eda077..1b21b38 100644
--- a/remoting/remoting.gyp
+++ b/remoting/remoting.gyp
@@ -2343,8 +2343,6 @@
'base/running_average.h',
'base/socket_reader.cc',
'base/socket_reader.h',
- 'base/stoppable.cc',
- 'base/stoppable.h',
'base/typed_buffer.h',
'base/util.cc',
'base/util.h',