Video capture PipeWire: fix thread and lock annotations

There are two threads involved here, the thread that calls the API
functions and the pipwire main loop. Using one race checker for both is
wrong and triggers aborts.

Use a different race checker for all variables that are used by the
pipewire main loop or guarded against concurrent access with the
thread_loop_lock.

In one case, two RTC_CHECK_RUNS_SERIALIZED() checks are needed, so
enhance the macro to generate unique variable names.

Bug: webrtc:15181
Change-Id: Ib41514eb7aa98fe85d830461aa0c71e42ba821bd
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/326781
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Commit-Queue: Tomas Gunnarsson <tommi@webrtc.org>
Reviewed-by: Tomas Gunnarsson <tommi@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41198}
This commit is contained in:
Michael Olbrich 2023-11-09 16:37:06 +01:00 committed by WebRTC LUCI CQ
parent 136d3b0df3
commit a9d497b52d
3 changed files with 18 additions and 9 deletions

View file

@ -126,6 +126,7 @@ int32_t VideoCaptureModulePipeWire::StartCapture(
RTC_LOG(LS_VERBOSE) << "Creating new PipeWire stream for node " << node_id_;
PipeWireThreadLoopLock thread_loop_lock(session_->pw_main_loop_);
RTC_CHECK_RUNS_SERIALIZED(&pipewire_checker_);
pw_properties* reuse_props =
pw_properties_new_string("pipewire.client.reuse=1");
stream_ = pw_stream_new(session_->pw_core_, "camera-stream", reuse_props);
@ -178,6 +179,7 @@ int32_t VideoCaptureModulePipeWire::StopCapture() {
RTC_DCHECK_RUN_ON(&api_checker_);
PipeWireThreadLoopLock thread_loop_lock(session_->pw_main_loop_);
RTC_CHECK_RUNS_SERIALIZED(&pipewire_checker_);
if (stream_) {
pw_stream_destroy(stream_);
stream_ = nullptr;
@ -210,14 +212,14 @@ void VideoCaptureModulePipeWire::OnStreamParamChanged(
VideoCaptureModulePipeWire* that =
static_cast<VideoCaptureModulePipeWire*>(data);
RTC_DCHECK(that);
RTC_CHECK_RUNS_SERIALIZED(&that->capture_checker_);
RTC_CHECK_RUNS_SERIALIZED(&that->pipewire_checker_);
if (format && id == SPA_PARAM_Format)
that->OnFormatChanged(format);
}
void VideoCaptureModulePipeWire::OnFormatChanged(const struct spa_pod* format) {
RTC_CHECK_RUNS_SERIALIZED(&capture_checker_);
RTC_CHECK_RUNS_SERIALIZED(&pipewire_checker_);
uint32_t media_type, media_subtype;
@ -359,7 +361,7 @@ static VideoRotation VideorotationFromPipeWireTransform(uint32_t transform) {
}
void VideoCaptureModulePipeWire::ProcessBuffers() {
RTC_CHECK_RUNS_SERIALIZED(&capture_checker_);
RTC_CHECK_RUNS_SERIALIZED(&pipewire_checker_);
while (pw_buffer* buffer = pw_stream_dequeue_buffer(stream_)) {
struct spa_meta_header* h;

View file

@ -43,15 +43,17 @@ class VideoCaptureModulePipeWire : public VideoCaptureImpl {
void OnFormatChanged(const struct spa_pod* format);
void ProcessBuffers();
rtc::RaceChecker pipewire_checker_;
const rtc::scoped_refptr<PipeWireSession> session_
RTC_GUARDED_BY(capture_checker_);
int node_id_ RTC_GUARDED_BY(capture_checker_);
VideoCaptureCapability configured_capability_
RTC_GUARDED_BY(capture_checker_);
RTC_GUARDED_BY(pipewire_checker_);
bool started_ RTC_GUARDED_BY(api_lock_);
struct pw_stream* stream_ RTC_GUARDED_BY(capture_checker_) = nullptr;
struct spa_hook stream_listener_ RTC_GUARDED_BY(capture_checker_);
struct pw_stream* stream_ RTC_GUARDED_BY(pipewire_checker_) = nullptr;
struct spa_hook stream_listener_ RTC_GUARDED_BY(pipewire_checker_);
};
} // namespace videocapturemodule
} // namespace webrtc

View file

@ -62,9 +62,14 @@ class RTC_SCOPED_LOCKABLE RaceCheckerScopeDoNothing {
} // namespace internal
} // namespace rtc
#define RTC_CHECK_RUNS_SERIALIZED(x) \
rtc::internal::RaceCheckerScope race_checker(x); \
RTC_CHECK(!race_checker.RaceDetected())
#define RTC_CHECK_RUNS_SERIALIZED(x) RTC_CHECK_RUNS_SERIALIZED_NEXT(x, __LINE__)
#define RTC_CHECK_RUNS_SERIALIZED_NEXT(x, suffix) \
RTC_CHECK_RUNS_SERIALIZED_IMPL(x, suffix)
#define RTC_CHECK_RUNS_SERIALIZED_IMPL(x, suffix) \
rtc::internal::RaceCheckerScope race_checker##suffix(x); \
RTC_CHECK(!race_checker##suffix.RaceDetected())
#if RTC_DCHECK_IS_ON
#define RTC_DCHECK_RUNS_SERIALIZED(x) \