Chromium Code Reviews| 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 |