Thread management for JavaScript running inside the Total Control (TC) environment.
This module exposes two thread wrappers — TCThread (backed by pooled Java platform threads)
and TCThreadVirtual (backed by JDK 21+ virtual threads) — plus a set of manager utilities
to coordinate thread lifecycle, cooperative pause/resume, interruption on timeout, and global
concurrency policy ("serialized" vs "unsafe-parallel").
Why this module exists
Rhino/RingoJS style engines frequently execute JS on a single-host thread and are not re‑entrant.
Running JS callbacks concurrently from multiple Java threads can corrupt interpreter state or
produce hard‑to‑debug races. This module provides:
- A global JS lock to serialize entry into JS frames when policy is "serialized"
- A thread registry with synchronized access to support lookups, counting, and cleanup
- Cooperative controls (pause/resume/stop) that work with yield points inside user code
- Stable waiting semantics via TCWait with immediate/finite timeout handling
- Re‑runnable executor that can be shut down and automatically re‑created as needed
Public Surface
- Classes: TCThread, TCThreadVirtual
- Managers: stopAllThreads, pauseAllThreads, resumeAllThreads,
listThreadStatus, shutdownExecutor - Waiting & lookup: TCWait, getAllThreadNames, getThreadByName,
getThreadsByName, threadCount, threadCountByPrefix - Diagnostics & policy: setDebug, getDebug, setGlobalConcurrency,
getGlobalConcurrency
Quick Start
var {
TCThread, TCThreadVirtual, TCWait,
pauseAllThreads, resumeAllThreads, stopAllThreads,
setGlobalConcurrency, getGlobalConcurrency
} = require("sigma/tcthreadmanager");
// Pooled thread
var t = new TCThread("job1", () => delay(200));
t.start();
print("job1 finished?", TCWait(t, 1000));
// Virtual thread
var v = new TCThreadVirtual("vjob", () => delay(150));
v.start();
print("vjob finished?", v.await(500));
setGlobalConcurrency("serialized");
Classes
Methods
(static) TCWait(name, timeOutopt) → {boolean}
Wait for a thread to complete with optional timeout. Supports thread object or name.
Example
// Example: wait by object
var t = new TCThread("w1", () => delay(80));
t.start();
print(TCWait(t, 500));
// Example: wait by name (most recent with same name)
var a = new TCThread("sameN", () => delay(200));
var b = new TCThread("sameN", () => delay(50));
a.start();
delay(10);
b.start();
print(TCWait("sameN", 500));
// Example: immediate timeout (<=0)
var longT = new TCThread("long", () => delay(2000));
longT.start();
print(TCWait(longT, 0)); // false
Parameters:
| Name | Type | Attributes | Description |
|---|---|---|---|
name |
TCThread | TCThreadVirtual | string | Thread object or logical name (most recent) |
|
timeOut |
number |
<optional> |
Milliseconds timeout (<=0 means immediate timeout) |
Returns:
true if finished without interruption, else false
- Type
- boolean
(static) getAllThreadNames() → {Array.<string>}
Get names of all currently registered threads.
Example
// Example: list names
print(getAllThreadNames().join(", "));
Returns:
- Type
- Array.<string>
(static) getDebug() → {boolean}
Return whether debug logging is enabled.
Example
// Example: query debug flag
print("debug enabled?", getDebug());
Returns:
- Type
- boolean
(static) getGlobalConcurrency() → {"serialized"|"unsafe-parallel"}
Get current global concurrency policy.
Example
// Example: print policy
print("Policy:", getGlobalConcurrency());
Returns:
- Type
- "serialized" | "unsafe-parallel"
(static) getThreadByName(name) → {TCThread|TCThreadVirtual|undefined}
Get the most recently started thread with a given name.
Example
// Example: fetch by name
var t = new TCThread("lookupJob", () => delay(50));
t.start();
var found = getThreadByName("lookupJob");
Parameters:
| Name | Type | Description |
|---|---|---|
name |
string |
Returns:
- Type
- TCThread | TCThreadVirtual | undefined
(static) getThreadsByName(name) → {Array.<(TCThread|TCThreadVirtual)>}
Get all threads (of any age) that match a given name.
Example
// Example: duplicate names
var a=new TCThread("dup",()=>delay(20)),
b=new TCThread("dup",()=>delay(20));
a.start();
b.start();
print(getThreadsByName("dup").length>=2);
Parameters:
| Name | Type | Description |
|---|---|---|
name |
string |
Returns:
- Type
- Array.<(TCThread|TCThreadVirtual)>
(static) listThreadStatus()
Print a snapshot of all registered threads.
Example
// Example: list current threads for debugging
listThreadStatus();
(static) pauseAllThreads()
Pause all registered threads (cooperative).
Example
pauseAllThreads();
(static) resumeAllThreads()
Resume all registered threads.
Example
resumeAllThreads();
(static) setDebug(v)
Enable/disable non‑fatal debug logs.
Example
// Example: enable logs while diagnosing a failure
setDebug(true); // ... run ...
setDebug(false);
Parameters:
| Name | Type | Description |
|---|---|---|
v |
boolean |
(static) setGlobalConcurrency(mode)
Switch the global JS concurrency policy.
serialized: all JS callbacks are serialized via a global lockunsafe-parallel(default): JS callbacks are invoked concurrently at your own risk
Example
// Example: enable parallel callbacks (expert only)
setGlobalConcurrency("unsafe-parallel");
// ... do parallel-safe work ...
setGlobalConcurrency("serialized");
Parameters:
| Name | Type | Description |
|---|---|---|
mode |
"serialized" | "unsafe-parallel" |
(static) shutdownExecutor()
Shutdown the shared ExecutorService and proactively stop registered virtual threads.
Destructive for pooled threads; future TCThread#start will recreate the pool.
Example
// Example: destructive shutdown (tests/teardown)
shutdownExecutor();
(static) stopAllThreads(optionsopt)
Stop all registered threads and guarantee registry cleanup.
Example
// Example: stop everything quickly
stopAllThreads({ timeout: 300, step: 25 });
// or
stopAllThreads();
Parameters:
| Name | Type | Attributes | Description | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
options |
Object |
<optional> |
Milliseconds window (default 1000/50) Properties
|
(static) threadCount() → {number}
Total number of registered threads.
Example
// Example: count after starting two threads
var t1=new TCThread("c1",()=>delay(30)),
t2=new TCThread("c2",()=>delay(30));
t1.start();
t2.start();
print(threadCount()>=2);
Returns:
- Type
- number
(static) threadCountByPrefix(prefix) → {number}
Count threads whose names start with a given prefix.
Example
// Example: count by prefix
var x1=new TCThread("job_x_1",()=>delay(30)),
x2=new TCThread("job_x_2",()=>delay(30));
x1.start();
x2.start();
print(threadCountByPrefix("job_x_")===2);
Parameters:
| Name | Type | Description |
|---|---|---|
prefix |
string |
Returns:
- Type
- number