From 02bb892d7a8c94622de4f6f9347376eea3e0e618 Mon Sep 17 00:00:00 2001 From: R-Goc Date: Thu, 30 Oct 2025 13:29:29 +0100 Subject: [PATCH] LibThreading/LibSync: Split out sync primitives This commit splits out synchronization primitives from LibThreading into LibSync. This is because LibThreading depends on LibCore, while LibCore needs the synchronization primitives from LibThreading. This worked while they were header only, but when I tried to add an implementation file it ran into the circular dependency. To abstract away the pthread implementation using cpp files is necessary so the synchronization primitives were moved to a separate library. --- Libraries/CMakeLists.txt | 1 + Libraries/LibCore/CMakeLists.txt | 2 +- Libraries/LibCore/EventLoop.cpp | 2 +- Libraries/LibCore/EventLoop.h | 4 +-- .../LibCore/EventLoopImplementationUnix.cpp | 26 +++++++-------- .../EventLoopImplementationWindows.cpp | 6 ++-- Libraries/LibCore/ThreadEventQueue.cpp | 18 +++++------ Libraries/LibCore/ThreadedPromise.h | 12 +++---- Libraries/LibDNS/CMakeLists.txt | 2 +- Libraries/LibDNS/Resolver.h | 10 +++--- Libraries/LibGC/BlockAllocator.cpp | 28 ++++++++-------- Libraries/LibGC/BlockAllocator.h | 8 ++--- Libraries/LibGC/CMakeLists.txt | 2 +- Libraries/LibGfx/CMakeLists.txt | 2 +- Libraries/LibIPC/CMakeLists.txt | 2 +- Libraries/LibIPC/TransportBootstrapMach.cpp | 3 +- Libraries/LibIPC/TransportBootstrapMach.h | 6 ++-- Libraries/LibIPC/TransportMachPort.cpp | 17 +++++----- Libraries/LibIPC/TransportMachPort.h | 9 +++--- Libraries/LibIPC/TransportSocket.cpp | 19 +++++------ Libraries/LibIPC/TransportSocket.h | 11 ++++--- .../Audio/PlaybackStreamAudioUnit.cpp | 8 ++--- .../Audio/PlaybackStreamPulseAudio.cpp | 4 +-- .../LibMedia/Audio/PlaybackStreamPulseAudio.h | 8 ++--- .../LibMedia/Audio/PlaybackStreamWasapi.cpp | 4 +-- .../LibMedia/Audio/PulseAudioWrappers.cpp | 10 +++--- Libraries/LibMedia/CMakeLists.txt | 2 +- .../Containers/Matroska/MatroskaDemuxer.cpp | 4 +-- .../Containers/Matroska/MatroskaDemuxer.h | 4 +-- .../LibMedia/IncrementallyPopulatedStream.cpp | 20 ++++++------ .../LibMedia/IncrementallyPopulatedStream.h | 8 ++--- Libraries/LibMedia/PlaybackManager.h | 6 ++-- .../LibMedia/Providers/AudioDataProvider.cpp | 2 +- .../LibMedia/Providers/AudioDataProvider.h | 10 +++--- .../LibMedia/Providers/VideoDataProvider.h | 10 +++--- Libraries/LibMedia/Sinks/AudioMixingSink.cpp | 8 ++--- Libraries/LibMedia/Sinks/AudioMixingSink.h | 14 ++++---- Libraries/LibSync/CMakeLists.txt | 5 +++ .../ConditionVariable.h | 4 +-- Libraries/LibSync/Mutex.cpp | 30 +++++++++++++++++ Libraries/{LibThreading => LibSync}/Mutex.h | 23 ++++--------- .../MutexProtected.h | 4 +-- Libraries/{LibThreading => LibSync}/Once.h | 8 ++--- Libraries/{LibThreading => LibSync}/RWLock.h | 2 +- .../RWLockProtected.h | 4 +-- Libraries/LibThreading/BackgroundAction.cpp | 2 +- Libraries/LibThreading/CMakeLists.txt | 2 +- Libraries/LibThreading/ThreadPool.cpp | 4 +-- Libraries/LibThreading/ThreadPool.h | 8 ++--- Libraries/LibWeb/CMakeLists.txt | 2 +- Libraries/LibWeb/HTML/RenderingThread.cpp | 32 +++++++++---------- Libraries/LibWeb/HTML/RenderingThread.h | 3 +- .../TrackBufferDemuxer.cpp | 18 +++++------ .../TrackBufferDemuxer.h | 8 ++--- .../LibWeb/Painting/ExternalContentSource.cpp | 6 ++-- .../LibWeb/Painting/ExternalContentSource.h | 4 +-- .../LibWeb/Painting/VideoFrameSource.cpp | 6 ++-- Libraries/LibWeb/Painting/VideoFrameSource.h | 4 +-- .../LibWeb/WebAudio/ControlMessageQueue.cpp | 4 +-- .../LibWeb/WebAudio/ControlMessageQueue.h | 4 +-- Libraries/LibWebView/CMakeLists.txt | 2 +- Libraries/LibWebView/Process.cpp | 2 +- Services/ImageDecoder/CMakeLists.txt | 2 +- Services/WebDriver/CMakeLists.txt | 2 +- Tests/LibCore/CMakeLists.txt | 6 ++-- Tests/LibMedia/CMakeLists.txt | 2 +- Tests/LibThreading/CMakeLists.txt | 2 ++ Tests/LibWeb/CMakeLists.txt | 1 + .../EventLoopImplementationMacOS.mm | 10 +++--- UI/CMakeLists.txt | 2 +- UI/Gtk/EventLoopImplementationGtk.cpp | 8 ++--- UI/Qt/EventLoopImplementationQt.cpp | 22 ++++++------- 72 files changed, 296 insertions(+), 264 deletions(-) create mode 100644 Libraries/LibSync/CMakeLists.txt rename Libraries/{LibThreading => LibSync}/ConditionVariable.h (96%) create mode 100644 Libraries/LibSync/Mutex.cpp rename Libraries/{LibThreading => LibSync}/Mutex.h (75%) rename Libraries/{LibThreading => LibSync}/MutexProtected.h (95%) rename Libraries/{LibThreading => LibSync}/Once.h (87%) rename Libraries/{LibThreading => LibSync}/RWLock.h (98%) rename Libraries/{LibThreading => LibSync}/RWLockProtected.h (96%) diff --git a/Libraries/CMakeLists.txt b/Libraries/CMakeLists.txt index bf7232de0a..2e5964d312 100644 --- a/Libraries/CMakeLists.txt +++ b/Libraries/CMakeLists.txt @@ -3,6 +3,7 @@ add_subdirectory(LibFileSystem) add_subdirectory(LibIDL) add_subdirectory(LibMain) add_subdirectory(LibRegex) +add_subdirectory(LibSync) add_subdirectory(LibTextCodec) add_subdirectory(LibUnicode) add_subdirectory(LibURL) diff --git a/Libraries/LibCore/CMakeLists.txt b/Libraries/LibCore/CMakeLists.txt index 1d80773226..6a9d9e9a34 100644 --- a/Libraries/LibCore/CMakeLists.txt +++ b/Libraries/LibCore/CMakeLists.txt @@ -91,7 +91,7 @@ if (APPLE) endif() ladybird_lib(LibCore core EXPLICIT_SYMBOL_EXPORT) -target_link_libraries(LibCore PRIVATE LibUnicode LibURL Threads::Threads LibTextCodec) +target_link_libraries(LibCore PRIVATE LibSync Threads::Threads LibUnicode LibURL LibTextCodec) if (${CMAKE_SYSTEM_NAME} MATCHES "NetBSD") # NetBSD has its shm_open and shm_unlink functions in librt so we need to link that diff --git a/Libraries/LibCore/EventLoop.cpp b/Libraries/LibCore/EventLoop.cpp index 28e9ac4b6c..af901097b6 100644 --- a/Libraries/LibCore/EventLoop.cpp +++ b/Libraries/LibCore/EventLoop.cpp @@ -173,7 +173,7 @@ WeakEventLoopReference::WeakEventLoopReference(EventLoop& event_loop) void WeakEventLoopReference::revoke() { - Threading::RWLockLocker locker { m_lock }; + Sync::RWLockLocker locker { m_lock }; m_event_loop = nullptr; } diff --git a/Libraries/LibCore/EventLoop.h b/Libraries/LibCore/EventLoop.h index 02c1d2a594..1f02b889df 100644 --- a/Libraries/LibCore/EventLoop.h +++ b/Libraries/LibCore/EventLoop.h @@ -17,7 +17,7 @@ #include #include #include -#include +#include namespace Core { @@ -118,7 +118,7 @@ private: void revoke(); EventLoop* m_event_loop; - Threading::RWLock m_lock; + Sync::RWLock m_lock; }; class CORE_API StrongEventLoopReference { diff --git a/Libraries/LibCore/EventLoopImplementationUnix.cpp b/Libraries/LibCore/EventLoopImplementationUnix.cpp index 217bd3bd61..146ce13922 100644 --- a/Libraries/LibCore/EventLoopImplementationUnix.cpp +++ b/Libraries/LibCore/EventLoopImplementationUnix.cpp @@ -17,8 +17,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include @@ -31,7 +31,7 @@ struct ThreadData; class TimeoutSet; HashMap s_thread_data; -Threading::RWLock s_thread_data_lock; +Sync::RWLock s_thread_data_lock; thread_local pthread_t s_thread_id; thread_local OwnPtr s_this_thread_data; @@ -231,7 +231,7 @@ struct ThreadData { data = new ThreadData; s_this_thread_data = adopt_own(*data); - Threading::RWLockLocker locker(s_thread_data_lock); + Sync::RWLockLocker locker(s_thread_data_lock); s_thread_data.set(s_thread_id, s_this_thread_data.ptr()); } else { data = s_this_thread_data.ptr(); @@ -267,11 +267,11 @@ struct ThreadData { close(wake_pipe_fds[0]); close(wake_pipe_fds[1]); - Threading::RWLockLocker locker(s_thread_data_lock); + Sync::RWLockLocker locker(s_thread_data_lock); s_thread_data.remove(s_thread_id); } - Threading::Mutex mutex; + Sync::Mutex mutex; // Each thread has its own timers, notifiers and a wake pipe. TimeoutSet timeouts; @@ -334,7 +334,7 @@ void EventLoopImplementationUnix::wake() void EventLoopManagerUnix::wait_for_events(EventLoopImplementation::PumpMode mode) { auto& thread_data = ThreadData::the(); - Threading::MutexLocker locker(thread_data.mutex); + Sync::MutexLocker locker(thread_data.mutex); retry: bool has_pending_events = ThreadEventQueue::current().has_pending_events(); @@ -626,7 +626,7 @@ intptr_t EventLoopManagerUnix::register_timer(EventReceiver& object, int millise { VERIFY(milliseconds >= 0); auto& thread_data = ThreadData::the(); - Threading::MutexLocker locker(thread_data.mutex); + Sync::MutexLocker locker(thread_data.mutex); auto timer = new EventLoopTimer; timer->owner_thread = s_thread_id; timer->owner = object; @@ -640,11 +640,11 @@ intptr_t EventLoopManagerUnix::register_timer(EventReceiver& object, int millise void EventLoopManagerUnix::unregister_timer(intptr_t timer_id) { auto* timer = bit_cast(timer_id); - Threading::RWLockLocker locker(s_thread_data_lock); + Sync::RWLockLocker locker(s_thread_data_lock); auto* thread_data_ptr = ThreadData::for_thread(timer->owner_thread); if (!thread_data_ptr) return; - Threading::MutexLocker thread_data_content_locker(thread_data_ptr->mutex); + Sync::MutexLocker thread_data_content_locker(thread_data_ptr->mutex); auto& thread_data = *thread_data_ptr; auto expected = false; if (timer->is_being_deleted.compare_exchange_strong(expected, true, AK::MemoryOrder::memory_order_acq_rel)) { @@ -657,7 +657,7 @@ void EventLoopManagerUnix::unregister_timer(intptr_t timer_id) void EventLoopManagerUnix::register_notifier(Notifier& notifier) { auto& thread_data = ThreadData::the(); - Threading::MutexLocker locker(thread_data.mutex); + Sync::MutexLocker locker(thread_data.mutex); thread_data.notifier_to_index.set(¬ifier, thread_data.poll_fds.size()); thread_data.notifiers.append(¬ifier); @@ -670,11 +670,11 @@ void EventLoopManagerUnix::register_notifier(Notifier& notifier) void EventLoopManagerUnix::unregister_notifier(Notifier& notifier) { - Threading::RWLockLocker locker(s_thread_data_lock); + Sync::RWLockLocker locker(s_thread_data_lock); auto* thread_data = ThreadData::for_thread(notifier.owner_thread()); if (!thread_data) return; - Threading::MutexLocker thread_data_content_locker(thread_data->mutex); + Sync::MutexLocker thread_data_content_locker(thread_data->mutex); auto notifier_index = thread_data->notifier_to_index.take(¬ifier).release_value(); diff --git a/Libraries/LibCore/EventLoopImplementationWindows.cpp b/Libraries/LibCore/EventLoopImplementationWindows.cpp index 57d011ea96..38e874265d 100644 --- a/Libraries/LibCore/EventLoopImplementationWindows.cpp +++ b/Libraries/LibCore/EventLoopImplementationWindows.cpp @@ -16,8 +16,8 @@ #include #include #include -#include -#include +#include +#include struct OwnHandle { HANDLE handle = NULL; @@ -152,7 +152,7 @@ struct ThreadData { NonnullOwnPtr wake_data; }; -static Threading::MutexProtected>> s_processes; +static Sync::MutexProtected>> s_processes; EventLoopImplementationWindows::EventLoopImplementationWindows() : m_wake_event(ThreadData::the()->wake_data->wait_event.handle) diff --git a/Libraries/LibCore/ThreadEventQueue.cpp b/Libraries/LibCore/ThreadEventQueue.cpp index 4a79a68eaf..67a830c5ba 100644 --- a/Libraries/LibCore/ThreadEventQueue.cpp +++ b/Libraries/LibCore/ThreadEventQueue.cpp @@ -9,8 +9,8 @@ #include #include #include -#include -#include +#include +#include #include #include @@ -41,16 +41,16 @@ struct ThreadEventQueue::Private { u8 event_type { Event::Type::Invalid }; }; - Threading::Mutex mutex; + Sync::Mutex mutex; Vector queued_events; }; static pthread_key_t s_current_thread_event_queue_key; -static Threading::OnceFlag s_current_thread_event_queue_key_once {}; +static Sync::OnceFlag s_current_thread_event_queue_key_once {}; ThreadEventQueue* ThreadEventQueue::current_or_null() { - call_once(s_current_thread_event_queue_key_once, [] { + Sync::call_once(s_current_thread_event_queue_key_once, [] { pthread_key_create(&s_current_thread_event_queue_key, [](void* value) { if (value) delete static_cast(value); @@ -80,7 +80,7 @@ ThreadEventQueue::~ThreadEventQueue() = default; void ThreadEventQueue::post_event(Core::EventReceiver* receiver, Core::Event::Type event_type) { { - Threading::MutexLocker lock(m_private->mutex); + Sync::MutexLocker lock(m_private->mutex); m_private->queued_events.empend(receiver, event_type); } Core::EventLoopManager::the().did_post_event(); @@ -89,7 +89,7 @@ void ThreadEventQueue::post_event(Core::EventReceiver* receiver, Core::Event::Ty void ThreadEventQueue::deferred_invoke(Function&& invokee) { { - Threading::MutexLocker lock(m_private->mutex); + Sync::MutexLocker lock(m_private->mutex); m_private->queued_events.empend(move(invokee)); } Core::EventLoopManager::the().did_post_event(); @@ -99,7 +99,7 @@ size_t ThreadEventQueue::process() { decltype(m_private->queued_events) events; { - Threading::MutexLocker locker(m_private->mutex); + Sync::MutexLocker locker(m_private->mutex); events = move(m_private->queued_events); } @@ -133,7 +133,7 @@ size_t ThreadEventQueue::process() bool ThreadEventQueue::has_pending_events() const { - Threading::MutexLocker locker(m_private->mutex); + Sync::MutexLocker locker(m_private->mutex); return !m_private->queued_events.is_empty(); } diff --git a/Libraries/LibCore/ThreadedPromise.h b/Libraries/LibCore/ThreadedPromise.h index d37d513abc..00af95a6ac 100644 --- a/Libraries/LibCore/ThreadedPromise.h +++ b/Libraries/LibCore/ThreadedPromise.h @@ -13,7 +13,7 @@ #include #include #include -#include +#include namespace Core { @@ -75,7 +75,7 @@ public: template, ResultType&&> ResolvedHandler> ThreadedPromise& when_resolved(ResolvedHandler handler) { - Threading::MutexLocker locker { m_mutex }; + Sync::MutexLocker locker { m_mutex }; VERIFY(!m_resolution_handler); m_resolution_handler = move(handler); return *this; @@ -112,7 +112,7 @@ public: template RejectedHandler> ThreadedPromise& when_rejected(RejectedHandler when_rejected = [](ErrorType&) { }) { - Threading::MutexLocker locker { m_mutex }; + Sync::MutexLocker locker { m_mutex }; VERIFY(!m_rejection_handler); m_rejection_handler = move(when_rejected); return *this; @@ -148,7 +148,7 @@ private: template static void deferred_handler_check(NonnullRefPtr self, F&& function) { - Threading::MutexLocker locker { self->m_mutex }; + Sync::MutexLocker locker { self->m_mutex }; if (self->m_rejection_handler) { function(); return; @@ -168,7 +168,7 @@ private: // to spin extremely briefly. Therefore, sleeping the thread should not be // necessary. while (true) { - Threading::MutexLocker locker { m_mutex }; + Sync::MutexLocker locker { m_mutex }; if (m_rejection_handler) break; } @@ -181,7 +181,7 @@ private: Function(ResultType&&)> m_resolution_handler; Function m_rejection_handler; - Threading::Mutex m_mutex; + Sync::Mutex m_mutex; Atomic m_has_completed; }; diff --git a/Libraries/LibDNS/CMakeLists.txt b/Libraries/LibDNS/CMakeLists.txt index f63b1a74bc..f396e22c24 100644 --- a/Libraries/LibDNS/CMakeLists.txt +++ b/Libraries/LibDNS/CMakeLists.txt @@ -3,4 +3,4 @@ set(SOURCES ) ladybird_lib(LibDNS dns EXPLICIT_SYMBOL_EXPORT) -target_link_libraries(LibDNS PRIVATE LibCore PUBLIC LibCrypto LibThreading) +target_link_libraries(LibDNS PRIVATE LibCore PUBLIC LibCrypto LibSync LibThreading) diff --git a/Libraries/LibDNS/Resolver.h b/Libraries/LibDNS/Resolver.h index 3780084e13..11d0377015 100644 --- a/Libraries/LibDNS/Resolver.h +++ b/Libraries/LibDNS/Resolver.h @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #define TRY_OR_REJECT_PROMISE(promise, expr) \ @@ -1412,10 +1412,10 @@ private: }); } - Threading::RWLockProtected>> m_cache; - Threading::RWLockProtected>> m_pending_system_resolutions; - Threading::RWLockProtected>> m_pending_lookups; - Threading::RWLockProtected>> m_socket; + Sync::RWLockProtected>> m_cache; + Sync::RWLockProtected>> m_pending_system_resolutions; + Sync::RWLockProtected>> m_pending_lookups; + Sync::RWLockProtected>> m_socket; Function()> m_create_socket; bool m_attempting_restart { false }; ConnectionMode m_mode { ConnectionMode::UDP }; diff --git a/Libraries/LibGC/BlockAllocator.cpp b/Libraries/LibGC/BlockAllocator.cpp index 2a6edef690..1dc165c805 100644 --- a/Libraries/LibGC/BlockAllocator.cpp +++ b/Libraries/LibGC/BlockAllocator.cpp @@ -110,8 +110,8 @@ private: void run(); void process_one(BlockAllocator&); - Threading::Mutex m_mutex; - Threading::ConditionVariable m_cv { m_mutex }; + Sync::Mutex m_mutex; + Sync::ConditionVariable m_cv { m_mutex }; RefPtr m_thread; Vector m_pending; bool m_kicked { false }; @@ -135,20 +135,20 @@ DecommitWorker::DecommitWorker() void DecommitWorker::register_pending(BlockAllocator& a) { - Threading::MutexLocker locker(m_mutex); + Sync::MutexLocker locker(m_mutex); m_pending.append(&a); } void DecommitWorker::deregister(BlockAllocator& a) { - Threading::MutexLocker locker(m_mutex); + Sync::MutexLocker locker(m_mutex); m_pending.remove_first_matching([&](auto* p) { return p == &a; }); } void DecommitWorker::kick() { { - Threading::MutexLocker locker(m_mutex); + Sync::MutexLocker locker(m_mutex); m_kicked = true; } m_cv.signal(); @@ -159,7 +159,7 @@ void DecommitWorker::run() while (true) { Vector snapshot; { - Threading::MutexLocker locker(m_mutex); + Sync::MutexLocker locker(m_mutex); while (!m_kicked) m_cv.wait(); m_kicked = false; @@ -182,7 +182,7 @@ void DecommitWorker::run() process_one(*a); int prev_refcount = a->m_worker_refcount.fetch_sub(1); if (prev_refcount == 1) { - Threading::MutexLocker locker(a->m_mutex); + Sync::MutexLocker locker(a->m_mutex); a->m_worker_cv.broadcast(); } } @@ -193,7 +193,7 @@ void DecommitWorker::process_one(BlockAllocator& a) { Vector to_process; { - Threading::MutexLocker locker(a.m_mutex); + Sync::MutexLocker locker(a.m_mutex); a.m_in_decommit_registry = false; to_process = move(a.m_freshly_freed); } @@ -209,7 +209,7 @@ void DecommitWorker::process_one(BlockAllocator& a) } { - Threading::MutexLocker locker(a.m_mutex); + Sync::MutexLocker locker(a.m_mutex); for (auto* slot : to_process) a.m_blocks.append(slot); } @@ -232,14 +232,14 @@ BlockAllocator::~BlockAllocator() // in-flight processing of *this before our storage goes away. DecommitWorker::the().deregister(*this); - Threading::MutexLocker locker(m_mutex); + Sync::MutexLocker locker(m_mutex); while (m_worker_refcount.load() != 0) m_worker_cv.wait(); } size_t BlockAllocator::block_count() { - Threading::MutexLocker locker(m_mutex); + Sync::MutexLocker locker(m_mutex); return m_blocks.size(); } @@ -249,7 +249,7 @@ void* BlockAllocator::allocate_block([[maybe_unused]] char const* name) bool needs_madvise_reuse = false; { - Threading::MutexLocker locker(m_mutex); + Sync::MutexLocker locker(m_mutex); // Prefer m_freshly_freed: those slots were never madvised, so we // can hand them back out with zero syscalls. This is the deferred- @@ -302,7 +302,7 @@ void* BlockAllocator::allocate_block([[maybe_unused]] char const* name) ASAN_POISON_MEMORY_REGION(chunk_base, CHUNK_SIZE); - Threading::MutexLocker locker(m_mutex); + Sync::MutexLocker locker(m_mutex); for (size_t i = 0; i < BLOCKS_PER_CHUNK; ++i) m_blocks.append(static_cast(chunk_base) + i * HeapBlock::BLOCK_SIZE); block = m_blocks.take_last(); @@ -335,7 +335,7 @@ void BlockAllocator::deallocate_block(void* block) bool need_to_register = false; { - Threading::MutexLocker locker(m_mutex); + Sync::MutexLocker locker(m_mutex); m_freshly_freed.append(block); if (!m_in_decommit_registry) { m_in_decommit_registry = true; diff --git a/Libraries/LibGC/BlockAllocator.h b/Libraries/LibGC/BlockAllocator.h index d4e9c69ccd..84377df16c 100644 --- a/Libraries/LibGC/BlockAllocator.h +++ b/Libraries/LibGC/BlockAllocator.h @@ -9,8 +9,8 @@ #include #include #include -#include -#include +#include +#include namespace GC { @@ -44,13 +44,13 @@ private: // Protects m_blocks, m_freshly_freed, and m_in_decommit_registry. Held // briefly on the alloc/dealloc hot path; uncontended in the common case. - Threading::Mutex m_mutex; + Sync::Mutex m_mutex; // Refcount the decommit worker bumps while it has a reference to this // allocator. The destructor waits on m_worker_cv until it hits zero so // we never let our storage go away while the worker is still running. AK::Atomic m_worker_refcount { 0 }; - Threading::ConditionVariable m_worker_cv; + Sync::ConditionVariable m_worker_cv; // True iff this allocator is currently in the worker's pending list. // Avoids re-registering on every dealloc; cleared by the worker at the diff --git a/Libraries/LibGC/CMakeLists.txt b/Libraries/LibGC/CMakeLists.txt index b446cbdd91..518f49d5b6 100644 --- a/Libraries/LibGC/CMakeLists.txt +++ b/Libraries/LibGC/CMakeLists.txt @@ -14,7 +14,7 @@ set(SOURCES ladybird_lib(LibGC gc EXPLICIT_SYMBOL_EXPORT) target_link_libraries(LibGC PRIVATE LibCore) -target_link_libraries(LibGC PUBLIC LibThreading) +target_link_libraries(LibGC PUBLIC LibSync LibThreading) if(cpptrace_FOUND AND LADYBIRD_ENABLE_CPPTRACE) target_link_libraries(LibGC PRIVATE cpptrace::cpptrace) diff --git a/Libraries/LibGfx/CMakeLists.txt b/Libraries/LibGfx/CMakeLists.txt index e4f53e695e..c31feda078 100644 --- a/Libraries/LibGfx/CMakeLists.txt +++ b/Libraries/LibGfx/CMakeLists.txt @@ -75,7 +75,7 @@ endif() ladybird_lib(LibGfx gfx) -target_link_libraries(LibGfx PRIVATE LibCompress LibCore LibCrypto LibFileSystem LibTextCodec LibIPC LibUnicode) +target_link_libraries(LibGfx PRIVATE LibCompress LibCore LibCrypto LibFileSystem LibTextCodec LibIPC LibSync LibUnicode) set(generated_sources TIFFMetadata.h TIFFTagHandler.cpp) list(TRANSFORM generated_sources PREPEND "ImageFormats/") diff --git a/Libraries/LibIPC/CMakeLists.txt b/Libraries/LibIPC/CMakeLists.txt index 7c35f64140..62663b545b 100644 --- a/Libraries/LibIPC/CMakeLists.txt +++ b/Libraries/LibIPC/CMakeLists.txt @@ -25,4 +25,4 @@ else() endif() ladybird_lib(LibIPC ipc) -target_link_libraries(LibIPC PRIVATE LibCore LibURL LibThreading) +target_link_libraries(LibIPC PRIVATE LibCore LibSync LibThreading LibURL) diff --git a/Libraries/LibIPC/TransportBootstrapMach.cpp b/Libraries/LibIPC/TransportBootstrapMach.cpp index 33858909c4..62ff89d26d 100644 --- a/Libraries/LibIPC/TransportBootstrapMach.cpp +++ b/Libraries/LibIPC/TransportBootstrapMach.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include @@ -112,7 +113,7 @@ ErrorOr TransportBootstrap { Optional child_transport; { - Threading::MutexLocker locker(m_child_registration_mutex); + Sync::MutexLocker locker(m_child_registration_mutex); child_transport = m_child_transports.take(pid); } diff --git a/Libraries/LibIPC/TransportBootstrapMach.h b/Libraries/LibIPC/TransportBootstrapMach.h index 77a1e61dd9..35c53ff828 100644 --- a/Libraries/LibIPC/TransportBootstrapMach.h +++ b/Libraries/LibIPC/TransportBootstrapMach.h @@ -16,7 +16,7 @@ #endif #include -#include +#include namespace IPC { @@ -43,7 +43,7 @@ public: // Hold this lock across process spawn and child transport registration so a // child bootstrap request cannot observe an unregistered pid. - Threading::Mutex& child_registration_lock() { return m_child_registration_mutex; } + Sync::Mutex& child_registration_lock() { return m_child_registration_mutex; } // Must be called while holding child_registration_lock(). void register_child_transport(pid_t, TransportBootstrapMachPorts); @@ -53,7 +53,7 @@ private: static void send_transport_ports_to_child(Core::MachPort reply_port, TransportBootstrapMachPorts ports); static ErrorOr create_on_demand_local_transport(Core::MachPort reply_port); - Threading::Mutex m_child_registration_mutex; + Sync::Mutex m_child_registration_mutex; HashMap m_child_transports; }; diff --git a/Libraries/LibIPC/TransportMachPort.cpp b/Libraries/LibIPC/TransportMachPort.cpp index e3617aeb38..fb4e5927d1 100644 --- a/Libraries/LibIPC/TransportMachPort.cpp +++ b/Libraries/LibIPC/TransportMachPort.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -145,7 +146,7 @@ void TransportMachPort::notify_read_available() void TransportMachPort::mark_peer_eof() { { - Threading::MutexLocker locker(m_incoming_mutex); + Sync::MutexLocker locker(m_incoming_mutex); m_peer_eof = true; } m_incoming_cv.broadcast(); @@ -164,14 +165,14 @@ intptr_t TransportMachPort::io_thread_loop() Vector messages_to_send; { - Threading::MutexLocker locker(m_send_mutex); + Sync::MutexLocker locker(m_send_mutex); messages_to_send = move(m_pending_send_messages); } for (auto& message : messages_to_send) send_mach_message(message); if (m_io_thread_state.load() == IOThreadState::SendPendingMessagesAndStop) { - Threading::MutexLocker locker(m_send_mutex); + Sync::MutexLocker locker(m_send_mutex); if (!m_pending_send_messages.is_empty()) continue; m_io_thread_state = IOThreadState::Stopped; @@ -308,7 +309,7 @@ void TransportMachPort::process_received_message(u8* buffer) return; { - Threading::MutexLocker locker(m_incoming_mutex); + Sync::MutexLocker locker(m_incoming_mutex); m_incoming_messages.append(move(message)); } m_incoming_cv.signal(); @@ -327,7 +328,7 @@ void TransportMachPort::set_up_read_hook(Function hook) }; { - Threading::MutexLocker locker(m_incoming_mutex); + Sync::MutexLocker locker(m_incoming_mutex); if (!m_incoming_messages.is_empty()) notify_read_available(); } @@ -352,7 +353,7 @@ void TransportMachPort::close_after_sending_all_pending_messages() void TransportMachPort::wait_until_readable() { - Threading::MutexLocker lock(m_incoming_mutex); + Sync::MutexLocker lock(m_incoming_mutex); while (m_incoming_messages.is_empty() && !m_peer_eof) m_incoming_cv.wait(); } @@ -360,7 +361,7 @@ void TransportMachPort::wait_until_readable() void TransportMachPort::post_message(Vector const& bytes, Vector& attachments) { { - Threading::MutexLocker locker(m_send_mutex); + Sync::MutexLocker locker(m_send_mutex); m_pending_send_messages.append(PendingMessage { bytes, move(attachments) }); } wake_io_thread(); @@ -370,7 +371,7 @@ TransportMachPort::ShouldShutdown TransportMachPort::read_as_many_messages_as_po { Vector> messages; { - Threading::MutexLocker locker(m_incoming_mutex); + Sync::MutexLocker locker(m_incoming_mutex); messages = move(m_incoming_messages); } for (auto& message : messages) diff --git a/Libraries/LibIPC/TransportMachPort.h b/Libraries/LibIPC/TransportMachPort.h index 9f5684e2c0..d3b7979029 100644 --- a/Libraries/LibIPC/TransportMachPort.h +++ b/Libraries/LibIPC/TransportMachPort.h @@ -21,7 +21,8 @@ #include #include #include -#include +#include +#include #include namespace IPC { @@ -101,11 +102,11 @@ private: Atomic m_peer_eof { false }; Vector m_pending_send_messages; - Threading::Mutex m_send_mutex; + Sync::Mutex m_send_mutex; Vector m_send_buffer; - Threading::Mutex m_incoming_mutex; - Threading::ConditionVariable m_incoming_cv { m_incoming_mutex }; + Sync::Mutex m_incoming_mutex; + Sync::ConditionVariable m_incoming_cv { m_incoming_mutex }; Vector> m_incoming_messages; RefPtr m_notify_hook_read_fd; diff --git a/Libraries/LibIPC/TransportSocket.cpp b/Libraries/LibIPC/TransportSocket.cpp index 6033e674be..157c06d021 100644 --- a/Libraries/LibIPC/TransportSocket.cpp +++ b/Libraries/LibIPC/TransportSocket.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include namespace IPC { @@ -50,7 +51,7 @@ ErrorOr TransportSocket::create_paired() void SendQueue::enqueue_message(ReadonlyBytes header, ReadonlyBytes payload, Vector&& fds) { - Threading::MutexLocker locker(m_mutex); + Sync::MutexLocker locker(m_mutex); VERIFY(MUST(m_stream.write_some(header)) == header.size()); VERIFY(MUST(m_stream.write_some(payload)) == payload.size()); m_fds.append(fds.data(), fds.size()); @@ -58,7 +59,7 @@ void SendQueue::enqueue_message(ReadonlyBytes header, ReadonlyBytes payload, Vec SendQueue::BytesAndFds SendQueue::peek(size_t max_bytes) { - Threading::MutexLocker locker(m_mutex); + Sync::MutexLocker locker(m_mutex); BytesAndFds result; auto bytes_to_send = min(max_bytes, m_stream.used_buffer_size()); result.bytes.resize(bytes_to_send); @@ -74,7 +75,7 @@ SendQueue::BytesAndFds SendQueue::peek(size_t max_bytes) void SendQueue::discard(size_t bytes_count, size_t fds_count) { - Threading::MutexLocker locker(m_mutex); + Sync::MutexLocker locker(m_mutex); MUST(m_stream.discard(bytes_count)); m_fds.remove(0, fds_count); } @@ -222,7 +223,7 @@ void TransportSocket::set_up_read_hook(Function hook) }; { - Threading::MutexLocker locker(m_incoming_mutex); + Sync::MutexLocker locker(m_incoming_mutex); if (!m_incoming_messages.is_empty()) { Array bytes = { 0 }; MUST(Core::System::write(m_notify_hook_write_fd->value(), bytes)); @@ -249,7 +250,7 @@ void TransportSocket::close_after_sending_all_pending_messages() void TransportSocket::wait_until_readable() { - Threading::MutexLocker lock(m_incoming_mutex); + Sync::MutexLocker lock(m_incoming_mutex); while (m_incoming_messages.is_empty() && m_io_thread_state == IOThreadState::Running) { m_incoming_cv.wait(); } @@ -284,7 +285,7 @@ void TransportSocket::post_message(Vector const& bytes_to_write, Vector {}; if (num_fds_to_transfer > 0) { raw_fds.ensure_capacity(num_fds_to_transfer); - Threading::MutexLocker locker(m_fds_retained_until_received_by_peer_mutex); + Sync::MutexLocker locker(m_fds_retained_until_received_by_peer_mutex); for (auto& attachment : attachments) { int fd = attachment.to_fd(); auto auto_fd = adopt_ref(*new AutoCloseFileDescriptor(fd)); @@ -463,7 +464,7 @@ void TransportSocket::read_incoming_messages() } if (acknowledged_fd_count > 0u) { - Threading::MutexLocker locker(m_fds_retained_until_received_by_peer_mutex); + Sync::MutexLocker locker(m_fds_retained_until_received_by_peer_mutex); while (acknowledged_fd_count > 0u) { if (m_fds_retained_until_received_by_peer.is_empty()) { dbgln("TransportSocket: Peer acknowledged more FDs than we sent"); @@ -494,7 +495,7 @@ void TransportSocket::read_incoming_messages() } if (!batch.is_empty()) { - Threading::MutexLocker locker(m_incoming_mutex); + Sync::MutexLocker locker(m_incoming_mutex); m_incoming_messages.extend(move(batch)); m_incoming_cv.broadcast(); notify_read_available(); @@ -510,7 +511,7 @@ TransportSocket::ShouldShutdown TransportSocket::read_as_many_messages_as_possib { Vector> messages; { - Threading::MutexLocker locker(m_incoming_mutex); + Sync::MutexLocker locker(m_incoming_mutex); messages = move(m_incoming_messages); } for (auto& message : messages) diff --git a/Libraries/LibIPC/TransportSocket.h b/Libraries/LibIPC/TransportSocket.h index d88a3a19e0..b6540e3e0b 100644 --- a/Libraries/LibIPC/TransportSocket.h +++ b/Libraries/LibIPC/TransportSocket.h @@ -13,7 +13,8 @@ #include #include #include -#include +#include +#include #include namespace IPC { @@ -31,7 +32,7 @@ public: private: AllocatingMemoryStream m_stream; Vector m_fds; - Threading::Mutex m_mutex; + Sync::Mutex m_mutex; }; class TransportSocket { @@ -99,7 +100,7 @@ private: // This is necessary to handle a specific behavior of the macOS kernel, which may prematurely garbage-collect the file // descriptor contained in the message before the peer receives it. https://openradar.me/9477351 Queue> m_fds_retained_until_received_by_peer; - Threading::Mutex m_fds_retained_until_received_by_peer_mutex; + Sync::Mutex m_fds_retained_until_received_by_peer_mutex; RefPtr m_io_thread; RefPtr m_send_queue; @@ -108,8 +109,8 @@ private: Atomic m_peer_eof { false }; ByteBuffer m_unprocessed_bytes; Queue m_unprocessed_attachments; - Threading::Mutex m_incoming_mutex; - Threading::ConditionVariable m_incoming_cv { m_incoming_mutex }; + Sync::Mutex m_incoming_mutex; + Sync::ConditionVariable m_incoming_cv { m_incoming_mutex }; Vector> m_incoming_messages; RefPtr m_wakeup_io_thread_read_fd; diff --git a/Libraries/LibMedia/Audio/PlaybackStreamAudioUnit.cpp b/Libraries/LibMedia/Audio/PlaybackStreamAudioUnit.cpp index d566b71938..b93e757519 100644 --- a/Libraries/LibMedia/Audio/PlaybackStreamAudioUnit.cpp +++ b/Libraries/LibMedia/Audio/PlaybackStreamAudioUnit.cpp @@ -13,7 +13,7 @@ #include #include #include -#include +#include #include #include @@ -211,7 +211,7 @@ public: void queue_task(AudioTask task) { - Threading::MutexLocker lock(m_task_queue_mutex); + Sync::MutexLocker lock(m_task_queue_mutex); m_task_queue.append(move(task)); m_task_queue_is_empty = false; } @@ -237,7 +237,7 @@ private: if (m_task_queue_is_empty.load()) return {}; - Threading::MutexLocker lock(m_task_queue_mutex); + Sync::MutexLocker lock(m_task_queue_mutex); m_task_queue_is_empty = m_task_queue.size() == 1; return m_task_queue.take_first(); @@ -306,7 +306,7 @@ private: AudioComponentInstance m_audio_unit { nullptr }; SampleSpecification m_sample_specification; - Threading::Mutex m_task_queue_mutex; + Sync::Mutex m_task_queue_mutex; Vector m_task_queue; Atomic m_task_queue_is_empty { true }; diff --git a/Libraries/LibMedia/Audio/PlaybackStreamPulseAudio.cpp b/Libraries/LibMedia/Audio/PlaybackStreamPulseAudio.cpp index 2070488d63..32ca6d9c0c 100644 --- a/Libraries/LibMedia/Audio/PlaybackStreamPulseAudio.cpp +++ b/Libraries/LibMedia/Audio/PlaybackStreamPulseAudio.cpp @@ -175,7 +175,7 @@ RefPtr const& PlaybackStreamPulseAudio::InternalState::stream( void PlaybackStreamPulseAudio::InternalState::enqueue(Function&& task) { - Threading::MutexLocker locker { m_mutex }; + Sync::MutexLocker locker { m_mutex }; m_tasks.enqueue(forward>(task)); m_wake_condition.signal(); } @@ -184,7 +184,7 @@ void PlaybackStreamPulseAudio::InternalState::thread_loop() { while (true) { auto task = [this]() -> Function { - Threading::MutexLocker locker { m_mutex }; + Sync::MutexLocker locker { m_mutex }; while (m_tasks.is_empty() && !m_exit) m_wake_condition.wait(); diff --git a/Libraries/LibMedia/Audio/PlaybackStreamPulseAudio.h b/Libraries/LibMedia/Audio/PlaybackStreamPulseAudio.h index c862d6b2da..462e66b89d 100644 --- a/Libraries/LibMedia/Audio/PlaybackStreamPulseAudio.h +++ b/Libraries/LibMedia/Audio/PlaybackStreamPulseAudio.h @@ -9,8 +9,8 @@ #include "PlaybackStream.h" #include "PulseAudioWrappers.h" #include -#include -#include +#include +#include namespace Audio { @@ -48,8 +48,8 @@ private: RefPtr m_stream { nullptr }; Queue> m_tasks; - Threading::Mutex m_mutex; - Threading::ConditionVariable m_wake_condition { m_mutex }; + Sync::Mutex m_mutex; + Sync::ConditionVariable m_wake_condition { m_mutex }; Atomic m_exit { false }; }; diff --git a/Libraries/LibMedia/Audio/PlaybackStreamWasapi.cpp b/Libraries/LibMedia/Audio/PlaybackStreamWasapi.cpp index 9aeb4a4c4c..7870815518 100644 --- a/Libraries/LibMedia/Audio/PlaybackStreamWasapi.cpp +++ b/Libraries/LibMedia/Audio/PlaybackStreamWasapi.cpp @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include @@ -100,7 +100,7 @@ struct PlaybackStreamWASAPI::AudioState : public AtomicRefCounted underrun_callback; - Threading::Mutex task_queue_mutex; + Sync::Mutex task_queue_mutex; Queue> task_queue; // FIXME: Create a owning handle type to be shared in the codebase HANDLE task_event = 0; diff --git a/Libraries/LibMedia/Audio/PulseAudioWrappers.cpp b/Libraries/LibMedia/Audio/PulseAudioWrappers.cpp index 36c996db5a..5eadd76665 100644 --- a/Libraries/LibMedia/Audio/PulseAudioWrappers.cpp +++ b/Libraries/LibMedia/Audio/PulseAudioWrappers.cpp @@ -7,16 +7,16 @@ #include "PulseAudioWrappers.h" #include -#include +#include namespace Audio { static PulseAudioContext* s_pulse_audio_context; -static Threading::Mutex s_pulse_audio_context_mutex; +static Sync::Mutex s_pulse_audio_context_mutex; ErrorOr> PulseAudioContext::the() { - auto instantiation_locker = Threading::MutexLocker(s_pulse_audio_context_mutex); + auto instantiation_locker = Sync::MutexLocker(s_pulse_audio_context_mutex); // Lock and unlock the mutex to ensure that the mutex is fully unlocked at application // exit. @@ -112,7 +112,7 @@ ErrorOr> PulseAudioContext::the() bool PulseAudioContext::is_connected() { - auto locker = Threading::MutexLocker(s_pulse_audio_context_mutex); + auto locker = Sync::MutexLocker(s_pulse_audio_context_mutex); return s_pulse_audio_context != nullptr; } @@ -125,7 +125,7 @@ PulseAudioContext::PulseAudioContext(pa_threaded_mainloop* main_loop, pa_mainloo PulseAudioContext::~PulseAudioContext() { - auto locker = Threading::MutexLocker(s_pulse_audio_context_mutex); + auto locker = Sync::MutexLocker(s_pulse_audio_context_mutex); { auto loop_locker = main_loop_locker(); diff --git a/Libraries/LibMedia/CMakeLists.txt b/Libraries/LibMedia/CMakeLists.txt index 72b48bf2fd..06f6d02baf 100644 --- a/Libraries/LibMedia/CMakeLists.txt +++ b/Libraries/LibMedia/CMakeLists.txt @@ -20,7 +20,7 @@ set(SOURCES ) ladybird_lib(LibMedia media EXPLICIT_SYMBOL_EXPORT) -target_link_libraries(LibMedia PRIVATE LibCore LibCrypto LibIPC LibGfx LibThreading LibUnicode) +target_link_libraries(LibMedia PRIVATE LibCore LibCrypto LibIPC LibGfx LibSync LibThreading LibUnicode) target_sources(LibMedia PRIVATE FFmpeg/FFmpegAudioConverter.cpp diff --git a/Libraries/LibMedia/Containers/Matroska/MatroskaDemuxer.cpp b/Libraries/LibMedia/Containers/Matroska/MatroskaDemuxer.cpp index 7648d07666..ae690293b2 100644 --- a/Libraries/LibMedia/Containers/Matroska/MatroskaDemuxer.cpp +++ b/Libraries/LibMedia/Containers/Matroska/MatroskaDemuxer.cpp @@ -48,7 +48,7 @@ static TrackEntry::TrackType matroska_track_type_from_track_type(TrackType type) DecoderErrorOr MatroskaDemuxer::create_context_for_track(Track const& track) { auto iterator = TRY(m_reader.create_sample_iterator(m_stream->create_cursor(), track.identifier())); - Threading::MutexLocker locker(m_track_statuses_mutex); + Sync::MutexLocker locker(m_track_statuses_mutex); VERIFY(m_track_statuses.set(track, TrackStatus(move(iterator))) == HashSetResult::InsertedNewEntry); return {}; } @@ -81,7 +81,7 @@ DecoderErrorOr> MatroskaDemuxer::get_preferred_track_for_type(Tr MatroskaDemuxer::TrackStatus& MatroskaDemuxer::get_track_status(Track const& track) { - Threading::MutexLocker locker(m_track_statuses_mutex); + Sync::MutexLocker locker(m_track_statuses_mutex); auto track_status = m_track_statuses.get(track); VERIFY(track_status.has_value()); return track_status.release_value(); diff --git a/Libraries/LibMedia/Containers/Matroska/MatroskaDemuxer.h b/Libraries/LibMedia/Containers/Matroska/MatroskaDemuxer.h index 0524e6f2e0..b05b8840c9 100644 --- a/Libraries/LibMedia/Containers/Matroska/MatroskaDemuxer.h +++ b/Libraries/LibMedia/Containers/Matroska/MatroskaDemuxer.h @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include "Reader.h" @@ -64,7 +64,7 @@ private: NonnullRefPtr m_stream; Reader m_reader; - mutable Threading::Mutex m_track_statuses_mutex; + mutable Sync::Mutex m_track_statuses_mutex; HashMap m_track_statuses; }; diff --git a/Libraries/LibMedia/IncrementallyPopulatedStream.cpp b/Libraries/LibMedia/IncrementallyPopulatedStream.cpp index eea623782f..c04c313b22 100644 --- a/Libraries/LibMedia/IncrementallyPopulatedStream.cpp +++ b/Libraries/LibMedia/IncrementallyPopulatedStream.cpp @@ -39,7 +39,7 @@ IncrementallyPopulatedStream::~IncrementallyPopulatedStream() = default; void IncrementallyPopulatedStream::set_data_request_callback(DataRequestCallback callback) { - Threading::MutexLocker locker { m_mutex }; + Sync::MutexLocker locker { m_mutex }; if (!callback) { m_callback_event_loop = nullptr; @@ -58,7 +58,7 @@ void IncrementallyPopulatedStream::add_chunk_at(u64 offset, ReadonlyBytes data) auto new_chunk_end = offset + data.size(); m_last_chunk_end = new_chunk_end; - Threading::MutexLocker locker { m_mutex }; + Sync::MutexLocker locker { m_mutex }; auto previous_chunk_iter = m_chunks.find_largest_not_above_iterator(offset); @@ -103,7 +103,7 @@ void IncrementallyPopulatedStream::add_chunk_at(u64 offset, ReadonlyBytes data) void IncrementallyPopulatedStream::close() { - Threading::MutexLocker locker { m_mutex }; + Sync::MutexLocker locker { m_mutex }; m_expected_size = m_last_chunk_end; m_closed = true; m_state_changed.broadcast(); @@ -111,7 +111,7 @@ void IncrementallyPopulatedStream::close() u64 IncrementallyPopulatedStream::size() { - Threading::MutexLocker locker { m_mutex }; + Sync::MutexLocker locker { m_mutex }; while (!m_expected_size.has_value()) m_state_changed.wait(); return m_expected_size.value(); @@ -119,14 +119,14 @@ u64 IncrementallyPopulatedStream::size() void IncrementallyPopulatedStream::set_expected_size(u64 expected_size) { - Threading::MutexLocker locker { m_mutex }; + Sync::MutexLocker locker { m_mutex }; m_expected_size = expected_size; m_state_changed.broadcast(); } Optional IncrementallyPopulatedStream::expected_size() const { - Threading::MutexLocker locker { m_mutex }; + Sync::MutexLocker locker { m_mutex }; return m_expected_size; } @@ -215,7 +215,7 @@ size_t IncrementallyPopulatedStream::read_from_chunks_while_locked(u64 position, DecoderErrorOr IncrementallyPopulatedStream::read_at(Cursor& cursor, size_t position, Bytes& bytes) { - Threading::MutexLocker locker { m_mutex }; + Sync::MutexLocker locker { m_mutex }; auto now = MonotonicTime::now_coarse(); cursor.m_active_timeout = now + CURSOR_ACTIVE_TIME; @@ -249,13 +249,13 @@ NonnullRefPtr IncrementallyPopulatedStream::create_cursor() IncrementallyPopulatedStream::Cursor::Cursor(NonnullRefPtr const& stream) : m_stream(stream) { - Threading::MutexLocker locker { m_stream->m_mutex }; + Sync::MutexLocker locker { m_stream->m_mutex }; m_stream->m_cursors.append(*this); } IncrementallyPopulatedStream::Cursor::~Cursor() { - Threading::MutexLocker locker { m_stream->m_mutex }; + Sync::MutexLocker locker { m_stream->m_mutex }; VERIFY(m_stream->m_cursors.remove_first_matching([&](Cursor const& cursor) { return this == &cursor; })); } @@ -288,7 +288,7 @@ DecoderErrorOr IncrementallyPopulatedStream::Cursor::read_into(Bytes byt void IncrementallyPopulatedStream::Cursor::abort() { - Threading::MutexLocker locker { m_stream->m_mutex }; + Sync::MutexLocker locker { m_stream->m_mutex }; m_aborted = true; m_stream->m_state_changed.broadcast(); } diff --git a/Libraries/LibMedia/IncrementallyPopulatedStream.h b/Libraries/LibMedia/IncrementallyPopulatedStream.h index f6f22a0b36..ad271be16f 100644 --- a/Libraries/LibMedia/IncrementallyPopulatedStream.h +++ b/Libraries/LibMedia/IncrementallyPopulatedStream.h @@ -18,8 +18,8 @@ #include #include #include -#include -#include +#include +#include namespace Media { @@ -109,9 +109,9 @@ private: bool check_if_data_is_available_or_begin_request_while_locked(MonotonicTime now, u64 position, u64 length); size_t read_from_chunks_while_locked(u64 position, Bytes& bytes) const; - mutable Threading::Mutex m_mutex; + mutable Sync::Mutex m_mutex; Vector m_cursors; - Threading::ConditionVariable m_state_changed { m_mutex }; + Sync::ConditionVariable m_state_changed { m_mutex }; Chunks m_chunks; Optional m_expected_size; diff --git a/Libraries/LibMedia/PlaybackManager.h b/Libraries/LibMedia/PlaybackManager.h index f12338ed8b..6ad78a9d9d 100644 --- a/Libraries/LibMedia/PlaybackManager.h +++ b/Libraries/LibMedia/PlaybackManager.h @@ -22,7 +22,7 @@ #include #include #include -#include +#include namespace Media { @@ -223,7 +223,7 @@ public: void revoke(Badge) { - Threading::MutexLocker locker { m_mutex }; + Sync::MutexLocker locker { m_mutex }; m_manager = nullptr; } @@ -234,7 +234,7 @@ private: VERIFY(&Core::EventLoop::current() == &m_originating_event_loop); } - mutable Threading::Mutex m_mutex; + mutable Sync::Mutex m_mutex; PlaybackManager* m_manager { nullptr }; Core::EventLoop& m_originating_event_loop; }; diff --git a/Libraries/LibMedia/Providers/AudioDataProvider.cpp b/Libraries/LibMedia/Providers/AudioDataProvider.cpp index a8f09ca40d..d9a13507ba 100644 --- a/Libraries/LibMedia/Providers/AudioDataProvider.cpp +++ b/Libraries/LibMedia/Providers/AudioDataProvider.cpp @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include "AudioDataProvider.h" diff --git a/Libraries/LibMedia/Providers/AudioDataProvider.h b/Libraries/LibMedia/Providers/AudioDataProvider.h index 4acc507f10..02a7d3a921 100644 --- a/Libraries/LibMedia/Providers/AudioDataProvider.h +++ b/Libraries/LibMedia/Providers/AudioDataProvider.h @@ -20,9 +20,9 @@ #include #include #include -#include +#include +#include #include -#include namespace Media { @@ -103,7 +103,7 @@ private: void seek(AK::Duration timestamp, SeekCompletionHandler&&); - [[nodiscard]] Threading::MutexLocker take_lock() const { return Threading::MutexLocker(m_mutex); } + [[nodiscard]] Sync::MutexLocker take_lock() const { return Sync::MutexLocker(m_mutex); } void wake() const { m_wait_condition.broadcast(); } AudioDecoder const& decoder() const { return *m_decoder; } @@ -120,8 +120,8 @@ private: NonnullRefPtr m_main_thread_event_loop; - mutable Threading::Mutex m_mutex; - mutable Threading::ConditionVariable m_wait_condition { m_mutex }; + mutable Sync::Mutex m_mutex; + mutable Sync::ConditionVariable m_wait_condition { m_mutex }; RequestedState m_requested_state { RequestedState::None }; NonnullRefPtr m_demuxer; diff --git a/Libraries/LibMedia/Providers/VideoDataProvider.h b/Libraries/LibMedia/Providers/VideoDataProvider.h index db7ef16eae..90ff833477 100644 --- a/Libraries/LibMedia/Providers/VideoDataProvider.h +++ b/Libraries/LibMedia/Providers/VideoDataProvider.h @@ -20,8 +20,8 @@ #include #include #include -#include -#include +#include +#include namespace Media { @@ -100,7 +100,7 @@ private: TimeRanges buffered_time_ranges() const; - [[nodiscard]] Threading::MutexLocker take_lock() const { return Threading::MutexLocker(m_mutex); } + [[nodiscard]] Sync::MutexLocker take_lock() const { return Sync::MutexLocker(m_mutex); } void wake() const { m_wait_condition.broadcast(); } private: @@ -113,8 +113,8 @@ private: NonnullRefPtr m_main_thread_event_loop; - mutable Threading::Mutex m_mutex; - mutable Threading::ConditionVariable m_wait_condition { m_mutex }; + mutable Sync::Mutex m_mutex; + mutable Sync::ConditionVariable m_wait_condition { m_mutex }; RequestedState m_requested_state { RequestedState::None }; NonnullRefPtr m_demuxer; diff --git a/Libraries/LibMedia/Sinks/AudioMixingSink.cpp b/Libraries/LibMedia/Sinks/AudioMixingSink.cpp index f1313337f2..89db38f027 100644 --- a/Libraries/LibMedia/Sinks/AudioMixingSink.cpp +++ b/Libraries/LibMedia/Sinks/AudioMixingSink.cpp @@ -39,7 +39,7 @@ AudioMixingSink::~AudioMixingSink() void AudioMixingSink::set_provider(Track const& track, RefPtr const& provider) { - Threading::MutexLocker locker { m_mutex }; + Sync::MutexLocker locker { m_mutex }; m_track_mixing_datas.remove(track); if (provider == nullptr) return; @@ -89,7 +89,7 @@ void AudioMixingSink::create_playback_stream() if (self->m_temporary_time.has_value()) self->set_time(self->m_temporary_time.value()); - Threading::MutexLocker locker { self->m_mutex }; + Sync::MutexLocker locker { self->m_mutex }; self->m_sample_specification = stream->sample_specification(); for (auto& [track, track_data] : self->m_track_mixing_datas) { @@ -121,7 +121,7 @@ ReadonlySpan AudioMixingSink::write_audio_data_to_playback_stream(Span(sample_count); @@ -341,7 +341,7 @@ void AudioMixingSink::set_time(AK::Duration time) self->m_last_media_time = self->m_temporary_time.release_value(); { - Threading::MutexLocker mixing_locker { self->m_mutex }; + Sync::MutexLocker mixing_locker { self->m_mutex }; self->m_next_sample_to_write = self->m_last_media_time.to_time_units(1, self->m_sample_specification.sample_rate()); } diff --git a/Libraries/LibMedia/Sinks/AudioMixingSink.h b/Libraries/LibMedia/Sinks/AudioMixingSink.h index fb7f8f9314..ad47677edf 100644 --- a/Libraries/LibMedia/Sinks/AudioMixingSink.h +++ b/Libraries/LibMedia/Sinks/AudioMixingSink.h @@ -15,8 +15,8 @@ #include #include #include -#include -#include +#include +#include namespace Media { @@ -53,17 +53,17 @@ private: void emplace(AudioMixingSink& sink) { m_ptr = &sink; } RefPtr take_strong() const { - Threading::MutexLocker locker { m_mutex }; + Sync::MutexLocker locker { m_mutex }; return m_ptr; } void revoke() { - Threading::MutexLocker locker { m_mutex }; + Sync::MutexLocker locker { m_mutex }; m_ptr = nullptr; } private: - mutable Threading::Mutex m_mutex; + mutable Sync::Mutex m_mutex; AudioMixingSink* m_ptr { nullptr }; }; @@ -84,8 +84,8 @@ private: Core::EventLoop& m_main_thread_event_loop; NonnullRefPtr m_weak_self; - Threading::Mutex m_mutex; - Threading::ConditionVariable m_wait_condition { m_mutex }; + Sync::Mutex m_mutex; + Sync::ConditionVariable m_wait_condition { m_mutex }; bool m_creating_playback_stream { false }; RefPtr m_playback_stream; Audio::SampleSpecification m_sample_specification; diff --git a/Libraries/LibSync/CMakeLists.txt b/Libraries/LibSync/CMakeLists.txt new file mode 100644 index 0000000000..4c1bf3dc7e --- /dev/null +++ b/Libraries/LibSync/CMakeLists.txt @@ -0,0 +1,5 @@ +set(SOURCES + Mutex.cpp +) +ladybird_lib(LibSync sync EXPLICIT_SYMBOL_EXPORT) + diff --git a/Libraries/LibThreading/ConditionVariable.h b/Libraries/LibSync/ConditionVariable.h similarity index 96% rename from Libraries/LibThreading/ConditionVariable.h rename to Libraries/LibSync/ConditionVariable.h index 6996de7eb9..7645baaab9 100644 --- a/Libraries/LibThreading/ConditionVariable.h +++ b/Libraries/LibSync/ConditionVariable.h @@ -7,11 +7,11 @@ #pragma once #include -#include +#include #include #include -namespace Threading { +namespace Sync { // A signaling condition variable that wraps over the pthread_cond_* APIs. class ConditionVariable { diff --git a/Libraries/LibSync/Mutex.cpp b/Libraries/LibSync/Mutex.cpp new file mode 100644 index 0000000000..bb7ab7f43b --- /dev/null +++ b/Libraries/LibSync/Mutex.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018-2021, Andreas Kling + * Copyright (c) 2021, kleines Filmröllchen + * Copyright (c) 2025, Ryszard Goc + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include + +namespace Sync { + +Mutex::Mutex() + : m_lock_count(0) +{ + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&m_mutex, &attr); + pthread_mutexattr_destroy(&attr); +} + +Mutex::~Mutex() +{ + VERIFY(m_lock_count == 0); + pthread_mutex_destroy(&m_mutex); +} + +} diff --git a/Libraries/LibThreading/Mutex.h b/Libraries/LibSync/Mutex.h similarity index 75% rename from Libraries/LibThreading/Mutex.h rename to Libraries/LibSync/Mutex.h index 64e9104e49..5316ce9850 100644 --- a/Libraries/LibThreading/Mutex.h +++ b/Libraries/LibSync/Mutex.h @@ -10,30 +10,19 @@ #include #include #include +#include #include -namespace Threading { +namespace Sync { -class Mutex { +class SYNC_API Mutex { AK_MAKE_NONCOPYABLE(Mutex); AK_MAKE_NONMOVABLE(Mutex); friend class ConditionVariable; public: - Mutex() - : m_lock_count(0) - { - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init(&m_mutex, &attr); - pthread_mutexattr_destroy(&attr); - } - ~Mutex() - { - VERIFY(m_lock_count == 0); - pthread_mutex_destroy(&m_mutex); - } + Mutex(); + ~Mutex(); void lock(); void unlock(); @@ -43,7 +32,7 @@ private: unsigned m_lock_count { 0 }; }; -class [[nodiscard]] MutexLocker { +class [[nodiscard]] SYNC_API MutexLocker { AK_MAKE_NONCOPYABLE(MutexLocker); AK_MAKE_NONMOVABLE(MutexLocker); diff --git a/Libraries/LibThreading/MutexProtected.h b/Libraries/LibSync/MutexProtected.h similarity index 95% rename from Libraries/LibThreading/MutexProtected.h rename to Libraries/LibSync/MutexProtected.h index c48d80983c..e1c2266b3d 100644 --- a/Libraries/LibThreading/MutexProtected.h +++ b/Libraries/LibSync/MutexProtected.h @@ -8,9 +8,9 @@ #include #include -#include +#include -namespace Threading { +namespace Sync { template class MutexProtected { diff --git a/Libraries/LibThreading/Once.h b/Libraries/LibSync/Once.h similarity index 87% rename from Libraries/LibThreading/Once.h rename to Libraries/LibSync/Once.h index f65688822b..e721e8fbd6 100644 --- a/Libraries/LibThreading/Once.h +++ b/Libraries/LibSync/Once.h @@ -8,12 +8,12 @@ #include #include -#include +#include -namespace Threading { +namespace Sync { struct OnceFlag { - Mutex mutex; + Sync::Mutex mutex; Atomic has_been_called { false }; }; @@ -21,7 +21,7 @@ template void call_once(OnceFlag& flag, Callable&& callable) { if (!flag.has_been_called.load(MemoryOrder::memory_order_acquire)) { - MutexLocker lock(flag.mutex); + Sync::MutexLocker lock(flag.mutex); // Another thread may have called the function while we were waiting on the mutex // The mutex guarantees exclusivity so we can use relaxed ordering diff --git a/Libraries/LibThreading/RWLock.h b/Libraries/LibSync/RWLock.h similarity index 98% rename from Libraries/LibThreading/RWLock.h rename to Libraries/LibSync/RWLock.h index a880e857a6..0bf8c8c229 100644 --- a/Libraries/LibThreading/RWLock.h +++ b/Libraries/LibSync/RWLock.h @@ -11,7 +11,7 @@ #include #include -namespace Threading { +namespace Sync { class RWLock { AK_MAKE_NONCOPYABLE(RWLock); diff --git a/Libraries/LibThreading/RWLockProtected.h b/Libraries/LibSync/RWLockProtected.h similarity index 96% rename from Libraries/LibThreading/RWLockProtected.h rename to Libraries/LibSync/RWLockProtected.h index 16d2d86b9d..cf3f9be913 100644 --- a/Libraries/LibThreading/RWLockProtected.h +++ b/Libraries/LibSync/RWLockProtected.h @@ -8,9 +8,9 @@ #include #include -#include +#include -namespace Threading { +namespace Sync { template class RWLockProtected { diff --git a/Libraries/LibThreading/BackgroundAction.cpp b/Libraries/LibThreading/BackgroundAction.cpp index ee43207948..c1a61e5f00 100644 --- a/Libraries/LibThreading/BackgroundAction.cpp +++ b/Libraries/LibThreading/BackgroundAction.cpp @@ -6,8 +6,8 @@ */ #include +#include #include -#include #include static pthread_mutex_t s_mutex = PTHREAD_MUTEX_INITIALIZER; diff --git a/Libraries/LibThreading/CMakeLists.txt b/Libraries/LibThreading/CMakeLists.txt index 9c77abaf11..a6ae6ccfe8 100644 --- a/Libraries/LibThreading/CMakeLists.txt +++ b/Libraries/LibThreading/CMakeLists.txt @@ -5,7 +5,7 @@ set(SOURCES ) ladybird_lib(LibThreading threading) -target_link_libraries(LibThreading PRIVATE LibCore) +target_link_libraries(LibThreading PRIVATE LibCore LibSync) if (WIN32) target_include_directories(LibThreading PUBLIC $) diff --git a/Libraries/LibThreading/ThreadPool.cpp b/Libraries/LibThreading/ThreadPool.cpp index 7cb81c7ea6..11473f9cd5 100644 --- a/Libraries/LibThreading/ThreadPool.cpp +++ b/Libraries/LibThreading/ThreadPool.cpp @@ -36,7 +36,7 @@ intptr_t ThreadPool::worker_thread_func() Function work; { - MutexLocker locker(m_mutex); + Sync::MutexLocker locker(m_mutex); m_condition.wait_while([this] { return m_work_queue.is_empty(); }); work = m_work_queue.dequeue(); } @@ -47,7 +47,7 @@ intptr_t ThreadPool::worker_thread_func() void ThreadPool::submit(Function work) { - MutexLocker locker(m_mutex); + Sync::MutexLocker locker(m_mutex); m_work_queue.enqueue(move(work)); m_condition.signal(); } diff --git a/Libraries/LibThreading/ThreadPool.h b/Libraries/LibThreading/ThreadPool.h index 01fc778727..c6148e4bcf 100644 --- a/Libraries/LibThreading/ThreadPool.h +++ b/Libraries/LibThreading/ThreadPool.h @@ -9,8 +9,8 @@ #include #include #include -#include -#include +#include +#include #include namespace Threading { @@ -26,8 +26,8 @@ private: intptr_t worker_thread_func(); - Mutex m_mutex; - ConditionVariable m_condition { m_mutex }; + Sync::Mutex m_mutex; + Sync::ConditionVariable m_condition { m_mutex }; Queue> m_work_queue; Vector> m_threads; }; diff --git a/Libraries/LibWeb/CMakeLists.txt b/Libraries/LibWeb/CMakeLists.txt index 6538d7a079..171500a993 100644 --- a/Libraries/LibWeb/CMakeLists.txt +++ b/Libraries/LibWeb/CMakeLists.txt @@ -1247,7 +1247,7 @@ set(GENERATED_SOURCES ladybird_lib(LibWeb web EXPLICIT_SYMBOL_EXPORT) -target_link_libraries(LibWeb PRIVATE LibCore LibCompress LibCrypto LibJS LibHTTP LibGfx LibIPC LibRegex LibSyntax LibTextCodec LibUnicode LibMedia LibWasm LibXML LibIDL LibURL LibTLS LibRequests LibGC LibThreading skia ${ANGLE_TARGETS} SDL3::SDL3 LibXml2::LibXml2) +target_link_libraries(LibWeb PRIVATE LibCore LibCompress LibCrypto LibJS LibHTTP LibGfx LibIPC LibRegex LibSyntax LibTextCodec LibUnicode LibMedia LibWasm LibXML LibIDL LibURL LibTLS LibRequests LibGC LibSync LibThreading skia ${ANGLE_TARGETS} SDL3::SDL3 LibXml2::LibXml2) import_rust_crate(MANIFEST_PATH Rust/Cargo.toml CRATE_NAME libweb_rust FFI_HEADER RustFFI.h) target_link_libraries(LibWeb PRIVATE libweb_rust) diff --git a/Libraries/LibWeb/HTML/RenderingThread.cpp b/Libraries/LibWeb/HTML/RenderingThread.cpp index 3695824b9e..d64b159fdb 100644 --- a/Libraries/LibWeb/HTML/RenderingThread.cpp +++ b/Libraries/LibWeb/HTML/RenderingThread.cpp @@ -145,13 +145,13 @@ public: void set_presentation_mode(RenderingThread::PresentationMode mode) { - Threading::MutexLocker const locker { m_mutex }; + Sync::MutexLocker const locker { m_mutex }; m_presentation_mode = move(mode); } void exit() { - Threading::MutexLocker const locker { m_mutex }; + Sync::MutexLocker const locker { m_mutex }; m_exit = true; m_command_ready.signal(); m_ready_to_paint.signal(); @@ -160,14 +160,14 @@ public: void enqueue_command(CompositorCommand&& command) { - Threading::MutexLocker const locker { m_mutex }; + Sync::MutexLocker const locker { m_mutex }; m_command_queue.enqueue(move(command)); m_command_ready.signal(); } u64 set_needs_present(Gfx::IntRect viewport_rect) { - Threading::MutexLocker const locker { m_mutex }; + Sync::MutexLocker const locker { m_mutex }; m_needs_present = true; m_pending_viewport_rect = viewport_rect; m_submitted_frame_id++; @@ -177,14 +177,14 @@ public: void mark_frame_complete(u64 frame_id) { - Threading::MutexLocker const locker { m_mutex }; + Sync::MutexLocker const locker { m_mutex }; m_completed_frame_id = frame_id; m_frame_completed.broadcast(); } void wait_for_frame(u64 frame_id) { - Threading::MutexLocker const locker { m_mutex }; + Sync::MutexLocker const locker { m_mutex }; while (m_completed_frame_id < frame_id && !m_exit) m_frame_completed.wait(); } @@ -195,7 +195,7 @@ public: while (true) { { - Threading::MutexLocker const locker { m_mutex }; + Sync::MutexLocker const locker { m_mutex }; while (m_command_queue.is_empty() && !m_needs_present && !m_exit) { m_command_ready.wait(); } @@ -209,7 +209,7 @@ public: while (true) { auto command = [this]() -> Optional { - Threading::MutexLocker const locker { m_mutex }; + Sync::MutexLocker const locker { m_mutex }; if (m_command_queue.is_empty()) return {}; return m_command_queue.dequeue(); @@ -250,7 +250,7 @@ public: Gfx::IntRect viewport_rect; u64 presenting_frame_id = 0; { - Threading::MutexLocker const locker { m_mutex }; + Sync::MutexLocker const locker { m_mutex }; if (m_needs_present) { should_present = true; viewport_rect = m_pending_viewport_rect; @@ -262,7 +262,7 @@ public: if (should_present) { // Block if we already have a frame queued (back pressure) { - Threading::MutexLocker const locker { m_mutex }; + Sync::MutexLocker const locker { m_mutex }; while (m_queued_rasterization_tasks > 1 && !m_exit) { m_ready_to_paint.wait(); } @@ -271,7 +271,7 @@ public: } auto presentation_mode = [this] { - Threading::MutexLocker const locker { m_mutex }; + Sync::MutexLocker const locker { m_mutex }; return m_presentation_mode; }(); @@ -368,8 +368,8 @@ private: NonnullRefPtr m_main_thread_event_loop; RenderingThread::PresentationCallback m_presentation_callback; - mutable Threading::Mutex m_mutex; - mutable Threading::ConditionVariable m_command_ready { m_mutex }; + mutable Sync::Mutex m_mutex; + mutable Sync::ConditionVariable m_command_ready { m_mutex }; Atomic m_exit { false }; Queue m_command_queue; @@ -382,19 +382,19 @@ private: RenderingThread::PresentationMode m_presentation_mode { RenderingThread::PresentToUI {} }; Atomic m_queued_rasterization_tasks { 0 }; - mutable Threading::ConditionVariable m_ready_to_paint { m_mutex }; + mutable Sync::ConditionVariable m_ready_to_paint { m_mutex }; bool m_needs_present { false }; Gfx::IntRect m_pending_viewport_rect; u64 m_submitted_frame_id { 0 }; u64 m_completed_frame_id { 0 }; - mutable Threading::ConditionVariable m_frame_completed { m_mutex }; + mutable Sync::ConditionVariable m_frame_completed { m_mutex }; public: void decrement_queued_tasks() { - Threading::MutexLocker const locker { m_mutex }; + Sync::MutexLocker const locker { m_mutex }; VERIFY(m_queued_rasterization_tasks >= 1 && m_queued_rasterization_tasks <= 2); m_queued_rasterization_tasks--; m_ready_to_paint.signal(); diff --git a/Libraries/LibWeb/HTML/RenderingThread.h b/Libraries/LibWeb/HTML/RenderingThread.h index 9097498dff..d4ac361793 100644 --- a/Libraries/LibWeb/HTML/RenderingThread.h +++ b/Libraries/LibWeb/HTML/RenderingThread.h @@ -11,9 +11,8 @@ #include #include #include -#include +#include #include -#include #include #include diff --git a/Libraries/LibWeb/MediaSourceExtensions/TrackBufferDemuxer.cpp b/Libraries/LibWeb/MediaSourceExtensions/TrackBufferDemuxer.cpp index 26c4fb03e6..523f0d1238 100644 --- a/Libraries/LibWeb/MediaSourceExtensions/TrackBufferDemuxer.cpp +++ b/Libraries/LibWeb/MediaSourceExtensions/TrackBufferDemuxer.cpp @@ -20,7 +20,7 @@ TrackBufferDemuxer::~TrackBufferDemuxer() = default; Media::TimeRanges TrackBufferDemuxer::track_buffer_ranges() const { - Threading::MutexLocker locker { m_mutex }; + Sync::MutexLocker locker { m_mutex }; // https://w3c.github.io/media-source/#track-buffer-ranges // NOTE: Implementations MAY coalesce adjacent ranges separated by a gap smaller than 2 times the // maximum frame duration buffered so far in this track buffer. @@ -32,7 +32,7 @@ Media::TimeRanges TrackBufferDemuxer::track_buffer_ranges() const void TrackBufferDemuxer::add_coded_frame(Media::CodedFrame frame) { - Threading::MutexLocker locker { m_mutex }; + Sync::MutexLocker locker { m_mutex }; auto start = frame.timestamp(); auto end = frame.timestamp() + frame.duration(); m_last_frame_duration = frame.duration(); @@ -60,7 +60,7 @@ void TrackBufferDemuxer::add_coded_frame(Media::CodedFrame frame) void TrackBufferDemuxer::remove_coded_frames_and_dependants_in_range(AK::Duration start, AK::Duration end) { - Threading::MutexLocker locker { m_mutex }; + Sync::MutexLocker locker { m_mutex }; // https://w3c.github.io/media-source/#sourcebuffer-coded-frame-processing // 1.13. Remove all coded frames from track buffer that have a presentation timestamp greater than @@ -107,14 +107,14 @@ void TrackBufferDemuxer::remove_coded_frames_and_dependants_in_range(AK::Duratio void TrackBufferDemuxer::set_reached_end_of_stream() { - Threading::MutexLocker locker { m_mutex }; + Sync::MutexLocker locker { m_mutex }; m_reached_end_of_stream = true; m_data_changed.broadcast(); } void TrackBufferDemuxer::clear_reached_end_of_stream() { - Threading::MutexLocker locker { m_mutex }; + Sync::MutexLocker locker { m_mutex }; m_reached_end_of_stream = false; } @@ -155,7 +155,7 @@ bool TrackBufferDemuxer::next_frame_is_in_gap_while_locked() const Media::DecoderErrorOr TrackBufferDemuxer::get_next_sample_for_track(Media::Track const&) { - Threading::MutexLocker locker { m_mutex }; + Sync::MutexLocker locker { m_mutex }; while (m_read_position >= m_coded_frames.size() || next_frame_is_in_gap_while_locked()) { if (m_aborted.load()) @@ -181,7 +181,7 @@ Media::DecoderErrorOr TrackBufferDemuxer::get_codec_initializatio Media::DecoderErrorOr TrackBufferDemuxer::seek_to_most_recent_keyframe(Media::Track const&, AK::Duration timestamp, Media::DemuxerSeekOptions) { - Threading::MutexLocker locker { m_mutex }; + Sync::MutexLocker locker { m_mutex }; size_t best_position = 0; AK::Duration best_timestamp; @@ -254,7 +254,7 @@ Media::TimeRanges TrackBufferDemuxer::buffered_time_ranges() const void TrackBufferDemuxer::set_blocking_reads_aborted_for_track(Media::Track const&) { m_aborted.store(true); - Threading::MutexLocker locker { m_mutex }; + Sync::MutexLocker locker { m_mutex }; m_data_changed.broadcast(); } @@ -265,7 +265,7 @@ void TrackBufferDemuxer::reset_blocking_reads_aborted_for_track(Media::Track con bool TrackBufferDemuxer::is_read_blocked_for_track(Media::Track const&) { - Threading::MutexLocker locker { m_mutex }; + Sync::MutexLocker locker { m_mutex }; if (m_aborted.load()) return false; return m_read_position >= m_coded_frames.size() || next_frame_is_in_gap_while_locked(); diff --git a/Libraries/LibWeb/MediaSourceExtensions/TrackBufferDemuxer.h b/Libraries/LibWeb/MediaSourceExtensions/TrackBufferDemuxer.h index 90a71ecf11..4b7fb796e8 100644 --- a/Libraries/LibWeb/MediaSourceExtensions/TrackBufferDemuxer.h +++ b/Libraries/LibWeb/MediaSourceExtensions/TrackBufferDemuxer.h @@ -13,8 +13,8 @@ #include #include #include -#include -#include +#include +#include namespace Web::MediaSourceExtensions { @@ -60,8 +60,8 @@ private: Media::CodecID m_codec_id; ByteBuffer m_codec_initialization_data; - mutable Threading::Mutex m_mutex; - Threading::ConditionVariable m_data_changed { m_mutex }; + mutable Sync::Mutex m_mutex; + Sync::ConditionVariable m_data_changed { m_mutex }; Vector m_coded_frames; size_t m_read_position { 0 }; diff --git a/Libraries/LibWeb/Painting/ExternalContentSource.cpp b/Libraries/LibWeb/Painting/ExternalContentSource.cpp index dc762d19e7..ae8dacf4c4 100644 --- a/Libraries/LibWeb/Painting/ExternalContentSource.cpp +++ b/Libraries/LibWeb/Painting/ExternalContentSource.cpp @@ -26,7 +26,7 @@ void ExternalContentSource::update(Optional frame) { Optional old; { - Threading::MutexLocker const locker { m_mutex }; + Sync::MutexLocker const locker { m_mutex }; old = move(m_frame); m_frame = move(frame); } @@ -36,14 +36,14 @@ void ExternalContentSource::clear() { Optional old; { - Threading::MutexLocker const locker { m_mutex }; + Sync::MutexLocker const locker { m_mutex }; old = move(m_frame); } } Optional ExternalContentSource::current_frame() const { - Threading::MutexLocker const locker { m_mutex }; + Sync::MutexLocker const locker { m_mutex }; return m_frame; } diff --git a/Libraries/LibWeb/Painting/ExternalContentSource.h b/Libraries/LibWeb/Painting/ExternalContentSource.h index 610b028ac7..60453a91ac 100644 --- a/Libraries/LibWeb/Painting/ExternalContentSource.h +++ b/Libraries/LibWeb/Painting/ExternalContentSource.h @@ -11,7 +11,7 @@ #include #include #include -#include +#include namespace Web::Painting { @@ -29,7 +29,7 @@ private: ExternalContentSource(); u64 m_id { 0 }; - mutable Threading::Mutex m_mutex; + mutable Sync::Mutex m_mutex; Optional m_frame; }; diff --git a/Libraries/LibWeb/Painting/VideoFrameSource.cpp b/Libraries/LibWeb/Painting/VideoFrameSource.cpp index 8db78fc65d..e63f7cdc89 100644 --- a/Libraries/LibWeb/Painting/VideoFrameSource.cpp +++ b/Libraries/LibWeb/Painting/VideoFrameSource.cpp @@ -28,7 +28,7 @@ void VideoFrameSource::update(RefPtr frame) { RefPtr old; { - Threading::MutexLocker const locker { m_mutex }; + Sync::MutexLocker const locker { m_mutex }; old = move(m_frame); m_frame = move(frame); } @@ -38,14 +38,14 @@ void VideoFrameSource::clear() { RefPtr old; { - Threading::MutexLocker const locker { m_mutex }; + Sync::MutexLocker const locker { m_mutex }; old = move(m_frame); } } RefPtr VideoFrameSource::current_frame() const { - Threading::MutexLocker const locker { m_mutex }; + Sync::MutexLocker const locker { m_mutex }; return m_frame; } diff --git a/Libraries/LibWeb/Painting/VideoFrameSource.h b/Libraries/LibWeb/Painting/VideoFrameSource.h index 023867a993..84f9f29b56 100644 --- a/Libraries/LibWeb/Painting/VideoFrameSource.h +++ b/Libraries/LibWeb/Painting/VideoFrameSource.h @@ -9,7 +9,7 @@ #include #include #include -#include +#include namespace Web::Painting { @@ -28,7 +28,7 @@ private: VideoFrameSource(); u64 m_id { 0 }; - mutable Threading::Mutex m_mutex; + mutable Sync::Mutex m_mutex; RefPtr m_frame; }; diff --git a/Libraries/LibWeb/WebAudio/ControlMessageQueue.cpp b/Libraries/LibWeb/WebAudio/ControlMessageQueue.cpp index e327b46514..d2268c6a94 100644 --- a/Libraries/LibWeb/WebAudio/ControlMessageQueue.cpp +++ b/Libraries/LibWeb/WebAudio/ControlMessageQueue.cpp @@ -9,13 +9,13 @@ namespace Web::WebAudio { void ControlMessageQueue::enqueue(ControlMessage message) { - Threading::MutexLocker locker(m_mutex); + Sync::MutexLocker locker(m_mutex); m_messages.append(move(message)); } Vector ControlMessageQueue::drain() { - Threading::MutexLocker locker(m_mutex); + Sync::MutexLocker locker(m_mutex); return move(m_messages); } diff --git a/Libraries/LibWeb/WebAudio/ControlMessageQueue.h b/Libraries/LibWeb/WebAudio/ControlMessageQueue.h index b3826efee1..5104943a97 100644 --- a/Libraries/LibWeb/WebAudio/ControlMessageQueue.h +++ b/Libraries/LibWeb/WebAudio/ControlMessageQueue.h @@ -7,7 +7,7 @@ #pragma once #include -#include +#include #include #include @@ -21,7 +21,7 @@ public: Vector drain(); // Called by the rendering thread. private: - mutable Threading::Mutex m_mutex; + mutable Sync::Mutex m_mutex; Vector m_messages; }; diff --git a/Libraries/LibWebView/CMakeLists.txt b/Libraries/LibWebView/CMakeLists.txt index 3798e747b4..9490f0b791 100644 --- a/Libraries/LibWebView/CMakeLists.txt +++ b/Libraries/LibWebView/CMakeLists.txt @@ -75,7 +75,7 @@ compile_ipc(${LADYBIRD_SOURCE_DIR}/Services/WebContent/WebUIClient.ipc ${CMAKE_B compile_ipc(${LADYBIRD_SOURCE_DIR}/Services/WebContent/WebUIServer.ipc ${CMAKE_BINARY_DIR}/Services/WebContent/WebUIServerEndpoint.h) ladybird_lib(LibWebView webview EXPLICIT_SYMBOL_EXPORT) -target_link_libraries(LibWebView PRIVATE LibCore LibDatabase LibDevTools LibFileSystem LibGfx LibHTTP LibImageDecoderClient LibIPC LibRequests LibJS LibWeb LibUnicode LibURL LibSyntax LibTextCodec) +target_link_libraries(LibWebView PRIVATE LibCore LibDatabase LibDevTools LibFileSystem LibGfx LibHTTP LibImageDecoderClient LibIPC LibRequests LibJS LibWeb LibUnicode LibURL LibSync LibSyntax LibTextCodec) # Third-party if (HAS_FONTCONFIG) diff --git a/Libraries/LibWebView/Process.cpp b/Libraries/LibWebView/Process.cpp index d9a19d6437..98bc504fe0 100644 --- a/Libraries/LibWebView/Process.cpp +++ b/Libraries/LibWebView/Process.cpp @@ -69,7 +69,7 @@ ErrorOr Process::spawn_and_connect_to_process(C auto port_b_recv = TRY(Core::MachPort::create_with_right(Core::MachPort::PortRight::Receive)); auto port_b_send = TRY(port_b_recv.insert_right(Core::MachPort::MessageRight::MakeSend)); - Threading::MutexLocker child_registration_locker(Application::transport_bootstrap_server().child_registration_lock()); + Sync::MutexLocker child_registration_locker(Application::transport_bootstrap_server().child_registration_lock()); auto process = TRY(Core::Process::spawn(spawn_options)); Application::transport_bootstrap_server().register_child_transport(process.pid(), IPC::TransportBootstrapMachPorts { move(port_b_recv), move(port_a_send) }); diff --git a/Services/ImageDecoder/CMakeLists.txt b/Services/ImageDecoder/CMakeLists.txt index 5a3375b5a9..ac2a45b0cb 100644 --- a/Services/ImageDecoder/CMakeLists.txt +++ b/Services/ImageDecoder/CMakeLists.txt @@ -23,7 +23,7 @@ target_include_directories(imagedecoderservice PRIVATE ${CMAKE_CURRENT_BINARY_DI target_include_directories(imagedecoderservice PRIVATE ${LADYBIRD_SOURCE_DIR}/Services/) target_link_libraries(ImageDecoder PRIVATE imagedecoderservice LibCore LibMain LibThreading) -target_link_libraries(imagedecoderservice PRIVATE LibCore LibGfx LibIPC LibImageDecoderClient LibMain LibThreading) +target_link_libraries(imagedecoderservice PRIVATE LibCore LibGfx LibIPC LibImageDecoderClient LibMain LibSync LibThreading) if (WIN32) ladybird_windows_bin(ImageDecoder CONSOLE) diff --git a/Services/WebDriver/CMakeLists.txt b/Services/WebDriver/CMakeLists.txt index 7eaa567236..ec5a1fba14 100644 --- a/Services/WebDriver/CMakeLists.txt +++ b/Services/WebDriver/CMakeLists.txt @@ -12,7 +12,7 @@ target_include_directories(WebDriver PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/../..) target_include_directories(WebDriver PRIVATE ${LADYBIRD_SOURCE_DIR}) target_include_directories(WebDriver PRIVATE ${LADYBIRD_SOURCE_DIR}/Services) -target_link_libraries(WebDriver PRIVATE LibCore LibFileSystem LibGfx LibIPC LibJS LibMain LibWeb LibWebSocket LibWebView) +target_link_libraries(WebDriver PRIVATE LibCore LibFileSystem LibGfx LibIPC LibJS LibMain LibSync LibWeb LibWebSocket LibWebView) target_link_libraries(WebDriver PRIVATE OpenSSL::Crypto OpenSSL::SSL) if (WIN32) diff --git a/Tests/LibCore/CMakeLists.txt b/Tests/LibCore/CMakeLists.txt index 9d152ec36e..44755da08f 100644 --- a/Tests/LibCore/CMakeLists.txt +++ b/Tests/LibCore/CMakeLists.txt @@ -20,12 +20,12 @@ foreach(source IN LISTS TEST_SOURCES) ladybird_test("${source}" LibCore) endforeach() -target_link_libraries(TestLibCorePromise PRIVATE LibThreading) -target_link_libraries(TestLibCoreStream PRIVATE LibThreading) +target_link_libraries(TestLibCorePromise PRIVATE LibSync LibThreading) +target_link_libraries(TestLibCoreStream PRIVATE LibSync LibThreading) if(NOT WIN32) # These tests use the .txt files in the current directory set_tests_properties(TestLibCoreMappedFile TestLibCoreStream PROPERTIES WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}") endif() -target_link_libraries(TestLibCoreEventLoop PRIVATE LibThreading) +target_link_libraries(TestLibCoreEventLoop PRIVATE LibSync LibThreading) diff --git a/Tests/LibMedia/CMakeLists.txt b/Tests/LibMedia/CMakeLists.txt index 9c1d6a5b46..78d0914b96 100644 --- a/Tests/LibMedia/CMakeLists.txt +++ b/Tests/LibMedia/CMakeLists.txt @@ -18,7 +18,7 @@ set(TEST_SOURCES ) foreach(source IN LISTS TEST_SOURCES) - ladybird_test("${source}" LibMedia LIBS LibMedia LibFileSystem) + ladybird_test("${source}" LibMedia LIBS LibMedia LibFileSystem LibSync) endforeach() target_link_libraries(TestFFmpegDemuxer PRIVATE LibThreading) diff --git a/Tests/LibThreading/CMakeLists.txt b/Tests/LibThreading/CMakeLists.txt index f6890c89fe..afb74b4154 100644 --- a/Tests/LibThreading/CMakeLists.txt +++ b/Tests/LibThreading/CMakeLists.txt @@ -6,3 +6,5 @@ set(TEST_SOURCES foreach(source IN LISTS TEST_SOURCES) ladybird_test("${source}" LibThreading LIBS LibThreading) endforeach() + +target_link_libraries(TestBackgroundAction PRIVATE LibSync) diff --git a/Tests/LibWeb/CMakeLists.txt b/Tests/LibWeb/CMakeLists.txt index b675501b93..41d518f767 100644 --- a/Tests/LibWeb/CMakeLists.txt +++ b/Tests/LibWeb/CMakeLists.txt @@ -24,6 +24,7 @@ endforeach() ladybird_utility(css-tokenizer SOURCES css-tokenizer.cpp LIBS LibFileSystem LibMain LibWeb) target_link_libraries(TestContentFilter PRIVATE LibURL) +target_link_libraries(TestControlMessageQueue PRIVATE LibSync) target_link_libraries(TestFetchURL PRIVATE LibURL) target_link_libraries(TestSourceHighlighter PRIVATE LibURL LibWebView) diff --git a/UI/AppKit/Application/EventLoopImplementationMacOS.mm b/UI/AppKit/Application/EventLoopImplementationMacOS.mm index 6cecfdd71f..bf4e101814 100644 --- a/UI/AppKit/Application/EventLoopImplementationMacOS.mm +++ b/UI/AppKit/Application/EventLoopImplementationMacOS.mm @@ -13,7 +13,7 @@ #include #include #include -#include +#include #import #import @@ -28,7 +28,7 @@ struct ThreadData; static thread_local OwnPtr s_this_thread_data; static HashMap s_thread_data; static thread_local pthread_t s_thread_id; -static Threading::RWLock s_thread_data_lock; +static Sync::RWLock s_thread_data_lock; struct ThreadData { static ThreadData& the() @@ -37,7 +37,7 @@ struct ThreadData { s_thread_id = pthread_self(); if (!s_this_thread_data) { s_this_thread_data = make(); - Threading::RWLockLocker locker(s_thread_data_lock); + Sync::RWLockLocker locker(s_thread_data_lock); s_thread_data.set(s_thread_id, s_this_thread_data); } return *s_this_thread_data; @@ -45,13 +45,13 @@ struct ThreadData { static ThreadData* for_thread(pthread_t thread_id) { - Threading::RWLockLocker locker(s_thread_data_lock); + Sync::RWLockLocker locker(s_thread_data_lock); return s_thread_data.get(thread_id).value_or(nullptr); } ~ThreadData() { - Threading::RWLockLocker locker(s_thread_data_lock); + Sync::RWLockLocker locker(s_thread_data_lock); s_thread_data.remove(s_thread_id); } diff --git a/UI/CMakeLists.txt b/UI/CMakeLists.txt index 16a0d8310f..7a0e960a81 100644 --- a/UI/CMakeLists.txt +++ b/UI/CMakeLists.txt @@ -59,7 +59,7 @@ else() set(LADYBIRD_TARGET ladybird PRIVATE) endif() -set(LADYBIRD_LIBS AK LibCore LibFileSystem LibGfx LibImageDecoderClient LibIPC LibJS LibMain LibWeb LibWebView LibRequests LibURL) +set(LADYBIRD_LIBS AK LibCore LibFileSystem LibGfx LibImageDecoderClient LibIPC LibJS LibMain LibWeb LibWebView LibRequests LibSync LibURL) target_link_libraries(${LADYBIRD_TARGET} PRIVATE ${LADYBIRD_LIBS}) target_link_libraries(${LADYBIRD_TARGET} PRIVATE OpenSSL::Crypto OpenSSL::SSL) diff --git a/UI/Gtk/EventLoopImplementationGtk.cpp b/UI/Gtk/EventLoopImplementationGtk.cpp index c8cc0a1dd7..d105dd07f4 100644 --- a/UI/Gtk/EventLoopImplementationGtk.cpp +++ b/UI/Gtk/EventLoopImplementationGtk.cpp @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include @@ -19,7 +19,7 @@ namespace Ladybird { static HashMap s_notifiers; -static Threading::Mutex s_notifiers_mutex; +static Sync::Mutex s_notifiers_mutex; // Signal handling for signals not supported by g_unix_signal_add // (which only handles SIGHUP, SIGINT, SIGTERM, SIGUSR1, SIGUSR2, SIGWINCH). @@ -144,13 +144,13 @@ void EventLoopManagerGtk::register_notifier(Core::Notifier& notifier) auto weak_notifier = new WeakPtr(notifier.make_weak_ptr()); auto source_id = g_unix_fd_add_full(G_PRIORITY_DEFAULT, notifier.fd(), condition, notifier_callback, weak_notifier, notifier_destroy); - Threading::MutexLocker locker(s_notifiers_mutex); + Sync::MutexLocker locker(s_notifiers_mutex); s_notifiers.set(¬ifier, source_id); } void EventLoopManagerGtk::unregister_notifier(Core::Notifier& notifier) { - Threading::MutexLocker locker(s_notifiers_mutex); + Sync::MutexLocker locker(s_notifiers_mutex); auto it = s_notifiers.find(¬ifier); if (it == s_notifiers.end()) return; diff --git a/UI/Qt/EventLoopImplementationQt.cpp b/UI/Qt/EventLoopImplementationQt.cpp index 767e28272a..1680c5d337 100644 --- a/UI/Qt/EventLoopImplementationQt.cpp +++ b/UI/Qt/EventLoopImplementationQt.cpp @@ -14,9 +14,9 @@ #include #include #include -#include -#include -#include +#include +#include +#include #include #include @@ -36,10 +36,10 @@ namespace Ladybird { struct ThreadData; static thread_local OwnPtr s_this_thread_data; static HashMap s_thread_data; -static Threading::RWLock s_thread_data_lock; +static Sync::RWLock s_thread_data_lock; static thread_local Optional s_thread_id; #if defined(AK_OS_WINDOWS) -static Threading::MutexProtected> s_processes; +static Sync::MutexProtected> s_processes; #endif struct ThreadData { @@ -49,7 +49,7 @@ struct ThreadData { s_thread_id = pthread_self(); if (!s_this_thread_data) { s_this_thread_data = make(); - Threading::RWLockLocker locker(s_thread_data_lock); + Sync::RWLockLocker locker(s_thread_data_lock); s_thread_data.set(s_thread_id.value(), s_this_thread_data.ptr()); } return *s_this_thread_data; @@ -57,17 +57,17 @@ struct ThreadData { static ThreadData* for_thread(pthread_t thread_id) { - Threading::RWLockLocker locker(s_thread_data_lock); + Sync::RWLockLocker locker(s_thread_data_lock); return s_thread_data.get(thread_id).value_or(nullptr); } ~ThreadData() { - Threading::RWLockLocker locker(s_thread_data_lock); + Sync::RWLockLocker locker(s_thread_data_lock); s_thread_data.remove(s_thread_id.value()); } - Threading::Mutex mutex; + Sync::Mutex mutex; HashMap> notifiers; }; @@ -325,7 +325,7 @@ void EventLoopManagerQt::register_notifier(Core::Notifier& notifier) { auto& thread_data = ThreadData::the(); - Threading::MutexLocker locker(thread_data.mutex); + Sync::MutexLocker locker(thread_data.mutex); thread_data.notifiers.set(¬ifier, move(socket_notifier)); } notifier.set_owner_thread(s_thread_id.value()); @@ -336,7 +336,7 @@ void EventLoopManagerQt::unregister_notifier(Core::Notifier& notifier) auto* thread_data = ThreadData::for_thread(notifier.owner_thread()); if (!thread_data) return; - Threading::MutexLocker locker(thread_data->mutex); + Sync::MutexLocker locker(thread_data->mutex); auto deleted_notifier = thread_data->notifiers.take(¬ifier).release_value(); if (QThread::currentThread() != deleted_notifier->thread()) { auto* deleted_notifier_ptr = deleted_notifier.ptr();