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); |
} |
} |