// In the newest pinging system (with flag PingV3), a ping source // is the object that "allows" some code to run. // When that code calls ping(), the ping source's action (if defined) // is triggered. // This allows randomly interrupting code execution, for example. sclass PingSource { // returns true if it slept settable volatile IF0 action; // optional description of this ping source S text; // optional thread pool that this ping source likes to run in ThreadPool threadPool; *() {} *(ThreadPool *threadPool) {} *(ThreadPool *threadPool, S *text) {} *(IF0 *action) {} // returns true if it slept final bool get() { var a = action; ret a != null && a!; } final void ping { var a = action; if (a != null) a!; } void cancel { action = new Cancelled; } class Cancelled is IF0 { public Bool get() { throw new PingSourceCancelledException(PingSource.this); } } record noeq Encapsulated(Runnable r) is Runnable { run { //System.out.println("Encapsulated running: " + r); try { pingSource_tl().set(PingSource.this); //System.out.println("Ping source set"); ping(); r.run(); //System.out.println("Done running"); } finally { //System.out.println("Finally"); pingSource_tl().set(null); } } toString { ret PingSource.this + ": " + r; } } void do(Runnable r) { if (r == null) ret; threadPool.acquireThreadOrQueue(new Encapsulated(r)); } toString { S t = text; ret nempty(t) ? t : super.toString(); } ISleeper_v2 sleeper() { ret threadPool.sleeper(); } }