OLD | NEW |
---|---|
1 // Copyright 2015 The Crashpad Authors. All rights reserved. | 1 // Copyright 2015 The Crashpad Authors. All rights reserved. |
2 // | 2 // |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
4 // you may not use this file except in compliance with the License. | 4 // you may not use this file except in compliance with the License. |
5 // You may obtain a copy of the License at | 5 // You may obtain a copy of the License at |
6 // | 6 // |
7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
8 // | 8 // |
9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 // See the License for the specific language governing permissions and | 12 // See the License for the specific language governing permissions and |
13 // limitations under the License. | 13 // limitations under the License. |
14 | 14 |
15 #ifndef CRASHPAD_TEST_WIN_WIN_MULTIPROCESS_H_ | 15 #ifndef CRASHPAD_TEST_WIN_WIN_MULTIPROCESS_H_ |
16 #define CRASHPAD_TEST_WIN_WIN_MULTIPROCESS_H_ | 16 #define CRASHPAD_TEST_WIN_WIN_MULTIPROCESS_H_ |
17 | 17 |
18 #include <windows.h> | 18 #include <windows.h> |
19 | 19 |
20 #include "base/basictypes.h" | 20 #include "base/basictypes.h" |
21 #include "gtest/gtest.h" | |
22 #include "test/win/win_child_process.h" | |
21 #include "util/file/file_io.h" | 23 #include "util/file/file_io.h" |
22 #include "util/win/scoped_handle.h" | 24 #include "util/win/scoped_handle.h" |
23 | 25 |
24 namespace crashpad { | 26 namespace crashpad { |
25 namespace test { | 27 namespace test { |
26 | 28 |
27 //! \brief Manages a multiprocess test on Windows. | 29 //! \brief Manages a multiprocess test on Windows. |
28 class WinMultiprocess { | 30 class WinMultiprocess { |
29 public: | 31 public: |
30 WinMultiprocess(); | 32 WinMultiprocess(); |
31 | 33 |
32 //! \brief Runs the test. | 34 //! \brief Runs the test. |
33 //! | 35 //! |
34 //! This method establishes the testing environment by respawning the process | 36 //! This method establishes the testing environment by respawning the process |
35 //! as a child with additional flags. | 37 //! as a child with additional flags. |
36 //! | 38 //! |
37 //! In the parent process, WinMultiprocessParent() is run, and in the child | 39 //! In the parent process, WinMultiprocessParent() is run, and in the child |
38 //! WinMultiprocessChild(). | 40 //! WinMultiprocessChild(). |
39 void Run(); | 41 template <class T> |
42 static void Run() { | |
43 ASSERT_NO_FATAL_FAILURE( | |
44 WinChildProcess::EntryPoint<ChildProcessHelper<T>>()); | |
45 // If WinChildProcess::EntryPoint returns, we are in the parent process. | |
46 scoped_ptr<WinChildProcess::Handles> child_handles = WinChildProcess::Launch (); | |
scottmg
2015/06/01 21:53:22
80 col
erikwright (departed)
2015/06/24 20:01:35
Done.
| |
47 ASSERT_TRUE(child_handles.get()); | |
48 T parent_process; | |
49 parent_process.child_handles_ = child_handles.get(); | |
50 static_cast<WinMultiprocess*>(&parent_process)->WinMultiprocessParent(); | |
51 } | |
40 | 52 |
41 protected: | 53 protected: |
42 virtual ~WinMultiprocess(); | 54 virtual ~WinMultiprocess(); |
43 | 55 |
44 //! \brief Returns the read pipe's file handle. | 56 //! \brief Returns the read pipe's file handle. |
45 //! | 57 //! |
46 //! This method may be called by either the parent or the child process. | 58 //! This method may be called by either the parent or the child process. |
47 //! Anything written to the write pipe in the partner process will appear | 59 //! Anything written to the write pipe in the partner process will appear |
48 //! on this file handle in this process. | 60 //! on this file handle in this process. |
49 //! | 61 //! |
(...skipping 25 matching lines...) Expand all Loading... | |
75 //! attempt to read from the read pipe in the partner process will indicate | 87 //! attempt to read from the read pipe in the partner process will indicate |
76 //! end-of-file. WritePipeHandle() must not be called after this. | 88 //! end-of-file. WritePipeHandle() must not be called after this. |
77 void CloseWritePipe(); | 89 void CloseWritePipe(); |
78 | 90 |
79 //! \brief Returns a handle to the child process. | 91 //! \brief Returns a handle to the child process. |
80 //! | 92 //! |
81 //! This method may only be called by the parent process. | 93 //! This method may only be called by the parent process. |
82 HANDLE ChildProcess() const; | 94 HANDLE ChildProcess() const; |
83 | 95 |
84 private: | 96 private: |
97 // Implements an adapter to provide WinMultiprocess with access to the | |
98 // anonymous pipe handles from WinChildProcess. | |
99 class ChildProcessHelperBase : public WinChildProcess { | |
100 public: | |
101 ChildProcessHelperBase() {} | |
102 ~ChildProcessHelperBase() override {} | |
103 | |
104 void CloseWritePipeForwarder() { CloseWritePipe(); } | |
105 void CloseReadPipeForwarder() { CloseReadPipe(); } | |
106 FileHandle ReadPipeHandleForwarder() const { return ReadPipeHandle(); } | |
107 FileHandle WritePipeHandleForwarder() const { return WritePipeHandle(); } | |
108 | |
109 private: | |
110 DISALLOW_COPY_AND_ASSIGN(ChildProcessHelperBase); | |
111 }; | |
112 | |
113 // Forwards WinChildProcess::Run to T::WinMultiprocessChild. | |
114 template <class T> | |
115 class ChildProcessHelper : public ChildProcessHelperBase { | |
116 public: | |
117 ChildProcessHelper() {} | |
118 ~ChildProcessHelper() override {} | |
119 | |
120 private: | |
121 void Run() override { | |
122 T child_process; | |
123 child_process.child_process_helper_ = this; | |
124 static_cast<WinMultiprocess*>(&child_process)->WinMultiprocessChild(); | |
125 exit(0); | |
126 } | |
127 | |
128 DISALLOW_COPY_AND_ASSIGN(ChildProcessHelper); | |
129 }; | |
130 | |
85 //! \brief The subclass-provided parent routine. | 131 //! \brief The subclass-provided parent routine. |
86 //! | 132 //! |
87 //! Test failures should be reported via gtest: `EXPECT_*()`, `ASSERT_*()`, | 133 //! Test failures should be reported via gtest: `EXPECT_*()`, `ASSERT_*()`, |
88 //! `FAIL()`, etc. | 134 //! `FAIL()`, etc. |
89 //! | 135 //! |
90 //! This method must not use `WaitForSingleObject()`-family call to wait for | 136 //! This method must not use `WaitForSingleObject()`-family call to wait for |
91 //! the child process to exit, as this is handled by this class. | 137 //! the child process to exit, as this is handled by this class. |
92 //! | 138 //! |
93 //! Subclasses must implement this method to define how the parent operates. | 139 //! Subclasses must implement this method to define how the parent operates. |
94 virtual void WinMultiprocessParent() = 0; | 140 virtual void |
scottmg
2015/06/01 21:53:22
extra \n
erikwright (departed)
2015/06/24 20:01:35
Done.
| |
141 WinMultiprocessParent() = 0; | |
95 | 142 |
96 //! \brief The subclass-provided child routine. | 143 //! \brief The subclass-provided child routine. |
97 //! | 144 //! |
98 //! Test failures should be reported via gtest: `EXPECT_*()`, `ASSERT_*()`, | 145 //! Test failures should be reported via gtest: `EXPECT_*()`, `ASSERT_*()`, |
99 //! `FAIL()`, etc. | 146 //! `FAIL()`, etc. |
100 //! | 147 //! |
101 //! Subclasses must implement this method to define how the child operates. | 148 //! Subclasses must implement this method to define how the child operates. |
102 //! Subclasses may exit with a failure status by using `LOG(FATAL)`, | 149 //! Subclasses may exit with a failure status by using `LOG(FATAL)`, |
103 //! `abort()`, or similar. They may exit cleanly by returning from this | 150 //! `abort()`, or similar. They may exit cleanly by returning from this |
104 //! method. | 151 //! method. |
105 virtual void WinMultiprocessChild() = 0; | 152 virtual void WinMultiprocessChild() = 0; |
106 | 153 |
107 ScopedFileHANDLE pipe_c2p_read_; | 154 WinChildProcess::Handles* child_handles_; |
108 ScopedFileHANDLE pipe_c2p_write_; | 155 ChildProcessHelperBase* child_process_helper_; |
109 ScopedFileHANDLE pipe_p2c_read_; | |
110 ScopedFileHANDLE pipe_p2c_write_; | |
111 ScopedKernelHANDLE child_handle_; | |
112 | 156 |
113 DISALLOW_COPY_AND_ASSIGN(WinMultiprocess); | 157 DISALLOW_COPY_AND_ASSIGN(WinMultiprocess); |
114 }; | 158 }; |
115 | 159 |
116 } // namespace test | 160 } // namespace test |
117 } // namespace crashpad | 161 } // namespace crashpad |
118 | 162 |
119 #endif // CRASHPAD_TEST_WIN_WIN_MULTIPROCESS_H_ | 163 #endif // CRASHPAD_TEST_WIN_WIN_MULTIPROCESS_H_ |
OLD | NEW |