Commit 38f036b0 authored by Benoît Lizé's avatar Benoît Lizé Committed by Commit Bot

blink: Add thread annotation to platform.

Replaces comments with annotations for variables protected by mutexes in
blink/platform. This allows the static analysis pass in clang to check locking
at compile time.

Changes are:
- Annotate member variables with GUARDED_BY()
- Add a few Mutex::AssertAcquired() assertions. These mark the mutex as acquired
  to the checker, and do not generate any code when DCHECK()s are off.
- Add required locking to some unit tests only methods. The code wasn't
  incorrect before as these are typically single-threaded, but this is still
  required in principle.

While in the neighborhood, also fix a few "git cl lint warnings": missing
include guards comments, explicit constructors, and include what you use.

Bug: 1013082
Change-Id: If957288537f1930f821f94296dd89e5525649ed2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1851709
Commit-Queue: Benoit L <lizeb@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#705040}
parent 3a7e17d4
...@@ -4,7 +4,9 @@ ...@@ -4,7 +4,9 @@
#include "third_party/blink/renderer/platform/audio/push_pull_fifo.h" #include "third_party/blink/renderer/platform/audio/push_pull_fifo.h"
#include <algorithm>
#include <memory> #include <memory>
#include "build/build_config.h" #include "build/build_config.h"
#include "third_party/blink/renderer/platform/audio/audio_utilities.h" #include "third_party/blink/renderer/platform/audio/audio_utilities.h"
#include "third_party/blink/renderer/platform/instrumentation/histogram.h" #include "third_party/blink/renderer/platform/instrumentation/histogram.h"
...@@ -207,7 +209,8 @@ size_t PushPullFIFO::Pull(AudioBus* output_bus, size_t frames_requested) { ...@@ -207,7 +209,8 @@ size_t PushPullFIFO::Pull(AudioBus* output_bus, size_t frames_requested) {
: 0; : 0;
} }
const PushPullFIFOStateForTest PushPullFIFO::GetStateForTest() const { const PushPullFIFOStateForTest PushPullFIFO::GetStateForTest() {
MutexLocker locker(lock_);
return {length(), NumberOfChannels(), frames_available_, index_read_, return {length(), NumberOfChannels(), frames_available_, index_read_,
index_write_, overflow_count_, underflow_count_}; index_write_, overflow_count_, underflow_count_};
} }
......
...@@ -67,15 +67,21 @@ class PLATFORM_EXPORT PushPullFIFO { ...@@ -67,15 +67,21 @@ class PLATFORM_EXPORT PushPullFIFO {
size_t Pull(AudioBus* output_bus, size_t frames_requested); size_t Pull(AudioBus* output_bus, size_t frames_requested);
size_t length() const { return fifo_length_; } size_t length() const { return fifo_length_; }
unsigned NumberOfChannels() const { return fifo_bus_->NumberOfChannels(); } unsigned NumberOfChannels() const {
lock_.AssertAcquired();
return fifo_bus_->NumberOfChannels();
}
// TODO(hongchan): For single thread unit test only. Consider refactoring. // TODO(hongchan): For single thread unit test only. Consider refactoring.
AudioBus* GetFIFOBusForTest() const { return fifo_bus_.get(); } AudioBus* GetFIFOBusForTest() {
MutexLocker locker(lock_);
return fifo_bus_.get();
}
// For single thread unit test only. Get the current configuration that // For single thread unit test only. Get the current configuration that
// consists of FIFO length, number of channels, read/write index position and // consists of FIFO length, number of channels, read/write index position and
// under/overflow count. // under/overflow count.
const PushPullFIFOStateForTest GetStateForTest() const; const PushPullFIFOStateForTest GetStateForTest();
private: private:
// The size of the FIFO. // The size of the FIFO.
...@@ -86,13 +92,12 @@ class PLATFORM_EXPORT PushPullFIFO { ...@@ -86,13 +92,12 @@ class PLATFORM_EXPORT PushPullFIFO {
unsigned overflow_count_ = 0; unsigned overflow_count_ = 0;
unsigned underflow_count_ = 0; unsigned underflow_count_ = 0;
// This lock protects variables below.
Mutex lock_; Mutex lock_;
// The number of frames in the FIFO actually available for pulling. // The number of frames in the FIFO actually available for pulling.
size_t frames_available_ = 0; size_t frames_available_ GUARDED_BY(lock_) = 0;
size_t index_read_ = 0; size_t index_read_ GUARDED_BY(lock_) = 0;
size_t index_write_ = 0; size_t index_write_ GUARDED_BY(lock_) = 0;
scoped_refptr<AudioBus> fifo_bus_; scoped_refptr<AudioBus> fifo_bus_ GUARDED_BY(lock_);
DISALLOW_COPY_AND_ASSIGN(PushPullFIFO); DISALLOW_COPY_AND_ASSIGN(PushPullFIFO);
}; };
......
...@@ -30,7 +30,8 @@ class FIFOClient { ...@@ -30,7 +30,8 @@ class FIFOClient {
public: public:
FIFOClient(PushPullFIFO* fifo, size_t bus_length, size_t jitter_range_ms) FIFOClient(PushPullFIFO* fifo, size_t bus_length, size_t jitter_range_ms)
: fifo_(fifo), : fifo_(fifo),
bus_(AudioBus::Create(fifo->NumberOfChannels(), bus_length)), bus_(AudioBus::Create(fifo->GetStateForTest().number_of_channels,
bus_length)),
client_thread_(Platform::Current()->CreateThread( client_thread_(Platform::Current()->CreateThread(
ThreadCreationParams(WebThreadType::kTestThread) ThreadCreationParams(WebThreadType::kTestThread)
.SetThreadNameForTest("FIFOClientThread"))), .SetThreadNameForTest("FIFOClientThread"))),
......
...@@ -240,6 +240,7 @@ template <class T, class U, class V> ...@@ -240,6 +240,7 @@ template <class T, class U, class V>
void ImageDecodingStore::InsertCacheInternal(std::unique_ptr<T> cache_entry, void ImageDecodingStore::InsertCacheInternal(std::unique_ptr<T> cache_entry,
U* cache_map, U* cache_map,
V* identifier_map) { V* identifier_map) {
mutex_.AssertAcquired();
const size_t cache_entry_bytes = cache_entry->MemoryUsageInBytes(); const size_t cache_entry_bytes = cache_entry->MemoryUsageInBytes();
heap_memory_usage_in_bytes_ += cache_entry_bytes; heap_memory_usage_in_bytes_ += cache_entry_bytes;
...@@ -266,6 +267,7 @@ void ImageDecodingStore::RemoveFromCacheInternal( ...@@ -266,6 +267,7 @@ void ImageDecodingStore::RemoveFromCacheInternal(
U* cache_map, U* cache_map,
V* identifier_map, V* identifier_map,
Vector<std::unique_ptr<CacheEntry>>* deletion_list) { Vector<std::unique_ptr<CacheEntry>>* deletion_list) {
mutex_.AssertAcquired();
DCHECK_EQ(cache_entry->UseCount(), 0); DCHECK_EQ(cache_entry->UseCount(), 0);
const size_t cache_entry_bytes = cache_entry->MemoryUsageInBytes(); const size_t cache_entry_bytes = cache_entry->MemoryUsageInBytes();
...@@ -307,6 +309,7 @@ void ImageDecodingStore::RemoveCacheIndexedByGeneratorInternal( ...@@ -307,6 +309,7 @@ void ImageDecodingStore::RemoveCacheIndexedByGeneratorInternal(
V* identifier_map, V* identifier_map,
const ImageFrameGenerator* generator, const ImageFrameGenerator* generator,
Vector<std::unique_ptr<CacheEntry>>* deletion_list) { Vector<std::unique_ptr<CacheEntry>>* deletion_list) {
mutex_.AssertAcquired();
typename V::iterator iter = identifier_map->find(generator); typename V::iterator iter = identifier_map->find(generator);
if (iter == identifier_map->end()) if (iter == identifier_map->end())
return; return;
...@@ -327,6 +330,7 @@ void ImageDecodingStore::RemoveCacheIndexedByGeneratorInternal( ...@@ -327,6 +330,7 @@ void ImageDecodingStore::RemoveCacheIndexedByGeneratorInternal(
void ImageDecodingStore::RemoveFromCacheListInternal( void ImageDecodingStore::RemoveFromCacheListInternal(
const Vector<std::unique_ptr<CacheEntry>>& deletion_list) { const Vector<std::unique_ptr<CacheEntry>>& deletion_list) {
mutex_.AssertAcquired();
for (size_t i = 0; i < deletion_list.size(); ++i) for (size_t i = 0; i < deletion_list.size(); ++i)
ordered_cache_list_.Remove(deletion_list[i].get()); ordered_cache_list_.Remove(deletion_list[i].get());
} }
......
...@@ -322,35 +322,31 @@ class PLATFORM_EXPORT ImageDecodingStore final { ...@@ -322,35 +322,31 @@ class PLATFORM_EXPORT ImageDecodingStore final {
// This is used for eviction of old entries. // This is used for eviction of old entries.
// Head of this list is the least recently used cache entry. // Head of this list is the least recently used cache entry.
// Tail of this list is the most recently used cache entry. // Tail of this list is the most recently used cache entry.
DoublyLinkedList<CacheEntry> ordered_cache_list_; DoublyLinkedList<CacheEntry> ordered_cache_list_ GUARDED_BY(mutex_);
// A lookup table for all decoder cache objects. Owns all decoder cache // A lookup table for all decoder cache objects. Owns all decoder cache
// objects. // objects.
typedef HashMap<DecoderCacheKey, std::unique_ptr<DecoderCacheEntry>> typedef HashMap<DecoderCacheKey, std::unique_ptr<DecoderCacheEntry>>
DecoderCacheMap; DecoderCacheMap;
DecoderCacheMap decoder_cache_map_; DecoderCacheMap decoder_cache_map_ GUARDED_BY(mutex_);
// A lookup table to map ImageFrameGenerator to all associated // A lookup table to map ImageFrameGenerator to all associated
// decoder cache keys. // decoder cache keys.
typedef HashSet<DecoderCacheKey> DecoderCacheKeySet; typedef HashSet<DecoderCacheKey> DecoderCacheKeySet;
typedef HashMap<const ImageFrameGenerator*, DecoderCacheKeySet> typedef HashMap<const ImageFrameGenerator*, DecoderCacheKeySet>
DecoderCacheKeyMap; DecoderCacheKeyMap;
DecoderCacheKeyMap decoder_cache_key_map_; DecoderCacheKeyMap decoder_cache_key_map_ GUARDED_BY(mutex_);
size_t heap_limit_in_bytes_; size_t heap_limit_in_bytes_ GUARDED_BY(mutex_);
size_t heap_memory_usage_in_bytes_; size_t heap_memory_usage_in_bytes_ GUARDED_BY(mutex_);
// A listener to global memory pressure events. // A listener to global memory pressure events.
base::MemoryPressureListener memory_pressure_listener_; base::MemoryPressureListener memory_pressure_listener_;
// Protect concurrent access to these members: // Also protects:
// m_orderedCacheList // - the CacheEntry in |decoder_cache_map_|.
// m_decoderCacheMap and all CacheEntrys stored in it // - calls to underlying skBitmap's LockPixels()/UnlockPixels() as they are
// m_decoderCacheKeyMap // not threadsafe.
// m_heapLimitInBytes
// m_heapMemoryUsageInBytes
// This mutex also protects calls to underlying skBitmap's
// lockPixels()/unlockPixels() as they are not threadsafe.
Mutex mutex_; Mutex mutex_;
DISALLOW_COPY_AND_ASSIGN(ImageDecodingStore); DISALLOW_COPY_AND_ASSIGN(ImageDecodingStore);
...@@ -358,4 +354,4 @@ class PLATFORM_EXPORT ImageDecodingStore final { ...@@ -358,4 +354,4 @@ class PLATFORM_EXPORT ImageDecodingStore final {
} // namespace blink } // namespace blink
#endif #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_IMAGE_DECODING_STORE_H_
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_IMAGE_FRAME_GENERATOR_H_ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_IMAGE_FRAME_GENERATOR_H_
#include <memory> #include <memory>
#include <utility>
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/scoped_refptr.h" #include "base/memory/scoped_refptr.h"
...@@ -150,13 +151,11 @@ class PLATFORM_EXPORT ImageFrameGenerator final ...@@ -150,13 +151,11 @@ class PLATFORM_EXPORT ImageFrameGenerator final
const bool is_multi_frame_; const bool is_multi_frame_;
const Vector<SkISize> supported_sizes_; const Vector<SkISize> supported_sizes_;
// Prevents concurrent access to all variables below.
mutable Mutex generator_mutex_; mutable Mutex generator_mutex_;
bool decode_failed_ GUARDED_BY(generator_mutex_) = false;
bool decode_failed_ = false; bool yuv_decoding_failed_ GUARDED_BY(generator_mutex_) = false;
bool yuv_decoding_failed_ = false; size_t frame_count_ GUARDED_BY(generator_mutex_) = 0u;
size_t frame_count_ = 0u; Vector<bool> has_alpha_ GUARDED_BY(generator_mutex_);
Vector<bool> has_alpha_;
struct ClientMutex { struct ClientMutex {
int ref_count = 0; int ref_count = 0;
...@@ -170,7 +169,7 @@ class PLATFORM_EXPORT ImageFrameGenerator final ...@@ -170,7 +169,7 @@ class PLATFORM_EXPORT ImageFrameGenerator final
std::unique_ptr<ClientMutex>, std::unique_ptr<ClientMutex>,
WTF::IntHash<cc::PaintImage::GeneratorClientId>, WTF::IntHash<cc::PaintImage::GeneratorClientId>,
WTF::UnsignedWithZeroKeyHashTraits<cc::PaintImage::GeneratorClientId>> WTF::UnsignedWithZeroKeyHashTraits<cc::PaintImage::GeneratorClientId>>
mutex_map_; mutex_map_ GUARDED_BY(generator_mutex_);
std::unique_ptr<ImageDecoderFactory> image_decoder_factory_; std::unique_ptr<ImageDecoderFactory> image_decoder_factory_;
...@@ -179,4 +178,4 @@ class PLATFORM_EXPORT ImageFrameGenerator final ...@@ -179,4 +178,4 @@ class PLATFORM_EXPORT ImageFrameGenerator final
} // namespace blink } // namespace blink
#endif #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_IMAGE_FRAME_GENERATOR_H_
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "third_party/blink/renderer/platform/image-decoders/segment_reader.h" #include "third_party/blink/renderer/platform/image-decoders/segment_reader.h"
#include <utility>
#include "base/containers/span.h" #include "base/containers/span.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/scoped_refptr.h" #include "base/memory/scoped_refptr.h"
...@@ -20,7 +22,7 @@ namespace blink { ...@@ -20,7 +22,7 @@ namespace blink {
// Interface for ImageDecoder to read a SharedBuffer. // Interface for ImageDecoder to read a SharedBuffer.
class SharedBufferSegmentReader final : public SegmentReader { class SharedBufferSegmentReader final : public SegmentReader {
public: public:
SharedBufferSegmentReader(scoped_refptr<SharedBuffer>); explicit SharedBufferSegmentReader(scoped_refptr<SharedBuffer>);
size_t size() const override; size_t size() const override;
size_t GetSomeData(const char*& data, size_t position) const override; size_t GetSomeData(const char*& data, size_t position) const override;
sk_sp<SkData> GetAsSkData() const override; sk_sp<SkData> GetAsSkData() const override;
...@@ -66,7 +68,7 @@ sk_sp<SkData> SharedBufferSegmentReader::GetAsSkData() const { ...@@ -66,7 +68,7 @@ sk_sp<SkData> SharedBufferSegmentReader::GetAsSkData() const {
// Interface for ImageDecoder to read an SkData. // Interface for ImageDecoder to read an SkData.
class DataSegmentReader final : public SegmentReader { class DataSegmentReader final : public SegmentReader {
public: public:
DataSegmentReader(sk_sp<SkData>); explicit DataSegmentReader(sk_sp<SkData>);
size_t size() const override; size_t size() const override;
size_t GetSomeData(const char*& data, size_t position) const override; size_t GetSomeData(const char*& data, size_t position) const override;
sk_sp<SkData> GetAsSkData() const override; sk_sp<SkData> GetAsSkData() const override;
...@@ -101,7 +103,7 @@ sk_sp<SkData> DataSegmentReader::GetAsSkData() const { ...@@ -101,7 +103,7 @@ sk_sp<SkData> DataSegmentReader::GetAsSkData() const {
class ROBufferSegmentReader final : public SegmentReader { class ROBufferSegmentReader final : public SegmentReader {
public: public:
ROBufferSegmentReader(sk_sp<SkROBuffer>); explicit ROBufferSegmentReader(sk_sp<SkROBuffer>);
size_t size() const override; size_t size() const override;
size_t GetSomeData(const char*& data, size_t position) const override; size_t GetSomeData(const char*& data, size_t position) const override;
...@@ -109,11 +111,10 @@ class ROBufferSegmentReader final : public SegmentReader { ...@@ -109,11 +111,10 @@ class ROBufferSegmentReader final : public SegmentReader {
private: private:
sk_sp<SkROBuffer> ro_buffer_; sk_sp<SkROBuffer> ro_buffer_;
// Protects access to mutable fields.
mutable Mutex read_mutex_; mutable Mutex read_mutex_;
// Position of the first char in the current block of iter_. // Position of the first char in the current block of iter_.
mutable size_t position_of_block_; mutable size_t position_of_block_ GUARDED_BY(read_mutex_);
mutable SkROBuffer::Iter iter_; mutable SkROBuffer::Iter iter_ GUARDED_BY(read_mutex_);
DISALLOW_COPY_AND_ASSIGN(ROBufferSegmentReader); DISALLOW_COPY_AND_ASSIGN(ROBufferSegmentReader);
}; };
......
...@@ -69,7 +69,7 @@ class PLATFORM_EXPORT MemoryPressureListenerRegistry final ...@@ -69,7 +69,7 @@ class PLATFORM_EXPORT MemoryPressureListenerRegistry final
static bool is_low_end_device_; static bool is_low_end_device_;
HeapHashSet<WeakMember<MemoryPressureListener>> clients_; HeapHashSet<WeakMember<MemoryPressureListener>> clients_;
HashSet<Thread*> threads_; HashSet<Thread*> threads_ GUARDED_BY(threads_mutex_);
Mutex threads_mutex_; Mutex threads_mutex_;
DISALLOW_COPY_AND_ASSIGN(MemoryPressureListenerRegistry); DISALLOW_COPY_AND_ASSIGN(MemoryPressureListenerRegistry);
......
...@@ -189,7 +189,10 @@ void MediaStreamSource::Trace(blink::Visitor* visitor) { ...@@ -189,7 +189,10 @@ void MediaStreamSource::Trace(blink::Visitor* visitor) {
} }
void MediaStreamSource::Dispose() { void MediaStreamSource::Dispose() {
{
MutexLocker locker(audio_consumers_lock_);
audio_consumers_.clear(); audio_consumers_.clear();
}
platform_source_.reset(); platform_source_.reset();
constraints_.Reset(); constraints_.Reset();
} }
......
...@@ -135,7 +135,8 @@ class PLATFORM_EXPORT MediaStreamSource final ...@@ -135,7 +135,8 @@ class PLATFORM_EXPORT MediaStreamSource final
bool requires_consumer_; bool requires_consumer_;
HeapHashSet<WeakMember<Observer>> observers_; HeapHashSet<WeakMember<Observer>> observers_;
Mutex audio_consumers_lock_; Mutex audio_consumers_lock_;
HashSet<AudioDestinationConsumer*> audio_consumers_; HashSet<AudioDestinationConsumer*> audio_consumers_
GUARDED_BY(audio_consumers_lock_);
std::unique_ptr<WebPlatformMediaStreamSource> platform_source_; std::unique_ptr<WebPlatformMediaStreamSource> platform_source_;
WebMediaConstraints constraints_; WebMediaConstraints constraints_;
WebMediaStreamSource::Capabilities capabilities_; WebMediaStreamSource::Capabilities capabilities_;
......
...@@ -362,9 +362,9 @@ class PLATFORM_EXPORT NetworkStateNotifier { ...@@ -362,9 +362,9 @@ class PLATFORM_EXPORT NetworkStateNotifier {
double GetRandomMultiplier(const String& host) const; double GetRandomMultiplier(const String& host) const;
mutable Mutex mutex_; mutable Mutex mutex_;
NetworkState state_; NetworkState state_ GUARDED_BY(mutex_);
bool has_override_; bool has_override_ GUARDED_BY(mutex_);
NetworkState override_; NetworkState override_ GUARDED_BY(mutex_);
ObserverListMap connection_observers_; ObserverListMap connection_observers_;
ObserverListMap on_line_state_observers_; ObserverListMap on_line_state_observers_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment