Chromium Code Reviews| Index: sandbox/win/src/handle_closer_agent.cc |
| diff --git a/sandbox/win/src/handle_closer_agent.cc b/sandbox/win/src/handle_closer_agent.cc |
| index 07c6a09854d2d5355a84f30f782ec57f1a04f3ab..179b173b0aa546aa684b4674dae9212a8330daa5 100644 |
| --- a/sandbox/win/src/handle_closer_agent.cc |
| +++ b/sandbox/win/src/handle_closer_agent.cc |
| @@ -41,6 +41,46 @@ bool HandleCloserAgent::NeedsHandlesClosed() { |
| return g_handles_to_close != NULL; |
| } |
| +HandleCloserAgent::HandleCloserAgent() |
| + : dummy_handle_(::CreateEvent(NULL, FALSE, FALSE, NULL)) { |
| +} |
| + |
|
cpu_(ooo_6.6-7.5)
2015/02/19 00:10:02
write a comment here about the technique including
|
| +bool HandleCloserAgent::AttemptToStuffHandleSlot(HANDLE closed_handle, |
| + const base::string16& type) { |
| + // Only attempt to stuff Files and Events at the moment. |
| + if (type != L"Event" && type != L"File") { |
| + return true; |
| + } |
| + |
| + if (!dummy_handle_.IsValid()) |
| + return false; |
| + |
| + // This should never happen, as g_dummy is created before closing to_stuff. |
| + DCHECK(dummy_handle_.Get() != closed_handle); |
| + |
| + std::vector<HANDLE> to_close; |
| + HANDLE dup_dummy = NULL; |
| + size_t count = 16; |
| + |
| + do { |
| + if (!::DuplicateHandle(::GetCurrentProcess(), dummy_handle_.Get(), |
| + ::GetCurrentProcess(), &dup_dummy, 0, FALSE, 0)) |
| + break; |
| + if (dup_dummy != closed_handle) |
| + to_close.push_back(dup_dummy); |
| + } while (count-- && |
| + reinterpret_cast<uintptr_t>(dup_dummy) < |
| + reinterpret_cast<uintptr_t>(closed_handle)); |
| + |
| + for (auto h : to_close) |
| + ::CloseHandle(h); |
| + |
| + // Useful to know when we're not able to stuff handles. |
| + DCHECK(dup_dummy == closed_handle); |
| + |
| + return dup_dummy == closed_handle; |
| +} |
| + |
| // Reads g_handles_to_close and creates the lookup map. |
| void HandleCloserAgent::InitializeHandlesToClose() { |
| CHECK(g_handles_to_close != NULL); |
| @@ -136,6 +176,8 @@ bool HandleCloserAgent::CloseHandles() { |
| return false; |
| if (!::CloseHandle(handle)) |
| return false; |
| + // Attempt to stuff this handle with a new dummy Event. |
| + AttemptToStuffHandleSlot(handle, result->first); |
| } |
| } |