Warning: session_start(): open(/var/lib/php/sessions/sess_9t7d60vvvtvl9ht965sp19vq5u, 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
transient sclass ReliableSingleThread implements Runnable {
O runnable; // usually a Runnable. is allowed to call trigger() itself
S name = "Single Thread";
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
F0 enter; // optional ownership marker, e.g. for DynModules
int cancelTimeOut = 10000;
bool trigger;
Thread thread;
WeakReference threadBeingCancelled;
L inserts = syncL();
// legacy
*(O *runnable) {}
*(Runnable *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);
}
swappable void preSleep {}
void _run() ctex {
while licensed {
preSleep();
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();
}
// TODO: trigger technically not necessary, just notify (I guess)
void insert(Runnable r) { inserts.add(r); trigger(); }
synchronized bool hasThread() { ret thread != null; }
}