@@ -182,24 +182,25 @@ void open_a_database_connection(JS::Realm& realm, StorageAPI::StorageKey storage
182182
183183 db->wait_for_connections_to_close (open_connections, GC::create_function (realm.heap (), [&realm, connection, version, request, on_complete] {
184184 // 6. Run upgrade a database using connection, version and request.
185- upgrade_a_database (realm, connection, version, request);
186-
187- // 7. If connection was closed, return a newly created "AbortError" DOMException and abort these steps.
188- if (connection->state () == ConnectionState::Closed) {
189- on_complete->function ()(WebIDL::AbortError::create (realm, " Connection was closed" _utf16));
190- return ;
191- }
192-
193- // 8. If request's error is set, run the steps to close a database connection with connection,
194- // return a newly created "AbortError" DOMException and abort these steps.
195- if (request->has_error ()) {
196- close_a_database_connection (*connection);
197- on_complete->function ()(WebIDL::AbortError::create (realm, " Upgrade transaction was aborted" _utf16));
198- return ;
199- }
200-
201- // 11. Return connection.
202- on_complete->function ()(connection);
185+ upgrade_a_database (realm, connection, version, request, GC::create_function (realm.heap (), [&realm, connection, request, on_complete] {
186+ // 7. If connection was closed, return a newly created "AbortError" DOMException and abort these steps.
187+ if (connection->state () == ConnectionState::Closed) {
188+ on_complete->function ()(WebIDL::AbortError::create (realm, " Connection was closed" _utf16));
189+ return ;
190+ }
191+
192+ // 8. If request's error is set, run the steps to close a database connection with connection,
193+ // return a newly created "AbortError" DOMException and abort these steps.
194+ if (request->has_error ()) {
195+ close_a_database_connection (*connection, GC::create_function (realm.heap (), [&realm, on_complete] {
196+ on_complete->function ()(WebIDL::AbortError::create (realm, " Upgrade transaction was aborted" _utf16));
197+ }));
198+ return ;
199+ }
200+
201+ // 11. Return connection.
202+ on_complete->function ()(connection);
203+ }));
203204 }));
204205 });
205206
@@ -356,7 +357,7 @@ WebIDL::ExceptionOr<GC::Ref<Key>> convert_a_value_to_a_key(JS::Realm& realm, JS:
356357}
357358
358359// https://w3c.github.io/IndexedDB/#close-a-database-connection
359- void close_a_database_connection (GC::Ref<IDBDatabase> connection, bool forced)
360+ void close_a_database_connection (GC::Ref<IDBDatabase> connection, GC::Ptr<GC::Function< void ()>> on_complete, bool forced)
360361{
361362 auto & realm = connection->realm ();
362363
@@ -371,32 +372,28 @@ void close_a_database_connection(GC::Ref<IDBDatabase> connection, bool forced)
371372 }
372373
373374 // 3. Wait for all transactions created using connection to complete. Once they are complete, connection is closed.
374- HTML::main_thread_event_loop ().spin_until (GC::create_function (realm.vm ().heap (), [connection]() {
375- if constexpr (IDB_DEBUG) {
376- dbgln (" close_a_database_connection: waiting for step 3" );
377- dbgln (" transactions created using connection:" );
378- for (auto const & transaction : connection->transactions ()) {
379- dbgln (" - {} - {}" , transaction->uuid (), (u8 )transaction->state ());
380- }
381- }
382-
375+ if constexpr (IDB_DEBUG) {
376+ dbgln (" close_a_database_connection: waiting for step 3" );
377+ dbgln (" transactions created using connection:" );
383378 for (auto const & transaction : connection->transactions ()) {
384- if (!transaction->is_finished ())
385- return false ;
379+ dbgln (" - {} - {}" , transaction->uuid (), (u8 )transaction->state ());
386380 }
381+ }
387382
388- return true ;
389- }) );
383+ connection-> wait_for_transactions_to_finish (connection-> transactions (), GC::create_function (realm. heap (), [&realm, connection, forced, on_complete] {
384+ connection-> set_state (ConnectionState::Closed );
390385
391- connection->set_state (ConnectionState::Closed);
386+ // 4. If the forced flag is true, then fire an event named close at connection.
387+ if (forced)
388+ connection->dispatch_event (DOM::Event::create (realm, HTML::EventNames::close));
392389
393- // 4. If the forced flag is true, then fire an event named close at connection.
394- if (forced)
395- connection-> dispatch_event ( DOM::Event::create (realm, HTML::EventNames::close ));
390+ if (on_complete)
391+ queue_a_database_task (on_complete. as_nonnull ());
392+ } ));
396393}
397394
398395// https://w3c.github.io/IndexedDB/#upgrade-a-database
399- void upgrade_a_database (JS::Realm& realm, GC::Ref<IDBDatabase> connection, u64 version, GC::Ref<IDBRequest> request)
396+ void upgrade_a_database (JS::Realm& realm, GC::Ref<IDBDatabase> connection, u64 version, GC::Ref<IDBRequest> request, GC::Ref<GC::Function< void ()>> on_complete )
400397{
401398 // 1. Let db be connection’s database.
402399 auto db = connection->associated_database ();
@@ -463,9 +460,9 @@ void upgrade_a_database(JS::Realm& realm, GC::Ref<IDBDatabase> connection, u64 v
463460 }));
464461
465462 // 11. Wait for transaction to finish.
466- HTML::main_thread_event_loop (). spin_until ( GC::create_function (realm. vm (). heap (), [transaction]() {
467- dbgln_if (IDB_DEBUG, " upgrade_a_database: waiting for step 11 " );
468- return transaction-> is_finished ( );
463+ dbgln_if (IDB_DEBUG, " upgrade_a_database: waiting for step 11 " );
464+ connection-> wait_for_transactions_to_finish ({ &transaction, 1 }, GC::create_function (realm. heap (), [on_complete] {
465+ queue_a_database_task (on_complete );
469466 }));
470467}
471468
0 commit comments