sclass CompactQ extends Meta is AutoCloseable { // Step 1 - no name... well, no reserved name field, anyway. // Most queues can be probably identified from context. // if you want æ name - use Meta S name() { ret (S) metaGet("name"); } void mame(S name) { metaSet(+name); } // Np syncLinkedList - just an AppendableChain // All sync is done on the main object AppendableChain q; // This is the fat boy ReliableSingleThread rst = new(r { _run() }); // retired also goes to meta bool retired() { ret metaGet("retired") != null; } void retired(bool b) { metaPut("retired", trueOrNull(b)); } *() {} *(S name) { name(name); } // append to q (do later) synchronized void add(Runnable r) { if (r == null) ret; synchronized { q = chainPlus(q, r); } _trigger(); } // prepend to q (do next) void addInFront(Runnable r) { if (r == null) ret; synchronized { q = itemPlusChain(q, r); } _trigger(); } void _trigger() { rst.name = name(); rst.go(); } synchronized void add(O r) { add(toRunnable(r)); } void _run() { while (licensed() && retired()) { Runnable r; synchronized { r = first(q); q = popFirst(q); } if (r != null) pcall { r?.run(); } else onIdle(); } } public void close() { retired(true); } // TODO: interrupt thread void done() {} // legacy function bool isEmpty() { ret q == null; } int size() { ret l(q); } O mutex() { this; } // clients can synchronize on this L snapshot() { ret cloneList(q); } // you can override this void onIdle {} }