OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "mojo/edk/system/raw_channel.h" | 5 #include "mojo/edk/system/raw_channel.h" |
6 | 6 |
7 #include <windows.h> | 7 #include <windows.h> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
11 #include "base/location.h" | 11 #include "base/location.h" |
12 #include "base/logging.h" | 12 #include "base/logging.h" |
13 #include "base/memory/scoped_ptr.h" | 13 #include "base/memory/scoped_ptr.h" |
14 #include "base/message_loop/message_loop.h" | 14 #include "base/message_loop/message_loop.h" |
15 #include "base/process/process.h" | 15 #include "base/process/process.h" |
16 #include "base/synchronization/lock.h" | 16 #include "base/synchronization/lock.h" |
| 17 #include "base/synchronization/waitable_event.h" |
17 #include "base/win/scoped_handle.h" | 18 #include "base/win/scoped_handle.h" |
18 #include "base/win/windows_version.h" | 19 #include "base/win/windows_version.h" |
19 #include "mojo/edk/embedder/embedder_internal.h" | 20 #include "mojo/edk/embedder/embedder_internal.h" |
20 #include "mojo/edk/embedder/platform_handle.h" | 21 #include "mojo/edk/embedder/platform_handle.h" |
21 #include "mojo/edk/system/transport_data.h" | 22 #include "mojo/edk/system/transport_data.h" |
22 #include "mojo/public/cpp/system/macros.h" | 23 #include "mojo/public/cpp/system/macros.h" |
23 | 24 |
24 #define STATUS_CANCELLED 0xC0000120 | 25 #define STATUS_CANCELLED 0xC0000120 |
25 #define STATUS_PIPE_BROKEN 0xC000014B | 26 #define STATUS_PIPE_BROKEN 0xC000014B |
26 | 27 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 HANDLE, FILE_INFO_BY_HANDLE_CLASS, LPVOID, DWORD); | 76 HANDLE, FILE_INFO_BY_HANDLE_CLASS, LPVOID, DWORD); |
76 | 77 |
77 bool is_vista_or_higher_; | 78 bool is_vista_or_higher_; |
78 CancelIoExFunc cancel_io_ex_; | 79 CancelIoExFunc cancel_io_ex_; |
79 GetFileInformationByHandleExFunc get_file_information_by_handle_ex_; | 80 GetFileInformationByHandleExFunc get_file_information_by_handle_ex_; |
80 }; | 81 }; |
81 | 82 |
82 base::LazyInstance<VistaOrHigherFunctions> g_vista_or_higher_functions = | 83 base::LazyInstance<VistaOrHigherFunctions> g_vista_or_higher_functions = |
83 LAZY_INSTANCE_INITIALIZER; | 84 LAZY_INSTANCE_INITIALIZER; |
84 | 85 |
| 86 void CancelOnIO(HANDLE handle, base::WaitableEvent* event) { |
| 87 CancelIo(handle); |
| 88 event->Signal(); |
| 89 } |
| 90 |
85 class RawChannelWin final : public RawChannel { | 91 class RawChannelWin final : public RawChannel { |
86 public: | 92 public: |
87 RawChannelWin(ScopedPlatformHandle handle) | 93 RawChannelWin(ScopedPlatformHandle handle) |
88 : handle_(handle.Pass()), io_handler_(nullptr) { | 94 : handle_(handle.Pass()), io_handler_(nullptr) { |
89 DCHECK(handle_.is_valid()); | 95 DCHECK(handle_.is_valid()); |
90 } | 96 } |
91 ~RawChannelWin() override { | 97 ~RawChannelWin() override { |
92 DCHECK(!io_handler_); | 98 DCHECK(!io_handler_); |
93 } | 99 } |
94 | 100 |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 owner_ = nullptr; | 229 owner_ = nullptr; |
224 if (ShouldSelfDestruct()) | 230 if (ShouldSelfDestruct()) |
225 delete this; | 231 delete this; |
226 } | 232 } |
227 | 233 |
228 ScopedPlatformHandle ReleaseHandle( | 234 ScopedPlatformHandle ReleaseHandle( |
229 std::vector<char>* serialized_read_buffer, | 235 std::vector<char>* serialized_read_buffer, |
230 std::vector<char>* serialized_write_buffer, | 236 std::vector<char>* serialized_write_buffer, |
231 bool* write_error) { | 237 bool* write_error) { |
232 // Cancel pending IO calls. | 238 // Cancel pending IO calls. |
| 239 bool is_xp = false; |
233 if (g_vista_or_higher_functions.Get().is_vista_or_higher()) { | 240 if (g_vista_or_higher_functions.Get().is_vista_or_higher()) { |
234 g_vista_or_higher_functions.Get().CancelIoEx(handle(), nullptr); | 241 g_vista_or_higher_functions.Get().CancelIoEx(handle(), nullptr); |
235 } else { | 242 } else { |
236 CHECK(false) << "TODO(jam): handle XP"; | 243 is_xp = true; |
| 244 if (pending_read_) { |
| 245 if (internal::g_io_thread_task_runner->RunsTasksOnCurrentThread()) { |
| 246 CancelIo(handle()); |
| 247 } else { |
| 248 base::WaitableEvent event(false, false); |
| 249 internal::g_io_thread_task_runner->PostTask( |
| 250 FROM_HERE, |
| 251 base::Bind(&CancelOnIO, handle(), &event)); |
| 252 event.Wait(); |
| 253 } |
| 254 } |
237 } | 255 } |
238 | 256 |
239 size_t additional_bytes_read = 0; | 257 size_t additional_bytes_read = 0; |
240 bool got_read_error = false; | 258 bool got_read_error = false; |
241 if (pending_read_) { | 259 if (pending_read_) { |
242 bool wait = false; | 260 bool wait = false; |
243 UnregisterWaitEx(read_wait_object_, INVALID_HANDLE_VALUE); | 261 UnregisterWaitEx(read_wait_object_, INVALID_HANDLE_VALUE); |
244 read_wait_object_ = NULL; | 262 read_wait_object_ = NULL; |
245 if (!read_event_signalled_) | 263 if (!read_event_signalled_) |
246 wait = true; | 264 wait = true; |
(...skipping 16 matching lines...) Expand all Loading... |
263 } | 281 } |
264 pending_read_ = false; | 282 pending_read_ = false; |
265 } | 283 } |
266 | 284 |
267 RawChannel::WriteBuffer* write_buffer = owner_->write_buffer_no_lock(); | 285 RawChannel::WriteBuffer* write_buffer = owner_->write_buffer_no_lock(); |
268 | 286 |
269 size_t additional_bytes_written = 0; | 287 size_t additional_bytes_written = 0; |
270 size_t additional_platform_handles_written = 0; | 288 size_t additional_platform_handles_written = 0; |
271 *write_error = owner_->pending_write_error(); | 289 *write_error = owner_->pending_write_error(); |
272 if (pending_write_) { | 290 if (pending_write_) { |
273 bool wait = false; | 291 // If we had a pending write, then on XP we just wait till it completes. |
| 292 // We use limited size buffers, so Windows should always find paged pool |
| 293 // memory to finish the writes. |
| 294 // TODO(jam): use background thread to verify that we don't hang here? |
| 295 bool wait = is_xp; |
274 UnregisterWaitEx(write_wait_object_, INVALID_HANDLE_VALUE); | 296 UnregisterWaitEx(write_wait_object_, INVALID_HANDLE_VALUE); |
275 write_wait_object_ = NULL; | 297 write_wait_object_ = NULL; |
276 if (!write_event_signalled_) | 298 if (!write_event_signalled_) |
277 wait = true; | 299 wait = true; |
278 | 300 |
279 DWORD bytes_written_dword = 0; | 301 DWORD bytes_written_dword = 0; |
280 | 302 |
281 // See comment above. | 303 // See comment above. |
282 BOOL rv = GetOverlappedResult( | 304 BOOL rv = GetOverlappedResult( |
283 handle(), &write_context_.overlapped, &bytes_written_dword, | 305 handle(), &write_context_.overlapped, &bytes_written_dword, |
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
770 FILE_NAME_INFO* fileinfo1 = reinterpret_cast<FILE_NAME_INFO *>(data1); | 792 FILE_NAME_INFO* fileinfo1 = reinterpret_cast<FILE_NAME_INFO *>(data1); |
771 FILE_NAME_INFO* fileinfo2 = reinterpret_cast<FILE_NAME_INFO *>(data2); | 793 FILE_NAME_INFO* fileinfo2 = reinterpret_cast<FILE_NAME_INFO *>(data2); |
772 CHECK(g_vista_or_higher_functions.Get().GetFileInformationByHandleEx( | 794 CHECK(g_vista_or_higher_functions.Get().GetFileInformationByHandleEx( |
773 this_handle.handle, FileNameInfo, fileinfo1, arraysize(data1))); | 795 this_handle.handle, FileNameInfo, fileinfo1, arraysize(data1))); |
774 CHECK(g_vista_or_higher_functions.Get().GetFileInformationByHandleEx( | 796 CHECK(g_vista_or_higher_functions.Get().GetFileInformationByHandleEx( |
775 other_handle.handle, FileNameInfo, fileinfo2, arraysize(data2))); | 797 other_handle.handle, FileNameInfo, fileinfo2, arraysize(data2))); |
776 std::wstring filepath1(fileinfo1->FileName, fileinfo1->FileNameLength / 2); | 798 std::wstring filepath1(fileinfo1->FileName, fileinfo1->FileNameLength / 2); |
777 std::wstring filepath2(fileinfo2->FileName, fileinfo2->FileNameLength / 2); | 799 std::wstring filepath2(fileinfo2->FileName, fileinfo2->FileNameLength / 2); |
778 return filepath1 == filepath2; | 800 return filepath1 == filepath2; |
779 } else { | 801 } else { |
780 // TODO: XP: see http://stackoverflow.com/questions/65170/how-to-get-name-as
sociated-with-open-handle/5286888#5286888 | 802 // This is to catch developer errors. Let them be caught on Vista and above, |
781 CHECK(false) << "TODO(jam): handle XP"; | 803 // i.e. no point in implementing this on XP since support for it will be |
| 804 // removed in early 2016. |
782 return false; | 805 return false; |
783 } | 806 } |
784 } | 807 } |
785 | 808 |
786 } // namespace edk | 809 } // namespace edk |
787 } // namespace mojo | 810 } // namespace mojo |
OLD | NEW |