Libraryless. Click here for Pure Java version (10477L/58K).
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<AutoCloseable> enter; // optional ownership marker, e.g. for DynModules
int cancelTimeOut = 10000;
bool trigger;
Thread thread;
WeakReference<Thread> threadBeingCancelled;
L<Runnable> inserts = syncL();
// If you want to set the action later
*() {}
// 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; }
selfType action(Runnable r) { runnable = r; this; }
}Began life as a copy of #1004705
download show line numbers debug dex old transpilations
Travelled to 19 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, irmadwmeruwu, ishqpsrjomds, lpdgvwnxivlt, mowyntqkapby, mqqgnosmbjvj, omdjrrnzbjjv, onxytkatvevr, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt, whxojlpjdney, xrpafgyirdlv
No comments. add comment
| Snippet ID: | #1006319 |
| Snippet name: | class ReliableSingleThread - triggers again reliably when one step is already running |
| Eternal ID of this version: | #1006319/31 |
| Text MD5: | 734470ef7b4d13d5d71ebbbed6e06b5a |
| Transpilation MD5: | 28ec46cfccbb78842e407dc089e62f81 |
| Author: | stefan |
| Category: | javax |
| Type: | JavaX fragment (include) |
| Public (visible to everyone): | Yes |
| Archived (hidden from active list): | No |
| Created/modified: | 2022-12-18 23:42:10 |
| Source code size: | 3016 bytes / 121 lines |
| Pitched / IR pitched: | No / No |
| Views / Downloads: | 1907 / 3738 |
| Version history: | 30 change(s) |
| Referenced in: | #1030787 - RSTOverQ (ReliableSingleThread that shares thread with a Q) [probably works] #1033541 - ReliableExecuteAfterChange [dev.] - replacement for ReliableSingleThread/RSTOverQ with new execution constructs [dev.] #1034167 - Standard Classes + Interfaces (LIVE, continuation of #1003674) |