Warning: session_start(): open(/var/lib/php/sessions/sess_bh3ins5phst0euvc5fq6hs3sao, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning: session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
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 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)); }
// stuff from RST
bool cancelBeforeTrigger; // always cancel running thread and wait for it to end before starting new operation
bool waitBetweenCancelAndTrigger; // make sure the old thread is actually ended
// 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...
Thread thread;
// This is useful also. All stuff that could go in meta though.
// The main idae is to have idle queues really small so just about
// every BEA object can have one and it doesn't cost us anything.
WeakReference threadBeingCancelled;
*(O *runnable) {}
void trigger() { go(); }
synchronized void go() {
if (cancelBeforeTrigger) cancelAndPossiblyWait();
trigger = true;
if (!running()) {
temp callF(enter);
thread = startThread(name, r {
temp callF(enter);
_run();
});
}
}
public void run() { go(); }
void get() { go(); } // so you can use the ! syntax
synchronized bool running() { ret thread != null; }
// use only if this is the last time you trigger this
void triggerAndWait() {
trigger();
waitUntilDone();
}
void waitUntilDone {
while (running()) sleep(1);
}
void _run() ctex {
while licensed {
Thread oldThread;
synchronized(this) {
var currentInserts = syncGetAndClear(inserts);
pcallFAll(currentInserts);
if (!trigger) {
thread = null;
break;
}
oldThread = getWeakRef(threadBeingCancelled);
trigger = false;
}
if (oldThread != null && oldThread != currentThread())
oldThread.join(cancelTimeOut);
pcallF(runnable);
}
}
synchronized void cancel() {
if (thread == null) ret;
threadBeingCancelled = new WeakReference(thread);
cancelAndInterruptThread(thread);
thread = null;
}
void cancelAndWait() {
Thread _thread;
synchronized {
if (thread == null) ret;
_thread = thread;
threadBeingCancelled = new WeakReference(thread);
thread = null;
}
cancelAndInterruptThread(_thread);
}
void cancelAndTrigger() {
cancelAndPossiblyWait();
trigger();
}
synchronized bool triggered() { ret trigger; }
void cleanMeUp { cancel(); }
selfType cancelBeforeTrigger() {
cancelBeforeTrigger = true;
this;
}
void cancelAndPossiblyWait() {
if (waitBetweenCancelAndTrigger)
cancel();
}
*() {}
*(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(r, q); }
_trigger();
}
void _trigger() {
rst.name = name();
rst.go();
}
void _bout {
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 {}
}