mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-13 13:50:40 +01:00

clangd ignores ASSERT_EXCLUSIVE_LOCK macro attached to an inline function in header, thus IDEs relying on clangd issue false positive warnings about members acceesses without the check of the current sequence. Attaching assert attribute to an inlined lambda function seems to solve that issue Bug: None Change-Id: I6199fee26061aa4223f2e3ea7b7b14bb5820c0bc Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/270480 Reviewed-by: Evan Shrubsole <eshr@webrtc.org> Reviewed-by: Tomas Gunnarsson <tommi@webrtc.org> Commit-Queue: Danil Chapovalov <danilchap@webrtc.org> Cr-Commit-Position: refs/heads/main@{#37678}
121 lines
4.1 KiB
C++
121 lines
4.1 KiB
C++
/*
|
|
* Copyright 2019 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
#ifndef API_SEQUENCE_CHECKER_H_
|
|
#define API_SEQUENCE_CHECKER_H_
|
|
|
|
#include "rtc_base/checks.h"
|
|
#include "rtc_base/synchronization/sequence_checker_internal.h"
|
|
#include "rtc_base/thread_annotations.h"
|
|
|
|
namespace webrtc {
|
|
|
|
// SequenceChecker is a helper class used to help verify that some methods
|
|
// of a class are called on the same task queue or thread. A
|
|
// SequenceChecker is bound to a a task queue if the object is
|
|
// created on a task queue, or a thread otherwise.
|
|
//
|
|
//
|
|
// Example:
|
|
// class MyClass {
|
|
// public:
|
|
// void Foo() {
|
|
// RTC_DCHECK_RUN_ON(&sequence_checker_);
|
|
// ... (do stuff) ...
|
|
// }
|
|
//
|
|
// private:
|
|
// SequenceChecker sequence_checker_;
|
|
// }
|
|
//
|
|
// In Release mode, IsCurrent will always return true.
|
|
class RTC_LOCKABLE SequenceChecker
|
|
#if RTC_DCHECK_IS_ON
|
|
: public webrtc_sequence_checker_internal::SequenceCheckerImpl {
|
|
using Impl = webrtc_sequence_checker_internal::SequenceCheckerImpl;
|
|
#else
|
|
: public webrtc_sequence_checker_internal::SequenceCheckerDoNothing {
|
|
using Impl = webrtc_sequence_checker_internal::SequenceCheckerDoNothing;
|
|
#endif
|
|
public:
|
|
// Returns true if sequence checker is attached to the current sequence.
|
|
bool IsCurrent() const { return Impl::IsCurrent(); }
|
|
// Detaches checker from sequence to which it is attached. Next attempt
|
|
// to do a check with this checker will result in attaching this checker
|
|
// to the sequence on which check was performed.
|
|
void Detach() { Impl::Detach(); }
|
|
};
|
|
|
|
} // namespace webrtc
|
|
|
|
// RTC_RUN_ON/RTC_GUARDED_BY/RTC_DCHECK_RUN_ON macros allows to annotate
|
|
// variables are accessed from same thread/task queue.
|
|
// Using tools designed to check mutexes, it checks at compile time everywhere
|
|
// variable is access, there is a run-time dcheck thread/task queue is correct.
|
|
//
|
|
// class SequenceCheckerExample {
|
|
// public:
|
|
// int CalledFromPacer() RTC_RUN_ON(pacer_sequence_checker_) {
|
|
// return var2_;
|
|
// }
|
|
//
|
|
// void CallMeFromPacer() {
|
|
// RTC_DCHECK_RUN_ON(&pacer_sequence_checker_)
|
|
// << "Should be called from pacer";
|
|
// CalledFromPacer();
|
|
// }
|
|
//
|
|
// private:
|
|
// int pacer_var_ RTC_GUARDED_BY(pacer_sequence_checker_);
|
|
// SequenceChecker pacer_sequence_checker_;
|
|
// };
|
|
//
|
|
// class TaskQueueExample {
|
|
// public:
|
|
// class Encoder {
|
|
// public:
|
|
// rtc::TaskQueueBase& Queue() { return encoder_queue_; }
|
|
// void Encode() {
|
|
// RTC_DCHECK_RUN_ON(&encoder_queue_);
|
|
// DoSomething(var_);
|
|
// }
|
|
//
|
|
// private:
|
|
// rtc::TaskQueueBase& encoder_queue_;
|
|
// Frame var_ RTC_GUARDED_BY(encoder_queue_);
|
|
// };
|
|
//
|
|
// void Encode() {
|
|
// // Will fail at runtime when DCHECK is enabled:
|
|
// // encoder_->Encode();
|
|
// // Will work:
|
|
// rtc::scoped_refptr<Encoder> encoder = encoder_;
|
|
// encoder_->Queue().PostTask([encoder] { encoder->Encode(); });
|
|
// }
|
|
//
|
|
// private:
|
|
// rtc::scoped_refptr<Encoder> encoder_;
|
|
// }
|
|
|
|
// Document if a function expected to be called from same thread/task queue.
|
|
#define RTC_RUN_ON(x) \
|
|
RTC_THREAD_ANNOTATION_ATTRIBUTE__(exclusive_locks_required(x))
|
|
|
|
// Checks current code is running on the desired sequence.
|
|
//
|
|
// First statement validates it is running on the sequence `x`.
|
|
// Second statement annotates for the thread safety analyzer the check was done.
|
|
// Such annotation has to be attached to a function, and that function has to be
|
|
// called. Thus current implementation creates a noop lambda and calls it.
|
|
#define RTC_DCHECK_RUN_ON(x) \
|
|
RTC_DCHECK((x)->IsCurrent()) \
|
|
<< webrtc::webrtc_sequence_checker_internal::ExpectationToString(x); \
|
|
[]() RTC_ASSERT_EXCLUSIVE_LOCK(x) {}()
|
|
|
|
#endif // API_SEQUENCE_CHECKER_H_
|