|
1 // Copyright (c) 2009 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 CHROME_COMMON_CHILD_PROCESS_HOST_H_ |
|
6 #define CHROME_COMMON_CHILD_PROCESS_HOST_H_ |
|
7 |
|
8 #include "build/build_config.h" |
|
9 |
|
10 #include <list> |
|
11 |
|
12 #include "base/basictypes.h" |
|
13 #include "base/scoped_ptr.h" |
|
14 #include "base/waitable_event_watcher.h" |
|
15 #include "chrome/common/child_process_info.h" |
|
16 #include "chrome/common/ipc_channel.h" |
|
17 |
|
18 namespace mozilla { |
|
19 namespace ipc { |
|
20 class FileDescriptor; |
|
21 } |
|
22 } |
|
23 |
|
24 class NotificationType; |
|
25 |
|
26 // Plugins/workers and other child processes that live on the IO thread should |
|
27 // derive from this class. |
|
28 class ChildProcessHost : |
|
29 public IPC::Message::Sender, |
|
30 public ChildProcessInfo, |
|
31 public base::WaitableEventWatcher::Delegate, |
|
32 public IPC::Channel::Listener { |
|
33 public: |
|
34 virtual ~ChildProcessHost(); |
|
35 |
|
36 // ResourceDispatcherHost::Receiver implementation: |
|
37 virtual bool Send(IPC::Message* msg); |
|
38 |
|
39 // The Iterator class allows iteration through either all child processes, or |
|
40 // ones of a specific type, depending on which constructor is used. Note that |
|
41 // this should be done from the IO thread and that the iterator should not be |
|
42 // kept around as it may be invalidated on subsequent event processing in the |
|
43 // event loop. |
|
44 class Iterator { |
|
45 public: |
|
46 Iterator(); |
|
47 Iterator(ProcessType type); |
|
48 ChildProcessHost* operator->() { return *iterator_; } |
|
49 ChildProcessHost* operator*() { return *iterator_; } |
|
50 ChildProcessHost* operator++(); |
|
51 bool Done(); |
|
52 |
|
53 private: |
|
54 bool all_; |
|
55 ProcessType type_; |
|
56 std::list<ChildProcessHost*>::iterator iterator_; |
|
57 }; |
|
58 |
|
59 protected: |
|
60 explicit ChildProcessHost(ProcessType type); |
|
61 |
|
62 // Derived classes return true if it's ok to shut down the child process. |
|
63 virtual bool CanShutdown() = 0; |
|
64 |
|
65 // Creates the IPC channel. Returns true iff it succeeded. |
|
66 bool CreateChannel(); |
|
67 |
|
68 bool CreateChannel(mozilla::ipc::FileDescriptor& aFileDescriptor); |
|
69 |
|
70 // Once the subclass gets a handle to the process, it needs to tell |
|
71 // ChildProcessHost using this function. |
|
72 void SetHandle(base::ProcessHandle handle); |
|
73 |
|
74 // Notifies us that an instance has been created on this child process. |
|
75 void InstanceCreated(); |
|
76 |
|
77 // IPC::Channel::Listener implementation: |
|
78 virtual void OnMessageReceived(const IPC::Message& msg) { } |
|
79 virtual void OnChannelConnected(int32_t peer_pid) { } |
|
80 virtual void OnChannelError() { } |
|
81 |
|
82 bool opening_channel() { return opening_channel_; } |
|
83 const std::wstring& channel_id() { return channel_id_; } |
|
84 |
|
85 base::WaitableEvent* GetProcessEvent() { return process_event_.get(); } |
|
86 |
|
87 const IPC::Channel& channel() const { return *channel_; } |
|
88 IPC::Channel* channelp() const { return channel_.get(); } |
|
89 |
|
90 private: |
|
91 // Sends the given notification to the notification service on the UI thread. |
|
92 void Notify(NotificationType type); |
|
93 |
|
94 protected: |
|
95 // WaitableEventWatcher::Delegate implementation: |
|
96 virtual void OnWaitableEventSignaled(base::WaitableEvent *event); |
|
97 |
|
98 private: |
|
99 // By using an internal class as the IPC::Channel::Listener, we can intercept |
|
100 // OnMessageReceived/OnChannelConnected and do our own processing before |
|
101 // calling the subclass' implementation. |
|
102 class ListenerHook : public IPC::Channel::Listener { |
|
103 public: |
|
104 ListenerHook(ChildProcessHost* host); |
|
105 virtual void OnMessageReceived(const IPC::Message& msg); |
|
106 virtual void OnChannelConnected(int32_t peer_pid); |
|
107 virtual void OnChannelError(); |
|
108 virtual void GetQueuedMessages(std::queue<IPC::Message>& queue); |
|
109 private: |
|
110 ChildProcessHost* host_; |
|
111 }; |
|
112 |
|
113 ListenerHook listener_; |
|
114 |
|
115 // True while we're waiting the channel to be opened. |
|
116 bool opening_channel_; |
|
117 |
|
118 // The IPC::Channel. |
|
119 scoped_ptr<IPC::Channel> channel_; |
|
120 |
|
121 // IPC Channel's id. |
|
122 std::wstring channel_id_; |
|
123 |
|
124 // Used to watch the child process handle. |
|
125 base::WaitableEventWatcher watcher_; |
|
126 |
|
127 scoped_ptr<base::WaitableEvent> process_event_; |
|
128 }; |
|
129 |
|
130 #endif // CHROME_COMMON_CHILD_PROCESS_HOST_H_ |