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

Unified Diff: remoting/host/plugin/daemon_controller_win.cc

Issue 10272029: Make sure the timer is stopped and destroyed on the thread it was created on. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: CR feedback Created 8 years, 8 months 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: remoting/host/plugin/daemon_controller_win.cc
diff --git a/remoting/host/plugin/daemon_controller_win.cc b/remoting/host/plugin/daemon_controller_win.cc
index 49b1809b831ebb2ea27ee93ac5379812e3c49bc8..ddf8df4a59510e1885b451fc90545dfc84fd81b7 100644
--- a/remoting/host/plugin/daemon_controller_win.cc
+++ b/remoting/host/plugin/daemon_controller_win.cc
@@ -55,25 +55,12 @@ class ComThread : public base::Thread {
public:
explicit ComThread(const char* name);
- // Activates an elevated instance of the controller and returns the pointer
- // to the control interface in |control_out|. This class keeps the ownership
- // of the pointer so the caller should not call call AddRef() or Release().
- HRESULT ActivateElevatedController(HWND window_handle,
- IDaemonControl** control_out);
-
bool Start();
protected:
virtual void Init() OVERRIDE;
virtual void CleanUp() OVERRIDE;
- void ReleaseElevatedController();
-
- ScopedComPtr<IDaemonControl> control_;
-
- // This timer is used to release |control_| after a timeout.
- base::OneShotTimer<ComThread> release_timer_;
-
DISALLOW_COPY_AND_ASSIGN(ComThread);
};
@@ -93,11 +80,11 @@ class DaemonControllerWin : public remoting::DaemonController {
virtual void SetWindow(void* window_handle) OVERRIDE;
private:
- // Converts a Windows service status code to a Daemon state.
- static State ConvertToDaemonState(DWORD service_state);
+ // Activates an elevated instance of the controller and caches it.
+ HRESULT ActivateElevatedController();
- // Converts HRESULT to the AsyncResult.
- static AsyncResult HResultToAsyncResult(HRESULT hr);
+ // Releases the cached instance of the elevated controller.
+ void ReleaseElevatedController();
// Procedes with the daemon configuration if the installation succeeded,
// otherwise reports the error.
@@ -112,6 +99,12 @@ class DaemonControllerWin : public remoting::DaemonController {
static void ConfigToString(const base::DictionaryValue& config,
ScopedBstr* out);
+ // Converts a Windows service status code to a Daemon state.
+ static State ConvertToDaemonState(DWORD service_state);
+
+ // Converts HRESULT to the AsyncResult.
+ static AsyncResult HResultToAsyncResult(HRESULT hr);
+
// The functions that actually do the work. They should be called in
// the context of |worker_thread_|;
void DoGetConfig(const GetConfigCallback& callback);
@@ -124,6 +117,11 @@ class DaemonControllerWin : public remoting::DaemonController {
void DoStop(const CompletionCallback& done_callback);
void DoSetWindow(void* window_handle);
+ ScopedComPtr<IDaemonControl> control_;
+
+ // This timer is used to release |control_| after a timeout.
+ scoped_ptr<base::OneShotTimer<DaemonControllerWin> > release_timer_;
+
// Handle of the plugin window.
HWND window_handle_;
@@ -135,38 +133,7 @@ class DaemonControllerWin : public remoting::DaemonController {
DISALLOW_COPY_AND_ASSIGN(DaemonControllerWin);
};
-ComThread::ComThread(const char* name) : base::Thread(name), control_(NULL) {
-}
-
-HRESULT ComThread::ActivateElevatedController(
- HWND window_handle,
- IDaemonControl** control_out) {
- // Cache an instance of the Elevated Controller to prevent a UAC prompt on
- // every operation.
- if (control_.get() == NULL) {
- BIND_OPTS3 bind_options;
- memset(&bind_options, 0, sizeof(bind_options));
- bind_options.cbStruct = sizeof(bind_options);
- bind_options.hwnd = GetTopLevelWindow(window_handle);
- bind_options.dwClassContext = CLSCTX_LOCAL_SERVER;
-
- HRESULT hr = ::CoGetObject(
- kDaemonControllerElevationMoniker,
- &bind_options,
- IID_IDaemonControl,
- control_.ReceiveVoid());
- if (FAILED(hr)) {
- return hr;
- }
-
- // Release |control_| upon expiration of the timeout.
- release_timer_.Start(FROM_HERE,
- base::TimeDelta::FromSeconds(kUacTimeoutSec),
- this, &ComThread::ReleaseElevatedController);
- }
-
- *control_out = control_.get();
- return S_OK;
+ComThread::ComThread(const char* name) : base::Thread(name) {
}
bool ComThread::Start() {
@@ -180,14 +147,9 @@ void ComThread::Init() {
}
void ComThread::CleanUp() {
- ReleaseElevatedController();
CoUninitialize();
}
-void ComThread::ReleaseElevatedController() {
- control_.Release();
-}
-
DaemonControllerWin::DaemonControllerWin()
: window_handle_(NULL),
worker_thread_(kDaemonControllerThreadName) {
@@ -197,6 +159,11 @@ DaemonControllerWin::DaemonControllerWin()
}
DaemonControllerWin::~DaemonControllerWin() {
+ // Clean up resources allocated on the worker thread.
+ worker_thread_.message_loop_proxy()->PostTask(
+ FROM_HERE,
+ base::Bind(&DaemonControllerWin::ReleaseElevatedController,
+ base::Unretained(this)));
worker_thread_.Stop();
}
@@ -265,40 +232,43 @@ void DaemonControllerWin::SetWindow(void* window_handle) {
window_handle));
}
-// static
-remoting::DaemonController::State DaemonControllerWin::ConvertToDaemonState(
- DWORD service_state) {
- switch (service_state) {
- case SERVICE_RUNNING:
- return STATE_STARTED;
-
- case SERVICE_CONTINUE_PENDING:
- case SERVICE_START_PENDING:
- return STATE_STARTING;
- break;
+HRESULT DaemonControllerWin::ActivateElevatedController() {
+ DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread());
- case SERVICE_PAUSE_PENDING:
- case SERVICE_STOP_PENDING:
- return STATE_STOPPING;
- break;
+ // Cache an instance of the Elevated Controller to prevent a UAC prompt on
+ // every operation.
+ if (control_.get() == NULL) {
+ BIND_OPTS3 bind_options;
+ memset(&bind_options, 0, sizeof(bind_options));
+ bind_options.cbStruct = sizeof(bind_options);
+ bind_options.hwnd = GetTopLevelWindow(window_handle_);
+ bind_options.dwClassContext = CLSCTX_LOCAL_SERVER;
- case SERVICE_PAUSED:
- case SERVICE_STOPPED:
- return STATE_STOPPED;
- break;
+ HRESULT hr = ::CoGetObject(
+ kDaemonControllerElevationMoniker,
+ &bind_options,
+ IID_IDaemonControl,
+ control_.ReceiveVoid());
+ if (FAILED(hr)) {
+ return hr;
+ }
- default:
- NOTREACHED();
- return STATE_UNKNOWN;
+ // Release |control_| upon expiration of the timeout.
+ release_timer_.reset(new base::OneShotTimer<DaemonControllerWin>());
+ release_timer_->Start(FROM_HERE,
+ base::TimeDelta::FromSeconds(kUacTimeoutSec),
+ this,
+ &DaemonControllerWin::ReleaseElevatedController);
}
+
+ return S_OK;
}
-// static
-DaemonController::AsyncResult DaemonControllerWin::HResultToAsyncResult(
- HRESULT hr) {
- // TODO(sergeyu): Report other errors to the webapp once it knows
- // how to handle them.
- return FAILED(hr) ? RESULT_FAILED : RESULT_OK;
+void DaemonControllerWin::ReleaseElevatedController() {
+ DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread());
+
+ control_.Release();
+ release_timer_.reset();
}
void DaemonControllerWin::OnInstallationComplete(
@@ -346,6 +316,7 @@ DWORD DaemonControllerWin::OpenService(ScopedScHandle* service_out) {
return ERROR_SUCCESS;
}
+// static
void DaemonControllerWin::ConfigToString(const base::DictionaryValue& config,
ScopedBstr* out) {
std::string config_str;
@@ -354,6 +325,42 @@ void DaemonControllerWin::ConfigToString(const base::DictionaryValue& config,
out->Swap(config_scoped_bstr);
}
+// static
+remoting::DaemonController::State DaemonControllerWin::ConvertToDaemonState(
+ DWORD service_state) {
+ switch (service_state) {
+ case SERVICE_RUNNING:
+ return STATE_STARTED;
+
+ case SERVICE_CONTINUE_PENDING:
+ case SERVICE_START_PENDING:
+ return STATE_STARTING;
+ break;
+
+ case SERVICE_PAUSE_PENDING:
+ case SERVICE_STOP_PENDING:
+ return STATE_STOPPING;
+ break;
+
+ case SERVICE_PAUSED:
+ case SERVICE_STOPPED:
+ return STATE_STOPPED;
+ break;
+
+ default:
+ NOTREACHED();
+ return STATE_UNKNOWN;
+ }
+}
+
+// static
+DaemonController::AsyncResult DaemonControllerWin::HResultToAsyncResult(
+ HRESULT hr) {
+ // TODO(sergeyu): Report other errors to the webapp once it knows
+ // how to handle them.
+ return FAILED(hr) ? RESULT_FAILED : RESULT_OK;
+}
+
void DaemonControllerWin::DoGetConfig(const GetConfigCallback& callback) {
DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread());
@@ -412,11 +419,8 @@ void DaemonControllerWin::DoInstallAsNeededAndStart(
const CompletionCallback& done_callback) {
DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread());
- IDaemonControl* control = NULL;
- HRESULT hr = worker_thread_.ActivateElevatedController(window_handle_,
- &control);
-
- // Just configure and start the Daemon Controller if it is installed already.
+ // Configure and start the Daemon Controller if it is installed already.
+ HRESULT hr = ActivateElevatedController();
if (SUCCEEDED(hr)) {
DoSetConfigAndStart(config.Pass(), done_callback);
return;
@@ -447,9 +451,7 @@ void DaemonControllerWin::DoSetConfigAndStart(
const CompletionCallback& done_callback) {
DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread());
- IDaemonControl* control = NULL;
- HRESULT hr = worker_thread_.ActivateElevatedController(window_handle_,
- &control);
+ HRESULT hr = ActivateElevatedController();
if (FAILED(hr)) {
done_callback.Run(HResultToAsyncResult(hr));
return;
@@ -463,14 +465,14 @@ void DaemonControllerWin::DoSetConfigAndStart(
return;
}
- hr = control->SetConfig(config_str);
+ hr = control_->SetConfig(config_str);
if (FAILED(hr)) {
done_callback.Run(HResultToAsyncResult(hr));
return;
}
// Start daemon.
- hr = control->StartDaemon();
+ hr = control_->StartDaemon();
done_callback.Run(HResultToAsyncResult(hr));
}
@@ -479,9 +481,7 @@ void DaemonControllerWin::DoUpdateConfig(
const CompletionCallback& done_callback) {
DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread());
- IDaemonControl* control = NULL;
- HRESULT hr = worker_thread_.ActivateElevatedController(window_handle_,
- &control);
+ HRESULT hr = ActivateElevatedController();
if (FAILED(hr)) {
done_callback.Run(HResultToAsyncResult(hr));
return;
@@ -495,22 +495,20 @@ void DaemonControllerWin::DoUpdateConfig(
return;
}
- hr = control->UpdateConfig(config_str);
+ hr = control_->UpdateConfig(config_str);
done_callback.Run(HResultToAsyncResult(hr));
}
void DaemonControllerWin::DoStop(const CompletionCallback& done_callback) {
DCHECK(worker_thread_.message_loop_proxy()->BelongsToCurrentThread());
- IDaemonControl* control = NULL;
- HRESULT hr = worker_thread_.ActivateElevatedController(window_handle_,
- &control);
+ HRESULT hr = ActivateElevatedController();
if (FAILED(hr)) {
done_callback.Run(HResultToAsyncResult(hr));
return;
}
- hr = control->StopDaemon();
+ hr = control_->StopDaemon();
done_callback.Run(HResultToAsyncResult(hr));
}
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698