MCPcopy Create free account
hub / github.com/codenameone/CodenameOne / drain

Function drain

vm/ByteCodeTranslator/src/javascript/parparvm_runtime.js:2688–2861  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

2686 }, 0);
2687 },
2688 drain() {
2689 if (this.draining) {
2690 return;
2691 }
2692 // Opportunistic wakeup delivery on every outermost drain (i.e. every host
2693 // event that wakes the worker): when the one-shot wakeup timeout is being
2694 // throttled by the host (see _ensureWakeupPump), due sleeps/waits still
2695 // fire with near-zero latency here instead of waiting for the 1s pump.
2696 // O(pending) once per burst; no-op when nothing is due.
2697 if (this.timedWakeups.length && !this._processingWakeups
2698 && this._earliestWakeAt() <= this.schedulerNow() + 1) {
2699 this._processExpiredTimedWakeups();
2700 }
2701 this.draining = true;
2702 const deadline = this.schedulerNow() + 8;
2703 let steps = 0;
2704 // Threads held aside while the capture gate is owned by another thread (see
2705 // captureGateOwner). They are NOT lost: restored to runnable in the finally,
2706 // and endCaptureGate()/scheduleDrain re-runs them once the gate clears. Stays
2707 // null on every non-capture drain, so the steady-state hot path is untouched.
2708 let captureDeferred = null;
2709 try {
2710 while (this.runnable.length) {
2711 if (steps++ > 2048 || this.schedulerNow() >= deadline) {
2712 this.scheduleDrain();
2713 break;
2714 }
2715 // While a screenshot capture is reading the canvas, defer any OTHER
2716 // thread so it can't paint mid-capture (the off-by-one race). The owner
2717 // itself is never deferred, and the gate is null outside captures.
2718 if (this.captureGateOwner && this.runnable[0] !== this.captureGateOwner) {
2719 (captureDeferred || (captureDeferred = [])).push(this.runnable.shift());
2720 continue;
2721 }
2722 // Atomic-thread mode (set by flushGraphics' begin/endGraphicsAtomic
2723 // pair) used to suppress dispatch of every other green thread.
2724 // That created a deadlock window with cooperative monitor parking:
2725 // if the atomic thread blocks on a monitor held by some other
2726 // green thread, drain refuses to run the holder, the holder
2727 // never releases, the atomic thread never unparks. Cooperative
2728 // monitor semantics already prevent the recursive-paint flood
2729 // the atomic flag was guarding against -- a thread that re-enters
2730 // synchronized(pendingDisplay) inside flushGraphics naturally
2731 // queues behind the active flush. Trusting the locks instead of
2732 // the atomic flag avoids the deadlock without re-introducing
2733 // the flood.
2734 const thread = this.runnable.shift();
2735 if (thread.done) {
2736 continue;
2737 }
2738 this.currentThread = thread;
2739 // Worker-liveness probe feeding the heartbeat timer below: a frozen
2740 // resume count with a live heartbeat means parked/starved, a stopped
2741 // heartbeat means a synchronous infinite loop in this step. The resume
2742 // counter is a trivial increment; the (string-building) label is only
2743 // recorded under diag so production pays nothing.
2744 this.__cn1ResumeCount = (this.__cn1ResumeCount | 0) + 1;
2745 if (VM_DIAG_ENABLED) {

Callers

nothing calls this directly

Calls 12

threadDebugLabelFunction · 0.85
shouldTraceThreadFunction · 0.85
vmTraceFunction · 0.85
__cn1TickResetFunction · 0.85
vmLifecycleFunction · 0.85
emitVmMessageFunction · 0.85
pushMethod · 0.65
shiftMethod · 0.65
nextMethod · 0.65
unshiftMethod · 0.65
notifyAllMethod · 0.45
failMethod · 0.45

Tested by

no test coverage detected