summaryrefslogtreecommitdiffstats
path: root/chrome/browser/child_process_host.h
blob: e73594024fabd226c82b67c097c08f7a0862a055 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
// Copyright (c) 2009 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 CHROME_BROWSER_CHILD_PROCESS_HOST_H_
#define CHROME_BROWSER_CHILD_PROCESS_HOST_H_

#include <list>
#include <string>

// Must be included early (e.g. before chrome/common/plugin_messages.h)
#include "ipc/ipc_logging.h"

#include "base/basictypes.h"
#include "base/scoped_ptr.h"
#include "chrome/browser/child_process_launcher.h"
#include "chrome/browser/renderer_host/resource_dispatcher_host.h"
#include "ipc/ipc_channel.h"

class CommandLine;
class NotificationType;

// Plugins/workers and other child processes that live on the IO thread should
// derive from this class.
//
// [Browser]RenderProcessHost is the main exception that doesn't derive from
// this class. That project lives on the UI thread.
class ChildProcessHost : public ResourceDispatcherHost::Receiver,
                         public IPC::Channel::Listener,
                         public ChildProcessLauncher::Client {
 public:
  virtual ~ChildProcessHost();

  // Returns the pathname to be used for a child process.  If a subprocess
  // pathname was specified on the command line, that will be used.  Otherwise,
  // the default child process pathname will be returned.  On most platforms,
  // this will be the same as the currently-executing process.
  //
  // The argument allow_self is used on Linux to indicate that we allow us to
  // fork from /proc/self/exe rather than using the "real" app path. This
  // prevents autoupdate from confusing us if it changes the file out from
  // under us. You will generally want to set this to true, except when there
  // is an override to the command line (for example, we're forking a renderer
  // in gdb). In this case, you'd use GetChildPath to get the real executable
  // file name, and then prepend the GDB command to the command line.
  //
  // On failure, returns an empty FilePath.
  static FilePath GetChildPath(bool allow_self);

  // Prepares command_line for crash reporting as appropriate.  On Linux and
  // Mac, a command-line flag to enable crash reporting in the child process
  // will be appended if needed, because the child process may not have access
  // to the data that determines the status of crash reporting in the
  // currently-executing process.  This function is a no-op on Windows.
  static void SetCrashReporterCommandLine(CommandLine* command_line);

  // ResourceDispatcherHost::Receiver implementation:
  virtual bool Send(IPC::Message* msg);

  // The Iterator class allows iteration through either all child processes, or
  // ones of a specific type, depending on which constructor is used.  Note that
  // this should be done from the IO thread and that the iterator should not be
  // kept around as it may be invalidated on subsequent event processing in the
  // event loop.
  class Iterator {
   public:
    Iterator();
    explicit Iterator(ProcessType type);
    ChildProcessHost* operator->() { return *iterator_; }
    ChildProcessHost* operator*() { return *iterator_; }
    ChildProcessHost* operator++();
    bool Done();

   private:
    bool all_;
    ProcessType type_;
    std::list<ChildProcessHost*>::iterator iterator_;
  };

 protected:
  // The resource_dispatcher_host may be NULL to indicate none is needed for
  // this process type.
  ChildProcessHost(ProcessType type,
                   ResourceDispatcherHost* resource_dispatcher_host);

  // Derived classes call this to launch the child process asynchronously.
  void Launch(
#if defined(OS_WIN)
      const FilePath& exposed_dir,
#elif defined(OS_POSIX)
      bool use_zygote,
      const base::environment_vector& environ,
#endif
      CommandLine* cmd_line);

  // Derived classes return true if it's ok to shut down the child process.
  virtual bool CanShutdown() = 0;

  // Send the shutdown message to the child process, and remove this host from
  // the host list. Does not check if CanShutdown is true.
  void ForceShutdown();

  // Creates the IPC channel.  Returns true iff it succeeded.
  bool CreateChannel();

  // Notifies us that an instance has been created on this child process.
  void InstanceCreated();

  // IPC::Channel::Listener implementation:
  virtual void OnMessageReceived(const IPC::Message& msg) { }
  virtual void OnChannelConnected(int32 peer_pid) { }
  virtual void OnChannelError() { }

  // ChildProcessLauncher::Client implementation.
  virtual void OnProcessLaunched() {}

  // Derived classes can override this to know if the process crashed.
  virtual void OnProcessCrashed() {}

  bool opening_channel() { return opening_channel_; }
  const std::string& channel_id() { return channel_id_; }

  virtual bool DidChildCrash();

  // Called when the child process goes away.
  virtual void OnChildDied();

 private:
  // Sends the given notification to the notification service on the UI thread.
  void Notify(NotificationType type);

  // By using an internal class as the IPC::Channel::Listener, we can intercept
  // OnMessageReceived/OnChannelConnected and do our own processing before
  // calling the subclass' implementation.
  class ListenerHook : public IPC::Channel::Listener,
                       public ChildProcessLauncher::Client {
   public:
    explicit ListenerHook(ChildProcessHost* host);
    virtual void OnMessageReceived(const IPC::Message& msg);
    virtual void OnChannelConnected(int32 peer_pid);
    virtual void OnChannelError();
    virtual void OnProcessLaunched();
   private:
    ChildProcessHost* host_;
  };

  ListenerHook listener_;

  // May be NULL if this current process has no resource dispatcher host.
  ResourceDispatcherHost* resource_dispatcher_host_;

  bool opening_channel_;  // True while we're waiting the channel to be opened.
  scoped_ptr<IPC::Channel> channel_;
  std::string channel_id_;
  scoped_ptr<ChildProcessLauncher> child_process_;
};

#endif  // CHROME_BROWSER_CHILD_PROCESS_HOST_H_