mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-04-25 17:25:08 +02:00
LibWeb/IndexedDB: Remove spin_until from checking finished transactions
This commit is contained in:
committed by
Andreas Kling
parent
52b53e52fb
commit
d87c2a55b0
Notes:
github-actions[bot]
2025-10-08 15:26:31 +00:00
Author: https://github.com/Lubrsi Commit: https://github.com/LadybirdBrowser/ladybird/commit/d87c2a55b00 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/6182
@@ -12,10 +12,12 @@
|
||||
#include <LibWeb/IndexedDB/IDBObjectStore.h>
|
||||
#include <LibWeb/IndexedDB/Internal/Algorithms.h>
|
||||
#include <LibWeb/IndexedDB/Internal/IDBDatabaseObserver.h>
|
||||
#include <LibWeb/IndexedDB/Internal/IDBTransactionObserver.h>
|
||||
|
||||
namespace Web::IndexedDB {
|
||||
|
||||
GC_DEFINE_ALLOCATOR(IDBDatabase);
|
||||
GC_DEFINE_ALLOCATOR(IDBDatabase::TransactionFinishState);
|
||||
|
||||
IDBDatabase::IDBDatabase(JS::Realm& realm, Database& db)
|
||||
: EventTarget(realm)
|
||||
@@ -47,6 +49,7 @@ void IDBDatabase::visit_edges(Visitor& visitor)
|
||||
visitor.visit(m_object_store_set);
|
||||
visitor.visit(m_associated_database);
|
||||
visitor.visit(m_transactions);
|
||||
visitor.visit(m_transaction_finish_queue);
|
||||
}
|
||||
|
||||
void IDBDatabase::set_onabort(WebIDL::CallbackType* event_handler)
|
||||
@@ -263,4 +266,60 @@ void IDBDatabase::set_state(ConnectionState state)
|
||||
});
|
||||
}
|
||||
|
||||
void IDBDatabase::wait_for_transactions_to_finish(ReadonlySpan<GC::Ref<IDBTransaction>> transactions, GC::Ref<GC::Function<void()>> on_complete)
|
||||
{
|
||||
GC::Ptr<TransactionFinishState> transaction_finish_state;
|
||||
|
||||
for (auto const& entry : transactions) {
|
||||
if (!entry->is_finished()) {
|
||||
if (!transaction_finish_state) {
|
||||
transaction_finish_state = heap().allocate<TransactionFinishState>();
|
||||
}
|
||||
|
||||
transaction_finish_state->add_transaction_to_observe(entry);
|
||||
}
|
||||
}
|
||||
|
||||
if (transaction_finish_state) {
|
||||
transaction_finish_state->after_all = GC::create_function(heap(), [this, transaction_finish_state, on_complete] {
|
||||
bool was_removed = m_transaction_finish_queue.remove_first_matching([transaction_finish_state](GC::Ref<TransactionFinishState> pending_transaction_finish_state) {
|
||||
return pending_transaction_finish_state == transaction_finish_state;
|
||||
});
|
||||
VERIFY(was_removed);
|
||||
queue_a_database_task(on_complete);
|
||||
});
|
||||
m_transaction_finish_queue.append(transaction_finish_state.as_nonnull());
|
||||
} else {
|
||||
queue_a_database_task(on_complete);
|
||||
}
|
||||
}
|
||||
|
||||
void IDBDatabase::TransactionFinishState::visit_edges(Visitor& visitor)
|
||||
{
|
||||
Base::visit_edges(visitor);
|
||||
visitor.visit(transaction_observers);
|
||||
visitor.visit(after_all);
|
||||
}
|
||||
|
||||
void IDBDatabase::TransactionFinishState::add_transaction_to_observe(GC::Ref<IDBTransaction> transaction)
|
||||
{
|
||||
auto transaction_observer = heap().allocate<IDBTransactionObserver>(transaction);
|
||||
transaction_observer->set_transaction_finished_observer(GC::create_function(heap(), [this] {
|
||||
transaction_observers.remove_all_matching([](GC::Ref<IDBTransactionObserver> const& transaction_observer) {
|
||||
if (transaction_observer->transaction()->is_finished()) {
|
||||
transaction_observer->unobserve();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
if (transaction_observers.is_empty()) {
|
||||
queue_a_database_task(after_all.as_nonnull());
|
||||
}
|
||||
}));
|
||||
|
||||
transaction_observers.append(transaction_observer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user