| 72 | { |
| 73 | std::lock_guard<Mutex> lock(_mutex); |
| 74 | if (_state != State::Running) { |
| 75 | return; |
| 76 | } |
| 77 | _state = State::Terminated; |
| 78 | _hostOnMessage = nullptr; |
| 79 | } |
| 80 | |
| 81 | // Aggressive termination forces the JS engine to abort mid-execution (even a frozen worker), which |
| 82 | // tears down in-flight bridge calls and causes teardown-race side effects. In cooperative mode we |
| 83 | // skip the forced abort: the worker drains its current work on the serial JS queue and the |
| 84 | // async-queued teardown then runs cleanly after it (matching self.close()). |
| 85 | if (!_workerRuntime->cooperativeTermination()) { |
| 86 | _workerRuntime->requestExecutionTermination(); |
| 87 | } |
| 88 | _workerRuntime->requestFullTeardown(); |
| 89 | } |
| 90 | |
| 91 | void JavaScriptWorker::doPostInit() { |
| 92 | auto weakSelf = weakRef(this); |
| 93 | // Set up globals in the worker runtime |
| 94 | // - onmessage |
| 95 | // - postMessage |
| 96 | // - close |
| 97 | // - location, https://developer.mozilla.org/en-US/docs/Web/API/WorkerLocation, only href and search are populated |
| 98 | _workerRuntime->setValueToGlobalObject(STRING_LITERAL("onmessage"), Value::undefined()); |
| 99 | auto postMessageFunc = [weakSelf](const ValueFunctionCallContext& callContext) -> Value { |
| 100 | auto self = weakSelf.lock(); |
| 101 | if (self && self->isRunning()) { |
| 102 | auto hostRuntime = Ref<JavaScriptRuntime>(self->_hostRuntime.lock()); |
| 103 | if (hostRuntime == nullptr) { |
| 104 | return Value::undefined(); |
| 105 | } |
| 106 | auto transfer = callContext.getParametersSize() > 1 ? callContext.getParameter(1) : Value::undefinedRef(); |
| 107 | auto message = JavaScriptMessage::make(callContext.getParameter(0), transfer, nullptr); |
| 108 | if (!message) { |
| 109 | callContext.getExceptionTracker().onError(message.moveError()); |
| 110 | return Value::undefined(); |
| 111 | } |
| 112 | message.value()->dispatchHandler(self->getHostOnMessage(), [weakSelf]() { |
| 113 | auto self = weakSelf.lock(); |
| 114 | return self != nullptr && self->canDeliverPendingMessage(); |
no test coverage detected