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 or(2(S) metaGet("name"), toString()); } void name(S name) { metaSet(+name); } // Np syncLinkedList - just an AppendableChain // All sync is done on the main object AppendableChain q; // retired also goes to meta bool retired() { ret metaGet("retired") != null; } void retired(bool b) { metaPut("retired", trueOrNull(b)); } // optional thread ownership marker, e.g. for OS modules. // Having slashed absolutely everything else, we do keep that as an actual field IF0 enter; // Being triggered is just having something in the queue. // So straightforward! bool triggered() { ret !isEmpty(); } // We do want to know who is servicing us currently... Thread thread; AutoCloseable enter() { ret callF(enter); } synchronized bool running() { ret thread != null; } protected synchronized void checkForAction() { if (running()) ret; temp enter(); thread = startThread(name(), rEnter _bout); } void waitUntilDone { while (!isEmpty()) sleep(1); } synchronized void cancel aka close() { clear(); if (thread == null) ret; threadBeingCancelled = new WeakReference(thread); cancelAndInterruptThread(thread); thread = null; } close { retired(true); clear(); cancelAndInterruptThread(); } public synchronized void clear { q = null; } // append to q (do later) synchronized void add(Runnable r) { if (r == null) ret; synchronized { q = chainPlus(q, r); } checkForAction(); } // prepend to q (do next) void addInFront(Runnable r) { if (r == null) ret; synchronized { q = itemPlusChain(r, q); } checkForAction } protected void checkForAction() { trigger = true; if (!running()) { temp callF(enter); thread = startThread(name, r { temp callF(enter); _run(); }); void _bout { while (licensed() && retired()) { Runnable r; synchronized { r = first(q); q = popFirst(q); } if (r != null) pcall { r?.run(); } else onIdle(); } } 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 {} }