Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

121
LINES

< > BotCompany Repo | #1006319 // class ReliableSingleThread - triggers again reliably when one step is already running

JavaX fragment (include) [tags: use-pretranspiled]

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; }
}

Author comment

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: 897 / 2553
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)