Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(344)

Side by Side Diff: ceee/ie/broker/executors_manager.cc

Issue 5622001: Make sure we don't keep tab id - handles mapping when a dread dies.... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 10 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ceee/ie/broker/executors_manager.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 // ExecutorsManager implementation. 5 // ExecutorsManager implementation.
6 6
7 #include "ceee/ie/broker/executors_manager.h" 7 #include "ceee/ie/broker/executors_manager.h"
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "ceee/ie/broker/broker_module_util.h" 10 #include "ceee/ie/broker/broker_module_util.h"
11 #include "ceee/ie/broker/chrome_postman.h"
11 #include "ceee/ie/broker/common_api_module.h" 12 #include "ceee/ie/broker/common_api_module.h"
12 #include "ceee/common/com_utils.h" 13 #include "ceee/common/com_utils.h"
13 14
14 namespace { 15 namespace {
15 16
16 // The timeout we set before accepting a failure when we wait for events. 17 // The timeout we set before accepting a failure when we wait for events.
17 const DWORD kTimeOut = 20000; 18 const DWORD kTimeOut = 20000;
18 19
19 // Utility class to ensure the setting of an event before we exit a method. 20 // Utility class to ensure the setting of an event before we exit a method.
20 class AutoSetEvent { 21 class AutoSetEvent {
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 } 186 }
186 187
187 // Update the list of handles that our thread is waiting on. 188 // Update the list of handles that our thread is waiting on.
188 BOOL success = ::SetEvent(update_threads_list_gate_); 189 BOOL success = ::SetEvent(update_threads_list_gate_);
189 DCHECK(success); 190 DCHECK(success);
190 return S_OK; 191 return S_OK;
191 } 192 }
192 193
193 HRESULT ExecutorsManager::GetExecutor(ThreadId thread_id, HWND window, 194 HRESULT ExecutorsManager::GetExecutor(ThreadId thread_id, HWND window,
194 REFIID riid, void** executor) { 195 REFIID riid, void** executor) {
196 VLOG(1) << "Thread: " << thread_id << ", window: " << window;
195 DCHECK(executor != NULL); 197 DCHECK(executor != NULL);
196 // We may need to wait for either a currently pending 198 // We may need to wait for either a currently pending
197 // or own newly created registration of a new executor. 199 // or own newly created registration of a new executor.
198 CHandle executor_registration_gate; 200 CHandle executor_registration_gate;
199 201
200 // We need to remember if we must create a new one or not. 202 // We need to remember if we must create a new one or not.
201 // But we must create the executor creator outside of the lock. 203 // But we must create the executor creator outside of the lock.
202 bool create_executor = false; 204 bool create_executor = false;
203 { 205 {
204 AutoLock lock(lock_); 206 AutoLock lock(lock_);
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 HWND frame_window = window_utils::GetTopLevelParent(handle); 394 HWND frame_window = window_utils::GetTopLevelParent(handle);
393 // There are cases where it's too late to get the parent, 395 // There are cases where it's too late to get the parent,
394 // so we will need to dig for it deeper later. 396 // so we will need to dig for it deeper later.
395 if (!common_api::CommonApiResult::IsIeFrameClass(frame_window)) 397 if (!common_api::CommonApiResult::IsIeFrameClass(frame_window))
396 frame_window = NULL; 398 frame_window = NULL;
397 399
398 bool send_on_removed = false; 400 bool send_on_removed = false;
399 AutoLock lock(lock_); 401 AutoLock lock(lock_);
400 { 402 {
401 HandleMap::iterator handle_it = handle_map_.find(handle); 403 HandleMap::iterator handle_it = handle_map_.find(handle);
402 DCHECK(handle_map_.end() != handle_it); 404 // Don't DCHECK, we may be called more than once, but it's fine,
405 // we just ignore subsequent calls.
403 if (handle_map_.end() != handle_it) { 406 if (handle_map_.end() != handle_it) {
404 TabIdMap::iterator tab_id_it = tab_id_map_.find(handle_it->second); 407 TabIdMap::iterator tab_id_it = tab_id_map_.find(handle_it->second);
408 // But if we have it in one map, we must have it in the reverse map.
405 DCHECK(tab_id_map_.end() != tab_id_it); 409 DCHECK(tab_id_map_.end() != tab_id_it);
406 if (tab_id_map_.end() != tab_id_it) { 410 if (tab_id_map_.end() != tab_id_it) {
407 #ifdef DEBUG 411 #ifdef DEBUG
408 tab_id_map_[handle_it->second] = 412 tab_id_map_[handle_it->second] =
409 reinterpret_cast<HWND>(INVALID_HANDLE_VALUE); 413 reinterpret_cast<HWND>(INVALID_HANDLE_VALUE);
410 handle_map_[handle] = kInvalidChromeSessionId; 414 handle_map_[handle] = kInvalidChromeSessionId;
411 #else 415 #else
412 tab_id_map_.erase(handle_it->second); 416 tab_id_map_.erase(handle_it->second);
413 handle_map_.erase(handle); 417 handle_map_.erase(handle);
414 #endif // DEBUG 418 #endif // DEBUG
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
456 frame_window_families_.erase(frame_window); 460 frame_window_families_.erase(frame_window);
457 send_on_removed = true; 461 send_on_removed = true;
458 } 462 }
459 } // End of lock 463 } // End of lock
460 464
461 // Safer to send notifications outside of our lock. 465 // Safer to send notifications outside of our lock.
462 if (send_on_removed) 466 if (send_on_removed)
463 windows_events_funnel().OnRemoved(frame_window); 467 windows_events_funnel().OnRemoved(frame_window);
464 } 468 }
465 469
470 // This is for using CleanupMapsForThread() into a runnable object without
471 // the need to AddRef/Release the ExecutorsManager which is a Singleton.
472 DISABLE_RUNNABLE_METHOD_REFCOUNT(ExecutorsManager);
473
474 void ExecutorsManager::CleanupMapsForThread(DWORD thread_id) {
475 // We collect the tab handles to remove so that we can do it outside of lock.
476 // This is because 1) it's not trivial to do it while we loop through the map,
477 // since there are multiple maps to deal with and the DeleteHandle takes care
478 // of that for us, and 2) we can't call DeleteHandle from within a lock.
479 std::vector<HWND> tab_handles_to_remove;
480 {
481 AutoLock lock(lock_);
482 HandleMap::iterator handle_it = handle_map_.begin();
483 for (; handle_it != handle_map_.end(); ++ handle_it) {
484 if (::GetWindowThreadProcessId(handle_it->first, NULL) == thread_id)
485 tab_handles_to_remove.push_back(handle_it->first);
486 }
487 } // AutoLock end
488
489 std::vector<HWND>::iterator tab_handle_it = tab_handles_to_remove.begin();
490 for (; tab_handle_it != tab_handles_to_remove.end(); ++tab_handle_it) {
491 DeleteTabHandle(*tab_handle_it);
492 }
493 }
494
466 bool ExecutorsManager::IsTabIdValid(int tab_id) { 495 bool ExecutorsManager::IsTabIdValid(int tab_id) {
467 AutoLock lock(lock_); 496 AutoLock lock(lock_);
468 TabIdMap::const_iterator it = tab_id_map_.find(tab_id); 497 TabIdMap::const_iterator it = tab_id_map_.find(tab_id);
469 #ifdef DEBUG 498 #ifdef DEBUG
470 return it != tab_id_map_.end() && it->second != INVALID_HANDLE_VALUE; 499 return it != tab_id_map_.end() && it->second != INVALID_HANDLE_VALUE;
471 #else 500 #else
472 return it != tab_id_map_.end(); 501 return it != tab_id_map_.end();
473 #endif 502 #endif
474 } 503 }
475 504
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
589 size_t num_handles = num_threads + kExtraHandles; 618 size_t num_handles = num_threads + kExtraHandles;
590 DWORD result = me->WaitForMultipleObjects(num_handles, handles, FALSE, 619 DWORD result = me->WaitForMultipleObjects(num_handles, handles, FALSE,
591 INFINITE); 620 INFINITE);
592 if (result == WAIT_OBJECT_0 + num_threads + 621 if (result == WAIT_OBJECT_0 + num_threads +
593 kUpdateHandleIndexOffset) { 622 kUpdateHandleIndexOffset) {
594 // We got a new thread added, 623 // We got a new thread added,
595 // simply let the loop turn to add it to our watch list. 624 // simply let the loop turn to add it to our watch list.
596 } else if (result >= WAIT_OBJECT_0 && 625 } else if (result >= WAIT_OBJECT_0 &&
597 result < WAIT_OBJECT_0 + num_threads) { 626 result < WAIT_OBJECT_0 + num_threads) {
598 // One of our threads have died, cleanup time. 627 // One of our threads have died, cleanup time.
599 me->RemoveExecutor(thread_ids[result - WAIT_OBJECT_0]); 628 DWORD thread_id = thread_ids[result - WAIT_OBJECT_0];
629 VLOG(1) << "Thread: " << thread_id << " is dying on us!";
630 me->RemoveExecutor(thread_id);
631 // We must asynchronously post this change in case there are pending
Sigurður Ásgeirsson 2010/12/03 20:40:42 Interesting. Doesn't this leave us with another r
632 // asynchronous notifications (e.g., tabs.onRemoved) that would still
633 // need the handle to tab id mapping.
634 // NOTE: No need to worry about the lifespan of the executors manager
635 // referred by the me variable since it's a singleton released at exit.
636 ChromePostman* single_instance = ChromePostman::GetInstance();
637 // This is not intialized in unittests yet.
638 if (single_instance) {
639 single_instance->QueueApiInvocationThreadTask(
640 NewRunnableMethod(me, &ExecutorsManager::CleanupMapsForThread,
641 thread_id));
642 }
600 } else if (result == WAIT_OBJECT_0 + num_threads + 643 } else if (result == WAIT_OBJECT_0 + num_threads +
601 kTerminationHandleIndexOffset) { 644 kTerminationHandleIndexOffset) {
602 // we are being terminated, break the cycle. 645 // we are being terminated, break the cycle.
603 break; 646 break;
604 } else { 647 } else {
605 DCHECK(result == WAIT_FAILED); 648 DCHECK(result == WAIT_FAILED);
606 LOG(ERROR) << "ExecutorsManager::ThreadProc " << com::LogWe(); 649 LOG(ERROR) << "ExecutorsManager::ThreadProc " << com::LogWe();
607 break; 650 break;
608 } 651 }
609 } 652 }
610 // Merci... Bonsoir... 653 // Merci... Bonsoir...
611 ::CoUninitialize(); 654 ::CoUninitialize();
612 return 1; 655 return 1;
613 } 656 }
OLDNEW
« no previous file with comments | « ceee/ie/broker/executors_manager.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698