File: 0122.patch

package info (click to toggle)
firefox-esr 140.5.0esr-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 4,538,920 kB
  • sloc: cpp: 7,381,527; javascript: 6,388,905; ansic: 3,710,087; python: 1,393,776; xml: 628,165; asm: 426,916; java: 184,004; sh: 65,744; makefile: 19,302; objc: 13,059; perl: 12,912; yacc: 4,583; cs: 3,846; pascal: 3,352; lex: 1,720; ruby: 1,226; exp: 762; php: 436; lisp: 258; awk: 247; sql: 66; sed: 54; csh: 10
file content (138 lines) | stat: -rw-r--r-- 4,813 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
From: Andreas Pehrson <apehrson@mozilla.com>
Date: Fri, 13 Sep 2024 09:48:00 +0000
Subject: Bug 1918096 - Make SckPickerHandle thread safe. r=padenot

We cannot guarantee that the thread it is used on is static, as both the
VideoCapture and DesktopCapture threads can come and go.

Differential Revision: https://phabricator.services.mozilla.com/D222082
Mercurial Revision: https://hg.mozilla.org/mozilla-central/rev/cfcdd5339805363c495841abc4b4f82cd287f712
---
 .../desktop_capture/mac/sck_picker_handle.mm  | 90 +++++++++++++------
 1 file changed, 62 insertions(+), 28 deletions(-)

diff --git a/modules/desktop_capture/mac/sck_picker_handle.mm b/modules/desktop_capture/mac/sck_picker_handle.mm
index 25e98b671f..0f26be79d1 100644
--- a/modules/desktop_capture/mac/sck_picker_handle.mm
+++ b/modules/desktop_capture/mac/sck_picker_handle.mm
@@ -12,57 +12,91 @@
 
 #import <ScreenCaptureKit/ScreenCaptureKit.h>
 
-#include "api/sequence_checker.h"
+#include "absl/base/attributes.h"
+#include "rtc_base/synchronization/mutex.h"
+
+#include <memory>
+#include <optional>
 
 namespace webrtc {
 
-class API_AVAILABLE(macos(14.0)) SckPickerHandle : public SckPickerHandleInterface {
+class SckPickerProxy;
+
+class API_AVAILABLE(macos(14.0)) SckPickerProxy {
  public:
-  explicit SckPickerHandle(DesktopCapturer::SourceId source) : source_(source) {
-    RTC_DCHECK_RUN_ON(&checker_);
-    RTC_CHECK_LE(sHandleCount, maximumStreamCount);
-    if (sHandleCount++ == 0) {
+  static SckPickerProxy* Get() {
+    static SckPickerProxy* sPicker = new SckPickerProxy();
+    return sPicker;
+  }
+
+  bool AtCapacity() const {
+    MutexLock lock(&mutex_);
+    return AtCapacityLocked();
+  }
+
+  SCContentSharingPicker* GetPicker() const { return SCContentSharingPicker.sharedPicker; }
+
+  ABSL_MUST_USE_RESULT std::optional<DesktopCapturer::SourceId> AcquireSourceId() {
+    MutexLock lock(&mutex_);
+    if (AtCapacityLocked()) {
+      return std::nullopt;
+    }
+    if (handle_count_++ == 0) {
       auto* picker = GetPicker();
       picker.maximumStreamCount = [NSNumber numberWithUnsignedInt:maximumStreamCount];
       picker.active = YES;
     }
+    return ++unique_source_id_;
   }
 
-  ~SckPickerHandle() {
-    RTC_DCHECK_RUN_ON(&checker_);
-    if (--sHandleCount > 0) {
+  void RelinquishSourceId(DesktopCapturer::SourceId source) {
+    MutexLock lock(&mutex_);
+    if (--handle_count_ > 0) {
       return;
     }
     GetPicker().active = NO;
   }
 
-  SCContentSharingPicker* GetPicker() const override {
-    return SCContentSharingPicker.sharedPicker;
+ private:
+  bool AtCapacityLocked() const {
+    mutex_.AssertHeld();
+    return handle_count_ == maximumStreamCount;
   }
 
-  DesktopCapturer::SourceId Source() const override {
-    return source_;
+  mutable Mutex mutex_;
+  // 100 is an arbitrary number that seems high enough to never get reached, while still providing
+  // a reasonably low upper bound.
+  static constexpr size_t maximumStreamCount = 100;
+  size_t handle_count_ RTC_GUARDED_BY(mutex_) = 0;
+  DesktopCapturer::SourceId unique_source_id_ RTC_GUARDED_BY(mutex_) = 0;
+};
+
+class API_AVAILABLE(macos(14.0)) SckPickerHandle : public SckPickerHandleInterface {
+ public:
+  static std::unique_ptr<SckPickerHandle> Create(SckPickerProxy* proxy) {
+    std::optional<DesktopCapturer::SourceId> id = proxy->AcquireSourceId();
+    if (!id) {
+      return nullptr;
+    }
+    return std::unique_ptr<SckPickerHandle>(new SckPickerHandle(proxy, *id));
   }
 
-  static bool AtCapacity() { return sHandleCount == maximumStreamCount; }
+  ~SckPickerHandle() { proxy_->RelinquishSourceId(source_); }
+
+  SCContentSharingPicker* GetPicker() const override { return proxy_->GetPicker(); }
+
+  DesktopCapturer::SourceId Source() const override { return source_; }
 
  private:
-  // 100 is an arbitrary number that seems high enough to never get reached, while still providing
-  // a reasonably low upper bound.
-  static constexpr size_t maximumStreamCount = 100;
-  static size_t sHandleCount;
-  SequenceChecker checker_;
+  SckPickerHandle(SckPickerProxy* proxy, DesktopCapturer::SourceId source)
+      : proxy_(proxy), source_(source) {}
+
+  SckPickerProxy* const proxy_;
   const DesktopCapturer::SourceId source_;
 };
 
-size_t SckPickerHandle::sHandleCount = 0;
-
-std::unique_ptr<SckPickerHandleInterface> CreateSckPickerHandle() API_AVAILABLE(macos(14.0)) {
-  if (SckPickerHandle::AtCapacity()) {
-    return nullptr;
-  }
-  static DesktopCapturer::SourceId unique_source_id = 0;
-  return std::make_unique<SckPickerHandle>(++unique_source_id);
+std::unique_ptr<SckPickerHandleInterface> CreateSckPickerHandle() {
+  return SckPickerHandle::Create(SckPickerProxy::Get());
 }
 
-}  // namespace webrtc
\ No newline at end of file
+}  // namespace webrtc