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
3 // found in the LICENSE file.
5 #ifndef REMOTING_HOST_WIN_WORKER_PROCESS_LAUNCHER_H_
6 #define REMOTING_HOST_WIN_WORKER_PROCESS_LAUNCHER_H_
8 #include "base/basictypes.h"
9 #include "base/callback.h"
10 #include "base/compiler_specific.h"
11 #include "base/memory/ref_counted.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/threading/non_thread_safe.h"
14 #include "base/timer/timer.h"
15 #include "base/win/object_watcher.h"
16 #include "base/win/scoped_handle.h"
17 #include "net/base/backoff_entry.h"
20 class SingleThreadTaskRunner
;
28 namespace tracked_objects
{
30 } // namespace tracked_objects
34 class WorkerProcessIpcDelegate
;
36 // Launches a worker process that is controlled via an IPC channel. All
37 // interaction with the spawned process is through WorkerProcessIpcDelegate and
38 // Send() method. In case of error the channel is closed and the worker process
40 class WorkerProcessLauncher
41 : public base::NonThreadSafe
,
42 public base::win::ObjectWatcher::Delegate
{
48 // Asynchronously starts the worker process and creates an IPC channel it
49 // can connect to. |event_handler| must remain valid until KillProcess() has
51 virtual void LaunchProcess(WorkerProcessLauncher
* event_handler
) = 0;
53 // Sends an IPC message to the worker process. The message will be silently
54 // dropped if the channel is closed.
55 virtual void Send(IPC::Message
* message
) = 0;
57 // Closes the IPC channel.
58 virtual void CloseChannel() = 0;
60 // Terminates the worker process and closes the IPC channel.
61 virtual void KillProcess() = 0;
64 // Creates the launcher that will use |launcher_delegate| to manage the worker
65 // process and |ipc_handler| to handle IPCs. The caller must ensure that
66 // |ipc_handler| must outlive this object.
67 WorkerProcessLauncher(scoped_ptr
<Delegate
> launcher_delegate
,
68 WorkerProcessIpcDelegate
* ipc_handler
);
69 virtual ~WorkerProcessLauncher();
71 // Asks the worker process to crash and generate a dump, and closes the IPC
72 // channel. |location| is passed to the worker so that it is on the stack in
73 // the dump. Restarts the worker process forcefully, if it does
74 // not exit on its own.
75 void Crash(const tracked_objects::Location
& location
);
77 // Sends an IPC message to the worker process. The message will be silently
78 // dropped if Send() is called before Start() or after stutdown has been
80 void Send(IPC::Message
* message
);
82 // Notification methods invoked by |Delegate|.
84 // Invoked to pass a handle of the launched process back to the caller of
85 // Delegate::LaunchProcess(). The delegate has to make sure that this method
86 // is called before OnChannelConnected().
87 void OnProcessLaunched(base::win::ScopedHandle worker_process
);
89 // Called when a fatal error occurs (i.e. a failed process launch).
90 // The delegate must guarantee that no other notifications are delivered once
91 // OnFatalError() has been called.
94 // Mirrors methods of IPC::Listener to be invoked by |Delegate|. |Delegate|
95 // has to validate |peer_pid| if necessary.
96 bool OnMessageReceived(const IPC::Message
& message
);
97 void OnChannelConnected(int32 peer_pid
);
98 void OnChannelError();
101 friend class WorkerProcessLauncherTest
;
103 // base::win::ObjectWatcher::Delegate implementation used to watch for
104 // the worker process exiting.
105 virtual void OnObjectSignaled(HANDLE object
) override
;
107 // Returns true when the object is being destroyed.
108 bool stopping() const { return ipc_handler_
== nullptr; }
110 // Attempts to launch the worker process. Schedules next launch attempt if
111 // creation of the process fails.
114 // Called to record outcome of a launch attempt: success or failure.
115 void RecordLaunchResult();
117 // Called by the test to record a successful launch attempt.
118 void RecordSuccessfulLaunchForTest();
120 // Set the desired timeout for |kill_process_timer_|.
121 void SetKillProcessTimeoutForTest(const base::TimeDelta
& timeout
);
123 // Stops the worker process and schedules next launch attempt unless the
124 // object is being destroyed already.
127 // Handles IPC messages sent by the worker process.
128 WorkerProcessIpcDelegate
* ipc_handler_
;
130 // Implements specifics of launching a worker process.
131 scoped_ptr
<WorkerProcessLauncher::Delegate
> launcher_delegate_
;
133 // Keeps the exit code of the worker process after it was closed. The exit
134 // code is used to determine whether the process has to be restarted.
137 // True if IPC messages should be passed to |ipc_handler_|.
140 // The timer used to delay termination of the worker process when an IPC error
141 // occured or when Crash() request is pending
142 base::OneShotTimer
<WorkerProcessLauncher
> kill_process_timer_
;
144 // The default timeout for |kill_process_timer_|.
145 base::TimeDelta kill_process_timeout_
;
147 // State used to backoff worker launch attempts on failure.
148 net::BackoffEntry launch_backoff_
;
150 // Timer used to schedule the next attempt to launch the process.
151 base::OneShotTimer
<WorkerProcessLauncher
> launch_timer_
;
153 // Monitors |worker_process_| to detect when the launched process
155 base::win::ObjectWatcher process_watcher_
;
157 // Timer used to detect whether a launch attempt was successful or not, and to
158 // cancel the launch attempt if it is taking too long.
159 base::OneShotTimer
<WorkerProcessLauncher
> launch_result_timer_
;
161 // The handle of the worker process, if launched.
162 base::win::ScopedHandle worker_process_
;
164 DISALLOW_COPY_AND_ASSIGN(WorkerProcessLauncher
);
167 } // namespace remoting
169 #endif // REMOTING_HOST_WIN_WORKER_PROCESS_LAUNCHER_H_