tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

writer-starvation.any.js (2786B)


      1 // META: title=IndexedDB writer starvation test
      2 // META: global=window,worker
      3 // META: script=resources/support.js
      4 // META: timeout=long
      5 
      6 'use strict';
      7 
      8 async_test(t => {
      9  let db;
     10  let read_request_count = 0;
     11  let read_success_count = 0;
     12  let write_request_count = 0;
     13  let write_success_count = 0;
     14  const RQ_COUNT = 25;
     15 
     16  const open_rq = createdb(t);
     17  open_rq.onupgradeneeded = t.step_func((e) => {
     18    db = e.target.result;
     19    db.createObjectStore('s').add('1', 1);
     20  });
     21 
     22  open_rq.onsuccess = t.step_func((e) => {
     23    let i = 0;
     24 
     25    // Pre-fill some read requests.
     26    for (i = 0; i < RQ_COUNT; i++) {
     27      read_request_count++;
     28 
     29      db.transaction('s', 'readonly').objectStore('s').get(1).onsuccess =
     30          t.step_func((e) => {
     31            read_success_count++;
     32            assert_equals(e.target.transaction.mode, 'readonly');
     33          });
     34    }
     35 
     36    t.step(loop);
     37 
     38    function loop() {
     39      read_request_count++;
     40 
     41      db.transaction('s', 'readonly').objectStore('s').get(1).onsuccess =
     42          t.step_func((e) => {
     43            read_success_count++;
     44            assert_equals(e.target.transaction.mode, 'readonly');
     45 
     46            if (read_success_count >= RQ_COUNT && write_request_count == 0) {
     47              write_request_count++;
     48 
     49              db.transaction('s', 'readwrite')
     50                  .objectStore('s')
     51                  .add('written', read_request_count)
     52                  .onsuccess = t.step_func((e) => {
     53                write_success_count++;
     54                assert_equals(e.target.transaction.mode, 'readwrite');
     55                assert_equals(
     56                    e.target.result, read_success_count,
     57                    'write cb came before later read cb\'s');
     58              });
     59 
     60              // Reads done after the write.
     61              for (i = 0; i < 5; i++) {
     62                read_request_count++;
     63 
     64                db.transaction('s', 'readonly')
     65                    .objectStore('s')
     66                    .get(1)
     67                    .onsuccess = t.step_func((e) => {
     68                  read_success_count++;
     69                });
     70              }
     71            }
     72          });
     73 
     74      if (read_success_count < RQ_COUNT + 5) {
     75        step_timeout(t.step_func(loop), write_request_count ? 1000 : 100);
     76      } else {
     77        // This runs finish() once `read_success_count` >= RQ_COUNT + 5.
     78        db.transaction('s', 'readonly').objectStore('s').count().onsuccess =
     79            t.step_func(() => {
     80              step_timeout(t.step_func(finish), 100);
     81            });
     82      }
     83    }
     84  });
     85 
     86  function finish() {
     87    assert_equals(read_request_count, read_success_count, 'read counts');
     88    assert_equals(write_request_count, write_success_count, 'write counts');
     89    t.done();
     90  }
     91 }, 'IDB read requests should not starve write requests');