From a93262428fbb89591faafceb82b21d608a06534c Mon Sep 17 00:00:00 2001 From: Rick Waldron Date: Tue, 26 Jun 2018 13:22:30 -0400 Subject: [PATCH] Atomics: improvements to wake-*.js tests --- .../Atomics/wake/bigint/wake-all-on-loc.js | 20 ++--- .../built-ins/Atomics/wake/wake-all-on-loc.js | 24 ++--- test/built-ins/Atomics/wake/wake-all.js | 18 ++-- .../Atomics/wake/wake-in-order-one-time.js | 87 +++++++++++++++++++ test/built-ins/Atomics/wake/wake-in-order.js | 26 ++++-- test/built-ins/Atomics/wake/wake-nan.js | 9 +- test/built-ins/Atomics/wake/wake-one.js | 12 +-- test/built-ins/Atomics/wake/wake-two.js | 19 ++-- test/built-ins/Atomics/wake/wake-zero.js | 54 +++++------- 9 files changed, 181 insertions(+), 88 deletions(-) create mode 100644 test/built-ins/Atomics/wake/wake-in-order-one-time.js diff --git a/test/built-ins/Atomics/wake/bigint/wake-all-on-loc.js b/test/built-ins/Atomics/wake/bigint/wake-all-on-loc.js index 679be97e7f..a6efe40575 100644 --- a/test/built-ins/Atomics/wake/bigint/wake-all-on-loc.js +++ b/test/built-ins/Atomics/wake/bigint/wake-all-on-loc.js @@ -10,18 +10,18 @@ includes: [atomicsHelper.js] features: [Atomics, BigInt, SharedArrayBuffer, TypedArray] ---*/ -const WAKEUP = 0; // Waiters on this will be woken -const DUMMY = 1; // Waiters on this will not be woken +const WAIT_INDEX = 0; // Waiters on this will be woken +const WAIT_FAKE = 1; // Waiters on this will not be woken const RUNNING = 2; // Accounting of live agents -const NUMELEM = 3; const NUMAGENT = 3; +const BUFFER_SIZE = 4; for (var i = 0; i < NUMAGENT; i++) { $262.agent.start(` $262.agent.receiveBroadcast(function(sab) { const i64a = new BigInt64Array(sab); Atomics.add(i64a, ${RUNNING}, 1); - $262.agent.report("A " + Atomics.wait(i64a, ${WAKEUP}, 0)); + $262.agent.report("A " + Atomics.wait(i64a, ${WAIT_INDEX}, 0)); $262.agent.leaving(); }); `); @@ -32,28 +32,28 @@ $262.agent.start(` const i64a = new BigInt64Array(sab); Atomics.add(i64a, ${RUNNING}, 1); // This will always time out. - $262.agent.report("B " + Atomics.wait(i64a, ${DUMMY}, 0, 10)); + $262.agent.report("B " + Atomics.wait(i64a, ${WAIT_FAKE}, 0, 10)); $262.agent.leaving(); }); `); const i64a = new BigInt64Array( - new SharedArrayBuffer(NUMELEM * BigInt64Array.BYTES_PER_ELEMENT) + new SharedArrayBuffer(BigInt64Array.BYTES_PER_ELEMENT * BUFFER_SIZE) ); $262.agent.broadcast(i64a.buffer); // Wait for agents to be running. -waitUntil(i64a, RUNNING, NUMAGENT + 1); +waitUntil(i64a, RUNNING, BUFFER_SIZE); // Then wait some more to give the agents a fair chance to wait. If we don't, // we risk sending the wakeup before agents are sleeping, and we hang. $262.agent.sleep(50); -// Wake all waiting on WAKEUP, should be 3 always, they won't time out. +// Wake all waiting on WAIT_INDEX, should be 3 always, they won't time out. assert.sameValue( - Atomics.wake(i64a, WAKEUP), + Atomics.wake(i64a, WAIT_INDEX), NUMAGENT, - 'Atomics.wake(i64a, WAKEUP) equals the value of `NUMAGENT` (3)' + 'Atomics.wake(i64a, WAIT_INDEX) equals the value of `NUMAGENT` (3)' ); var rs = []; diff --git a/test/built-ins/Atomics/wake/wake-all-on-loc.js b/test/built-ins/Atomics/wake/wake-all-on-loc.js index e094e8526f..cda0d96a94 100644 --- a/test/built-ins/Atomics/wake/wake-all-on-loc.js +++ b/test/built-ins/Atomics/wake/wake-all-on-loc.js @@ -10,19 +10,18 @@ includes: [atomicsHelper.js] features: [Atomics, SharedArrayBuffer, TypedArray] ---*/ -const WAKEUP = 0; // Waiters on this will be woken -const DUMMY = 1; // Waiters on this will not be woken +const WAIT_INDEX = 0; // Waiters on this will be woken +const WAIT_FAKE = 1; // Waiters on this will not be woken const RUNNING = 2; // Accounting of live agents -const NUMELEM = 3; - const NUMAGENT = 3; +const BUFFER_SIZE = 4; -for (var i=0; i < NUMAGENT; i++) { +for (var i = 0; i < NUMAGENT; i++) { $262.agent.start(` $262.agent.receiveBroadcast(function(sab) { const i32a = new Int32Array(sab); Atomics.add(i32a, ${RUNNING}, 1); - $262.agent.report("A " + Atomics.wait(i32a, ${WAKEUP}, 0)); + $262.agent.report("A " + Atomics.wait(i32a, ${WAIT_INDEX}, 0)); $262.agent.leaving(); }); `); @@ -33,28 +32,29 @@ $262.agent.start(` const i32a = new Int32Array(sab); Atomics.add(i32a, ${RUNNING}, 1); // This will always time out. - $262.agent.report("B " + Atomics.wait(i32a, ${DUMMY}, 0, 10)); + $262.agent.report("B " + Atomics.wait(i32a, ${WAIT_FAKE}, 0, 10)); $262.agent.leaving(); }); `); const i32a = new Int32Array( - new SharedArrayBuffer(NUMELEM * Int32Array.BYTES_PER_ELEMENT) + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * BUFFER_SIZE) ); + $262.agent.broadcast(i32a.buffer); // Wait for agents to be running. -waitUntil(i32a, RUNNING, NUMAGENT + 1); +waitUntil(i32a, RUNNING, BUFFER_SIZE); // Then wait some more to give the agents a fair chance to wait. If we don't, // we risk sending the wakeup before agents are sleeping, and we hang. $262.agent.sleep(50); -// Wake all waiting on WAKEUP, should be 3 always, they won't time out. +// Wake all waiting on WAIT_INDEX, should be 3 always, they won't time out. assert.sameValue( - Atomics.wake(i32a, WAKEUP), + Atomics.wake(i32a, WAIT_INDEX), NUMAGENT, - 'Atomics.wake(i32a, WAKEUP) equals the value of `NUMAGENT` (3)' + 'Atomics.wake(i32a, WAIT_INDEX) equals the value of `NUMAGENT` (3)' ); const rs = []; diff --git a/test/built-ins/Atomics/wake/wake-all.js b/test/built-ins/Atomics/wake/wake-all.js index 1d6a3de1dd..0da7909479 100644 --- a/test/built-ins/Atomics/wake/wake-all.js +++ b/test/built-ins/Atomics/wake/wake-all.js @@ -9,18 +9,18 @@ includes: [atomicsHelper.js] features: [Atomics, SharedArrayBuffer, TypedArray] ---*/ -const WAKEUP = 0; // Waiters on this will be woken -const DUMMY = 1; // Waiters on this will not be woken +const WAIT_INDEX = 0; // Waiters on this will be woken +const WAIT_FAKE = 1; // Waiters on this will not be woken const RUNNING = 2; // Accounting of live agents -const NUMELEM = 3; const NUMAGENT = 3; +const BUFFER_SIZE = 4; for (var i = 0; i < NUMAGENT; i++) { $262.agent.start(` $262.agent.receiveBroadcast(function(sab) { const i32a = new Int32Array(sab); Atomics.add(i32a, ${RUNNING}, 1); - $262.agent.report("A " + Atomics.wait(i32a, ${WAKEUP}, 0)); + $262.agent.report("A " + Atomics.wait(i32a, ${WAIT_INDEX}, 0)); $262.agent.leaving(); }); `); @@ -31,13 +31,13 @@ $262.agent.start(` const i32a = new Int32Array(sab); Atomics.add(i32a, ${RUNNING}, 1); // This will always time out. - $262.agent.report("B " + Atomics.wait(i32a, ${DUMMY}, 0, 10)); + $262.agent.report("B " + Atomics.wait(i32a, ${WAIT_FAKE}, 0, 10)); $262.agent.leaving(); }); `); const i32a = new Int32Array( - new SharedArrayBuffer(NUMELEM * Int32Array.BYTES_PER_ELEMENT) + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * BUFFER_SIZE) ); $262.agent.broadcast(i32a.buffer); @@ -49,11 +49,11 @@ waitUntil(i32a, RUNNING, NUMAGENT + 1); // we risk sending the wakeup before agents are sleeping, and we hang. $262.agent.sleep(50); -// Wake all waiting on WAKEUP, should be 3 always, they won't time out. +// Wake all waiting on WAIT_INDEX, should be 3 always, they won't time out. assert.sameValue( - Atomics.wake(i32a, WAKEUP), + Atomics.wake(i32a, WAIT_INDEX), NUMAGENT, - 'Atomics.wake(i32a, WAKEUP) equals the value of `NUMAGENT` (3)' + 'Atomics.wake(i32a, WAIT_INDEX) equals the value of `NUMAGENT` (3)' ); const rs = []; diff --git a/test/built-ins/Atomics/wake/wake-in-order-one-time.js b/test/built-ins/Atomics/wake/wake-in-order-one-time.js new file mode 100644 index 0000000000..1ab2223be2 --- /dev/null +++ b/test/built-ins/Atomics/wake/wake-in-order-one-time.js @@ -0,0 +1,87 @@ +// Copyright (C) 2017 Mozilla Corporation. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. + +/*--- +esid: sec-atomics.wake +description: > + Test that Atomics.wake wakes agents in the order they are waiting. +includes: [atomicsHelper.js] +features: [Atomics, SharedArrayBuffer, TypedArray] +---*/ + +const NUMAGENT = 3; +const WAIT_INDEX = 0; // Waiters on this will be woken +const SPIN = 1; // Worker i (zero-based) spins on location SPIN+i +const RUNNING = SPIN + NUMAGENT; // Accounting of live agents +const BUFFER_SIZE = RUNNING + 1; + +// Create workers and start them all spinning. We set atomic slots to make +// them go into a wait, thus controlling the waiting order. Then we wake them +// one by one and observe the wakeup order. + +for (var i = 0; i < NUMAGENT; i++) { + $262.agent.start(` + $262.agent.receiveBroadcast(function(sab) { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + while (Atomics.load(i32a, ${SPIN + i}) === 0) { + /* nothing */ + } + $262.agent.report(${i}); + Atomics.wait(i32a, ${WAIT_INDEX}, 0); + $262.agent.report(${i}); + $262.agent.leaving(); + }); + `); +} + +const i32a = new Int32Array( + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * BUFFER_SIZE) +); + +$262.agent.broadcast(i32a.buffer); + +// Wait for agents to be running. +waitUntil(i32a, RUNNING, NUMAGENT); + +// Sleep to allow the agents a fair chance to wait. If we don't, +// we risk sending the wakeup before agents are sleeping, and we hang. +$262.agent.sleep(50); + +var waiterlist = []; +assert.sameValue(Atomics.store(i32a, SPIN + 0, 1), 1); +waiterlist.push(getReport()); + +assert.sameValue(Atomics.store(i32a, SPIN + 1, 1), 1); +waiterlist.push(getReport()); + +assert.sameValue(Atomics.store(i32a, SPIN + 2, 1), 1); +waiterlist.push(getReport()); + +var notified = []; +assert.sameValue( + Atomics.wake(i32a, WAIT_INDEX, 1), + 1, + `Notification #0: on WAIT_INDEX (0) of i32a must notify 1 waiter.` +); +notified.push(getReport()); + +assert.sameValue( + Atomics.wake(i32a, WAIT_INDEX, 1), + 1, + `Notification #1: on WAIT_INDEX (0) of i32a must notify 1 waiter.` +); +notified.push(getReport()); + +assert.sameValue( + Atomics.wake(i32a, WAIT_INDEX, 1), + 1, + `Notification #2: on WAIT_INDEX (0) of i32a must notify 1 waiter.` +); +notified.push(getReport()); + +assert.sameValue( + notified.join(''), + waiterlist.join(''), + `notified and waiterlist order do not match.` +); diff --git a/test/built-ins/Atomics/wake/wake-in-order.js b/test/built-ins/Atomics/wake/wake-in-order.js index 0b81dda43f..25df57db54 100644 --- a/test/built-ins/Atomics/wake/wake-in-order.js +++ b/test/built-ins/Atomics/wake/wake-in-order.js @@ -10,10 +10,10 @@ features: [Atomics, SharedArrayBuffer, TypedArray] ---*/ const NUMAGENT = 3; -const WAKEUP = 0; // Waiters on this will be woken +const WAIT_INDEX = 0; // Waiters on this will be woken const SPIN = 1; // Worker i (zero-based) spins on location SPIN+i const RUNNING = SPIN + NUMAGENT; // Accounting of live agents -const NUMELEM = RUNNING + 1; +const BUFFER_SIZE = RUNNING + 1; // Create workers and start them all spinning. We set atomic slots to make // them go into a wait, thus controlling the waiting order. Then we wake them @@ -29,7 +29,7 @@ for (var attempt = 0; attempt < 10; attempt++) { /* nothing */ } $262.agent.report(${i}); - Atomics.wait(i32a, ${WAKEUP}, 0); + Atomics.wait(i32a, ${WAIT_INDEX}, 0); $262.agent.report(${i}); $262.agent.leaving(); }); @@ -37,7 +37,7 @@ for (var attempt = 0; attempt < 10; attempt++) { } const i32a = new Int32Array( - new SharedArrayBuffer(NUMELEM * Int32Array.BYTES_PER_ELEMENT) + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * BUFFER_SIZE) ); $262.agent.broadcast(i32a.buffer); @@ -60,13 +60,25 @@ for (var attempt = 0; attempt < 10; attempt++) { waiterlist.push(getReport()); var notified = []; - assert.sameValue(Atomics.wake(i32a, WAKEUP, 1), 1); + assert.sameValue( + Atomics.wake(i32a, WAIT_INDEX, 1), + 1, + `Attempt #${attempt}, Notification #0: on WAIT_INDEX (0) of i32a must notify 1 waiter.` + ); notified.push(getReport()); - assert.sameValue(Atomics.wake(i32a, WAKEUP, 1), 1); + assert.sameValue( + Atomics.wake(i32a, WAIT_INDEX, 1), + 1, + `Attempt #${attempt}, Notification #1: on WAIT_INDEX (0) of i32a must notify 1 waiter.` + ); notified.push(getReport()); - assert.sameValue(Atomics.wake(i32a, WAKEUP, 1), 1); + assert.sameValue( + Atomics.wake(i32a, WAIT_INDEX, 1), + 1, + `Attempt #${attempt}, Notification #2: on WAIT_INDEX (0) of i32a must notify 1 waiter.` + ); notified.push(getReport()); assert.sameValue( diff --git a/test/built-ins/Atomics/wake/wake-nan.js b/test/built-ins/Atomics/wake/wake-nan.js index 1c9a99dea0..972853e1ef 100644 --- a/test/built-ins/Atomics/wake/wake-nan.js +++ b/test/built-ins/Atomics/wake/wake-nan.js @@ -12,7 +12,7 @@ features: [ArrayBuffer, DataView, let, arrow-function, for-of, Atomics, BigInt, $262.agent.start(` $262.agent.receiveBroadcast(function(sab) { const i32a = new Int32Array(sab); - $262.agent.report(Atomics.wait(i32a, 0, 0, 1000)); // We will timeout eventually + $262.agent.report(Atomics.wait(i32a, 0, 0, 200)); // We will timeout eventually $262.agent.leaving(); }); `); @@ -22,6 +22,9 @@ const i32a = new Int32Array( ); $262.agent.broadcast(i32a.buffer); -$262.agent.sleep(500); // Give the agent a chance to wait -assert.sameValue(Atomics.wake(i32a, 0, NaN), 0, 'Atomics.wake(i32a, 0, NaN) returns 0'); // Don't actually wake it +$262.agent.sleep(10); // Give the agent a chance to wait +assert.sameValue(Atomics.wake(i32a, 0, NaN), 0, 'Atomics.wake(i32a, 0, NaN) returns 0, and will not actually notify any waiters.'); + +// Sleep past the timeout +$262.agent.sleep(300); assert.sameValue(getReport(), 'timed-out', 'getReport() returns "timed-out"'); diff --git a/test/built-ins/Atomics/wake/wake-one.js b/test/built-ins/Atomics/wake/wake-one.js index 11b74ce861..a4fba02930 100644 --- a/test/built-ins/Atomics/wake/wake-one.js +++ b/test/built-ins/Atomics/wake/wake-one.js @@ -9,11 +9,11 @@ includes: [atomicsHelper.js] features: [Atomics, SharedArrayBuffer, TypedArray] ---*/ -const NUMAGENT = 3; -const WAKEUP = 0; // Agents wait here +const WAIT_INDEX = 0; // Agents wait here const RUNNING = 1; // Accounting of live agents here -const NUMELEM = 2; const WAKECOUNT = 1; +const NUMAGENT = 3; +const BUFFER_SIZE = 4; for (var i = 0; i < NUMAGENT; i++ ) { $262.agent.start(` @@ -21,14 +21,14 @@ for (var i = 0; i < NUMAGENT; i++ ) { const i32a = new Int32Array(sab); Atomics.add(i32a, ${RUNNING}, 1); // Waiters that are not woken will time out eventually. - $262.agent.report(Atomics.wait(i32a, ${WAKEUP}, 0, 2000)); + $262.agent.report(Atomics.wait(i32a, ${WAIT_INDEX}, 0, 2000)); $262.agent.leaving(); }); `); } const i32a = new Int32Array( - new SharedArrayBuffer(NUMELEM * Int32Array.BYTES_PER_ELEMENT) + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * BUFFER_SIZE) ); $262.agent.broadcast(i32a.buffer); @@ -38,7 +38,7 @@ waitUntil(i32a, RUNNING, NUMAGENT); // Then wait some more to give the agents a fair chance to wait. If we don't, // we risk sending the wakeup before agents are sleeping, and we hang. -$262.agent.sleep(50); +$262.agent.sleep(10); // There's a slight risk we'll fail to wake the desired count, if the preceding // sleep() took much longer than anticipated and workers have started timing diff --git a/test/built-ins/Atomics/wake/wake-two.js b/test/built-ins/Atomics/wake/wake-two.js index 6829f8f1d2..5cc398816f 100644 --- a/test/built-ins/Atomics/wake/wake-two.js +++ b/test/built-ins/Atomics/wake/wake-two.js @@ -10,11 +10,11 @@ features: [Atomics, SharedArrayBuffer, TypedArray] ---*/ -var NUMAGENT = 3; -var WAKEUP = 0; // Agents wait here -var RUNNING = 1; // Accounting of live agents here -var NUMELEM = 2; -var WAKECOUNT = 2; +const WAIT_INDEX = 0; // Agents wait here +const RUNNING = 1; // Accounting of live agents here +const WAKECOUNT = 2; +const NUMAGENT = 3; +const BUFFER_SIZE = 4; for (var i = 0; i < NUMAGENT; i++ ) { $262.agent.start(` @@ -22,14 +22,14 @@ for (var i = 0; i < NUMAGENT; i++ ) { const i32a = new Int32Array(sab); Atomics.add(i32a, ${RUNNING}, 1); // Waiters that are not woken will time out eventually. - $262.agent.report(Atomics.wait(i32a, ${WAKEUP}, 0, 2000)); + $262.agent.report(Atomics.wait(i32a, ${WAIT_INDEX}, 0, 200)); $262.agent.leaving(); }) `); } const i32a = new Int32Array( - new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * 4) + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * BUFFER_SIZE) ); $262.agent.broadcast(i32a.buffer); @@ -39,7 +39,7 @@ waitUntil(i32a, RUNNING, NUMAGENT); // Then wait some more to give the agents a fair chance to wait. If we don't, // we risk sending the wakeup before agents are sleeping, and we hang. -$262.agent.sleep(500); +$262.agent.sleep(10); // There's a slight risk we'll fail to wake the desired count, if the preceding // sleep() took much longer than anticipated and workers have started timing @@ -50,6 +50,9 @@ assert.sameValue( 'Atomics.wake(i32a, 0, WAKECOUNT) equals the value of `WAKECOUNT` (2)' ); +// Sleep past the timeout +$262.agent.sleep(300); + // Collect and check results var rs = []; for (var i = 0; i < NUMAGENT; i++) { diff --git a/test/built-ins/Atomics/wake/wake-zero.js b/test/built-ins/Atomics/wake/wake-zero.js index f4c6066496..b9725e3a00 100644 --- a/test/built-ins/Atomics/wake/wake-zero.js +++ b/test/built-ins/Atomics/wake/wake-zero.js @@ -9,26 +9,26 @@ includes: [atomicsHelper.js] features: [Atomics, SharedArrayBuffer, TypedArray] ---*/ -var NUMAGENT = 3; -var WAKEUP = 0; // Agents wait here -var RUNNING = 1; // Accounting of live agents here -var NUMELEM = 2; -var WAKECOUNT = 0; +const WAKECOUNT = 0; +const WAIT_INDEX = 0; // Agents wait here +const RUNNING = 1; // Accounting of live agents here +const NUMAGENT = 3; +const BUFFER_SIZE = 4; for (var i = 0; i < NUMAGENT; i++) { -$262.agent.start(` - $262.agent.receiveBroadcast(function(sab) { - const i32a = new Int32Array(sab); - Atomics.add(i32a, ${RUNNING}, 1); - // Waiters that are not woken will time out eventually. - $262.agent.report(Atomics.wait(i32a, ${WAKEUP}, 0, 200)); - $262.agent.leaving(); - }); -`); + $262.agent.start(` + $262.agent.receiveBroadcast(function(sab) { + const i32a = new Int32Array(sab); + Atomics.add(i32a, ${RUNNING}, 1); + // Waiters that are not woken will time out eventually. + $262.agent.report(Atomics.wait(i32a, ${WAIT_INDEX}, 0, 200)); + $262.agent.leaving(); + }); + `); } const i32a = new Int32Array( - new SharedArrayBuffer(NUMELEM * Int32Array.BYTES_PER_ELEMENT) + new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT * BUFFER_SIZE) ); $262.agent.broadcast(i32a.buffer); @@ -36,30 +36,18 @@ $262.agent.broadcast(i32a.buffer); // Wait for agents to be running. waitUntil(i32a, RUNNING, NUMAGENT); -// Then wait some more to give the agents a fair chance to wait. If we don't, -// we risk sending the wakeup before agents are sleeping, and we hang. -$262.agent.sleep(50); - // There's a slight risk we'll fail to wake the desired count, if the preceding // sleep() took much longer than anticipated and workers have started timing // out. assert.sameValue( - Atomics.wake(i32a, 0, WAKECOUNT), + Atomics.wake(i32a, WAIT_INDEX, WAKECOUNT), WAKECOUNT, - 'Atomics.wake(i32a, 0, WAKECOUNT) equals the value of `WAKECOUNT` (0)' + 'Atomics.wake(i32a, WAIT_INDEX, WAKECOUNT) equals the value of `WAKECOUNT` (0)' ); -// Collect and check results -var rs = []; +// Sleep past the timeout +$262.agent.sleep(300); + for (var i = 0; i < NUMAGENT; i++) { - rs.push(getReport()); + assert.sameValue(getReport(), 'timed-out', `Report #${i}: must equal "timed-out"`); } -rs.sort(); - -for (var i = 0; i < WAKECOUNT; i++) { - assert.sameValue(rs[i], 'ok', 'The value of rs[i] is "ok"'); -} -for (var i = WAKECOUNT; i < NUMAGENT; i++) { - assert.sameValue(rs[i], 'timed-out', 'The value of rs[i] is "timed-out"'); -} -