OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "base/at_exit.h" | 5 #include "base/at_exit.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <ostream> | 8 #include <ostream> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
74 // Callbacks may try to add new callbacks, so run them without holding | 74 // Callbacks may try to add new callbacks, so run them without holding |
75 // |lock_|. This is an error and caught by the DCHECK in RegisterTask(), but | 75 // |lock_|. This is an error and caught by the DCHECK in RegisterTask(), but |
76 // handle it gracefully in release builds so we don't deadlock. | 76 // handle it gracefully in release builds so we don't deadlock. |
77 std::stack<base::Closure> tasks; | 77 std::stack<base::Closure> tasks; |
78 { | 78 { |
79 AutoLock lock(g_top_manager->lock_); | 79 AutoLock lock(g_top_manager->lock_); |
80 tasks.swap(g_top_manager->stack_); | 80 tasks.swap(g_top_manager->stack_); |
81 g_top_manager->processing_callbacks_ = true; | 81 g_top_manager->processing_callbacks_ = true; |
82 } | 82 } |
83 | 83 |
| 84 // Relax the cross-thread access restriction to non-thread-safe RefCount. |
| 85 // It's safe since all other threads should be terminated at this point. |
| 86 ScopedAllowCrossThreadRefCountAccess allow_cross_thread_ref_count_access; |
| 87 |
84 while (!tasks.empty()) { | 88 while (!tasks.empty()) { |
85 base::Closure task = tasks.top(); | 89 base::Closure task = tasks.top(); |
86 task.Run(); | 90 task.Run(); |
87 tasks.pop(); | 91 tasks.pop(); |
88 } | 92 } |
89 | 93 |
90 // Expect that all callbacks have been run. | 94 // Expect that all callbacks have been run. |
91 DCHECK(g_top_manager->stack_.empty()); | 95 DCHECK(g_top_manager->stack_.empty()); |
92 } | 96 } |
93 | 97 |
94 void AtExitManager::DisableAllAtExitManagers() { | 98 void AtExitManager::DisableAllAtExitManagers() { |
95 AutoLock lock(g_top_manager->lock_); | 99 AutoLock lock(g_top_manager->lock_); |
96 g_disable_managers = true; | 100 g_disable_managers = true; |
97 } | 101 } |
98 | 102 |
99 AtExitManager::AtExitManager(bool shadow) | 103 AtExitManager::AtExitManager(bool shadow) |
100 : processing_callbacks_(false), next_manager_(g_top_manager) { | 104 : processing_callbacks_(false), next_manager_(g_top_manager) { |
101 DCHECK(shadow || !g_top_manager); | 105 DCHECK(shadow || !g_top_manager); |
102 g_top_manager = this; | 106 g_top_manager = this; |
103 } | 107 } |
104 | 108 |
105 } // namespace base | 109 } // namespace base |
OLD | NEW |