blob: a23ac08885ec88cf6dad56e0350e1d49a75992d1 [file] [log] [blame]
Artem Titov3f7990d2021-02-03 15:23:471/*
2 * Copyright 2020 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10#ifndef RTC_BASE_SYNCHRONIZATION_SEQUENCE_CHECKER_INTERNAL_H_
11#define RTC_BASE_SYNCHRONIZATION_SEQUENCE_CHECKER_INTERNAL_H_
12
13#include <string>
14#include <type_traits>
15
16#include "api/task_queue/task_queue_base.h"
17#include "rtc_base/platform_thread_types.h"
18#include "rtc_base/synchronization/mutex.h"
19#include "rtc_base/system/rtc_export.h"
20#include "rtc_base/thread_annotations.h"
21
22namespace webrtc {
23namespace webrtc_sequence_checker_internal {
24
25// Real implementation of SequenceChecker, for use in debug mode, or
26// for temporary use in release mode (e.g. to RTC_CHECK on a threading issue
27// seen only in the wild).
28//
29// Note: You should almost always use the SequenceChecker class to get the
30// right version for your build configuration.
31class RTC_EXPORT SequenceCheckerImpl {
32 public:
Tommi3da04a92023-03-21 10:42:2733 explicit SequenceCheckerImpl(bool attach_to_current_thread);
Tommi7c1ddb72023-10-23 12:38:1334 explicit SequenceCheckerImpl(TaskQueueBase* attached_queue);
Artem Titov3f7990d2021-02-03 15:23:4735 ~SequenceCheckerImpl() = default;
36
37 bool IsCurrent() const;
38 // Changes the task queue or thread that is checked for in IsCurrent. This can
39 // be useful when an object may be created on one task queue / thread and then
40 // used exclusively on another thread.
41 void Detach();
42
43 // Returns a string that is formatted to match with the error string printed
44 // by RTC_CHECK() when a condition is not met.
45 // This is used in conjunction with the RTC_DCHECK_RUN_ON() macro.
46 std::string ExpectationToString() const;
47
48 private:
49 mutable Mutex lock_;
50 // These are mutable so that IsCurrent can set them.
51 mutable bool attached_ RTC_GUARDED_BY(lock_);
52 mutable rtc::PlatformThreadRef valid_thread_ RTC_GUARDED_BY(lock_);
53 mutable const TaskQueueBase* valid_queue_ RTC_GUARDED_BY(lock_);
Artem Titov3f7990d2021-02-03 15:23:4754};
55
56// Do nothing implementation, for use in release mode.
57//
58// Note: You should almost always use the SequenceChecker class to get the
59// right version for your build configuration.
60class SequenceCheckerDoNothing {
61 public:
Tommi3da04a92023-03-21 10:42:2762 explicit SequenceCheckerDoNothing(bool attach_to_current_thread) {}
Tommi7c1ddb72023-10-23 12:38:1363 explicit SequenceCheckerDoNothing(TaskQueueBase* attached_queue) {}
Artem Titov3f7990d2021-02-03 15:23:4764 bool IsCurrent() const { return true; }
65 void Detach() {}
66};
67
Byoungchan Lee40867212022-09-26 14:24:0468template <typename ThreadLikeObject>
69std::enable_if_t<std::is_base_of_v<SequenceCheckerImpl, ThreadLikeObject>,
70 std::string>
71ExpectationToString(const ThreadLikeObject* checker) {
72#if RTC_DCHECK_IS_ON
73 return checker->ExpectationToString();
74#else
75 return std::string();
76#endif
77}
Artem Titov3f7990d2021-02-03 15:23:4778
79// Catch-all implementation for types other than explicitly supported above.
80template <typename ThreadLikeObject>
Byoungchan Lee40867212022-09-26 14:24:0481std::enable_if_t<!std::is_base_of_v<SequenceCheckerImpl, ThreadLikeObject>,
82 std::string>
83ExpectationToString(const ThreadLikeObject*) {
Artem Titov3f7990d2021-02-03 15:23:4784 return std::string();
85}
86
87} // namespace webrtc_sequence_checker_internal
88} // namespace webrtc
89
90#endif // RTC_BASE_SYNCHRONIZATION_SEQUENCE_CHECKER_INTERNAL_H_