start method

Future<void> start()

Starts execution of this Thread in a new Isolate.

The entry function passed to this thread must be a top-level or static function. Once started, the Isolate will execute that function with an internal ThreadMessage containing a SendPort and optional data.

Throws InvalidArgumentException if called more than once.

Example:

await thread.start();

Implementation

Future<void> start() async {
  if (_isolate != null) {
    throw InvalidArgumentException('DartThread already started.');
  }

  _receivePort = ReceivePort();
  _joinCompleter = Completer<void>();

  _isolate = await Isolate.spawn<ThreadMessage>(
    _entryPoint,
    ThreadMessage(_receivePort!.sendPort, initialMessage),
    debugName: _debugName,
    errorsAreFatal: true,
  );

  _activeThreads[_isolate!] = this; // Register the thread instance

  _receivePort!.listen((message) {
    if (message == 'done') {
      _joinCompleter?.complete();
      _receivePort?.close();
      _activeThreads.remove(_isolate); // Unregister on completion
      _isolate = null;
    } else if (message is List && message[0] == 'error') {
      _joinCompleter?.completeError(ThreadSpawnException(message[1], cause: message[2]));
      _receivePort?.close();
      _activeThreads.remove(_isolate); // Unregister on error
      _isolate = null;
    }
  }, onError: (error) {
    _joinCompleter?.completeError(error);
    _receivePort?.close();
    _activeThreads.remove(_isolate); // Unregister on error
    _isolate = null;
  }, onDone: () {
    // This callback is invoked when the ReceivePort is closed.
    // If the completer is not yet completed, it means:
    // 1. The Isolate exited without sending 'done' or an explicit error message.
    // 2. The Isolate was killed by `interrupt()`.
    // In both cases, it's not a successful completion from the perspective of `join()`.
    if (!(_joinCompleter?.isCompleted ?? false)) {
      // If it was killed by interrupt(), interrupt() already called completeError.
      // If it exited unexpectedly, we should complete with an error.
      _joinCompleter?.completeError(ThreadInterruptedException('Isolate $_debugName terminated unexpectedly or was interrupted.'));
    }
    _activeThreads.remove(_isolate); // Ensure unregistration on any done event
  });
}