/src/brpc/src/butil/threading/thread_restrictions.cc
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 | | // Use of this source code is governed by a BSD-style license that can be |
3 | | // found in the LICENSE file. |
4 | | |
5 | | #include "butil/threading/thread_restrictions.h" |
6 | | |
7 | | #if ENABLE_THREAD_RESTRICTIONS |
8 | | |
9 | | #include "butil/lazy_instance.h" |
10 | | #include "butil/logging.h" |
11 | | #include "butil/threading/thread_local.h" |
12 | | |
13 | | namespace butil { |
14 | | |
15 | | namespace { |
16 | | |
17 | | LazyInstance<ThreadLocalBoolean>::Leaky |
18 | | g_io_disallowed = LAZY_INSTANCE_INITIALIZER; |
19 | | |
20 | | LazyInstance<ThreadLocalBoolean>::Leaky |
21 | | g_singleton_disallowed = LAZY_INSTANCE_INITIALIZER; |
22 | | |
23 | | LazyInstance<ThreadLocalBoolean>::Leaky |
24 | | g_wait_disallowed = LAZY_INSTANCE_INITIALIZER; |
25 | | |
26 | | } // anonymous namespace |
27 | | |
28 | | // static |
29 | 0 | bool ThreadRestrictions::SetIOAllowed(bool allowed) { |
30 | 0 | bool previous_disallowed = g_io_disallowed.Get().Get(); |
31 | 0 | g_io_disallowed.Get().Set(!allowed); |
32 | 0 | return !previous_disallowed; |
33 | 0 | } |
34 | | |
35 | | // static |
36 | 0 | void ThreadRestrictions::AssertIOAllowed() { |
37 | 0 | if (g_io_disallowed.Get().Get()) { |
38 | 0 | LOG(FATAL) << |
39 | 0 | "Function marked as IO-only was called from a thread that " |
40 | 0 | "disallows IO! If this thread really should be allowed to " |
41 | 0 | "make IO calls, adjust the call to " |
42 | 0 | "butil::ThreadRestrictions::SetIOAllowed() in this thread's " |
43 | 0 | "startup."; |
44 | 0 | } |
45 | 0 | } |
46 | | |
47 | | // static |
48 | 0 | bool ThreadRestrictions::SetSingletonAllowed(bool allowed) { |
49 | 0 | bool previous_disallowed = g_singleton_disallowed.Get().Get(); |
50 | 0 | g_singleton_disallowed.Get().Set(!allowed); |
51 | 0 | return !previous_disallowed; |
52 | 0 | } |
53 | | |
54 | | // static |
55 | 0 | void ThreadRestrictions::AssertSingletonAllowed() { |
56 | 0 | if (g_singleton_disallowed.Get().Get()) { |
57 | 0 | LOG(FATAL) << "LazyInstance/Singleton is not allowed to be used on this " |
58 | 0 | << "thread. Most likely it's because this thread is not " |
59 | 0 | << "joinable, so AtExitManager may have deleted the object " |
60 | 0 | << "on shutdown, leading to a potential shutdown crash."; |
61 | 0 | } |
62 | 0 | } |
63 | | |
64 | | // static |
65 | 0 | void ThreadRestrictions::DisallowWaiting() { |
66 | 0 | g_wait_disallowed.Get().Set(true); |
67 | 0 | } |
68 | | |
69 | | // static |
70 | 0 | void ThreadRestrictions::AssertWaitAllowed() { |
71 | 0 | if (g_wait_disallowed.Get().Get()) { |
72 | 0 | LOG(FATAL) << "Waiting is not allowed to be used on this thread to prevent" |
73 | 0 | << "jank and deadlock."; |
74 | 0 | } |
75 | 0 | } |
76 | | |
77 | 0 | bool ThreadRestrictions::SetWaitAllowed(bool allowed) { |
78 | 0 | bool previous_disallowed = g_wait_disallowed.Get().Get(); |
79 | 0 | g_wait_disallowed.Get().Set(!allowed); |
80 | 0 | return !previous_disallowed; |
81 | 0 | } |
82 | | |
83 | | } // namespace butil |
84 | | |
85 | | #endif // ENABLE_THREAD_RESTRICTIONS |