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');