blob: 1fc8b7577e9322f5d27117371310bac9e90fba26 [file]
import { Layout, Context } from "rive/host";
import { Jobs } from "rive/jobs";
import { SharedRegion, Signal } from "rive/shared";
// Holds the region until the top level lets go. Only a threaded page runs it
// while the top level waits.
@job export function holds(region: SharedRegion, flag: SharedRegion, held: Signal): i32 {
region.exclusive((view): void => {
held.notify();
while (flag.atomicLoad(0) == 0) {}
});
return 1;
}
let region = SharedRegion.create(16);
let flag = SharedRegion.create(16);
let held = Signal.create();
let job = Jobs.run(holds, region, flag, held);
// The page's thread waits a tenth of a second at most, so a late pool thread
// gets a second wait, and one of the locks ends with the top level's budget.
let holding = job.running && (held.waitWithin(0, 0.1) > 0 || held.waitWithin(0, 0.1) > 0);
let got = region.tryExclusive((view): void => {}, 30) || region.tryExclusive((view): void => {}, 30);
flag.atomicStore(0, 1);
// Enough turns to meet a fuel check.
let turns = 0;
for (let i = 0; i < 2000; i++) {
turns++;
}
export class Main extends Layout {
override init(context: Context): bool {
context.log("top level lock " + (!holding ? "never held" : got ? "taken" : "timed out") +
" turns " + turns.toString());
return true;
}
}