Home | History | Annotate | Download | only in win
      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.
      4 
      5 #ifndef REMOTING_HOST_WIN_WORKER_PROCESS_LAUNCHER_H_
      6 #define REMOTING_HOST_WIN_WORKER_PROCESS_LAUNCHER_H_
      7 
      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"
     18 
     19 namespace base {
     20 class SingleThreadTaskRunner;
     21 class TimeDelta;
     22 } // namespace base
     23 
     24 namespace IPC {
     25 class Message;
     26 } // namespace IPC
     27 
     28 namespace tracked_objects {
     29 class Location;
     30 }  // namespace tracked_objects
     31 
     32 namespace remoting {
     33 
     34 class WorkerProcessIpcDelegate;
     35 
     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
     39 // is terminated.
     40 class WorkerProcessLauncher
     41     : public base::NonThreadSafe,
     42       public base::win::ObjectWatcher::Delegate {
     43  public:
     44   class Delegate {
     45    public:
     46     virtual ~Delegate();
     47 
     48     // Asynchronously starts the worker process and creates an IPC channel it
     49     // can connect to. |event_handler| must remain valid until KillProcess() has
     50     // been called.
     51     virtual void LaunchProcess(WorkerProcessLauncher* event_handler) = 0;
     52 
     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;
     56 
     57     // Closes the IPC channel.
     58     virtual void CloseChannel() = 0;
     59 
     60     // Terminates the worker process and closes the IPC channel.
     61     virtual void KillProcess() = 0;
     62   };
     63 
     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();
     70 
     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);
     76 
     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
     79   // initiated.
     80   void Send(IPC::Message* message);
     81 
     82   // Notification methods invoked by |Delegate|.
     83 
     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);
     88 
     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.
     92   void OnFatalError();
     93 
     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();
     99 
    100  private:
    101   friend class WorkerProcessLauncherTest;
    102 
    103   // base::win::ObjectWatcher::Delegate implementation used to watch for
    104   // the worker process exiting.
    105   virtual void OnObjectSignaled(HANDLE object) OVERRIDE;
    106 
    107   // Returns true when the object is being destroyed.
    108   bool stopping() const { return ipc_handler_ == NULL; }
    109 
    110   // Attempts to launch the worker process. Schedules next launch attempt if
    111   // creation of the process fails.
    112   void LaunchWorker();
    113 
    114   // Called to record outcome of a launch attempt: success or failure.
    115   void RecordLaunchResult();
    116 
    117   // Called by the test to record a successful launch attempt.
    118   void RecordSuccessfulLaunchForTest();
    119 
    120   // Set the desired timeout for |kill_process_timer_|.
    121   void SetKillProcessTimeoutForTest(const base::TimeDelta& timeout);
    122 
    123   // Stops the worker process and schedules next launch attempt unless the
    124   // object is being destroyed already.
    125   void StopWorker();
    126 
    127   // Handles IPC messages sent by the worker process.
    128   WorkerProcessIpcDelegate* ipc_handler_;
    129 
    130   // Implements specifics of launching a worker process.
    131   scoped_ptr<WorkerProcessLauncher::Delegate> launcher_delegate_;
    132 
    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.
    135   DWORD exit_code_;
    136 
    137   // True if IPC messages should be passed to |ipc_handler_|.
    138   bool ipc_enabled_;
    139 
    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_;
    143 
    144   // The default timeout for |kill_process_timer_|.
    145   base::TimeDelta kill_process_timeout_;
    146 
    147   // State used to backoff worker launch attempts on failure.
    148   net::BackoffEntry launch_backoff_;
    149 
    150   // Timer used to schedule the next attempt to launch the process.
    151   base::OneShotTimer<WorkerProcessLauncher> launch_timer_;
    152 
    153   // Monitors |worker_process_| to detect when the launched process
    154   // terminates.
    155   base::win::ObjectWatcher process_watcher_;
    156 
    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_;
    160 
    161   // The handle of the worker process, if launched.
    162   base::win::ScopedHandle worker_process_;
    163 
    164   DISALLOW_COPY_AND_ASSIGN(WorkerProcessLauncher);
    165 };
    166 
    167 }  // namespace remoting
    168 
    169 #endif  // REMOTING_HOST_WIN_WORKER_PROCESS_LAUNCHER_H_
    170