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 | |
88 while (!tasks.empty()) { | 84 while (!tasks.empty()) { |
89 base::Closure task = tasks.top(); | 85 base::Closure task = tasks.top(); |
90 task.Run(); | 86 task.Run(); |
91 tasks.pop(); | 87 tasks.pop(); |
92 } | 88 } |
93 | 89 |
94 // Expect that all callbacks have been run. | 90 // Expect that all callbacks have been run. |
95 DCHECK(g_top_manager->stack_.empty()); | 91 DCHECK(g_top_manager->stack_.empty()); |
96 } | 92 } |
97 | 93 |
98 void AtExitManager::DisableAllAtExitManagers() { | 94 void AtExitManager::DisableAllAtExitManagers() { |
99 AutoLock lock(g_top_manager->lock_); | 95 AutoLock lock(g_top_manager->lock_); |
100 g_disable_managers = true; | 96 g_disable_managers = true; |
101 } | 97 } |
102 | 98 |
103 AtExitManager::AtExitManager(bool shadow) | 99 AtExitManager::AtExitManager(bool shadow) |
104 : processing_callbacks_(false), next_manager_(g_top_manager) { | 100 : processing_callbacks_(false), next_manager_(g_top_manager) { |
105 DCHECK(shadow || !g_top_manager); | 101 DCHECK(shadow || !g_top_manager); |
106 g_top_manager = this; | 102 g_top_manager = this; |
107 } | 103 } |
108 | 104 |
109 } // namespace base | 105 } // namespace base |
OLD | NEW |