Anthony O
Anthony O

Reputation: 672

Are synchronous functions in Dart executed atomically?

I understand that Dart is single-threaded and that within an isolate a function call is popped from the event loop queue and executed. There seems to be two cases, async and sync.

a) Async: An asynchronous function will run without interruption until it gets to the await keyword. At this point, it may release control of the instruction pointer or continue its routine. (i.e. async functions can be but are not required to be interrupted on await)

b) Sync: All instructions from setup -> body -> and teardown are executed without interruption. If this is the case, I would say that synchronous functions are atomic.

I have an event listener that may have multiple calls in the event loop queue. I think I have two options.

Using the Synchronized package

a) Async version:

import 'package:synchronized/synchronized.dart';

final Lock _lock = Lock();

...

() async {
    await _lock.synchronized(() async {
      if (_condition) {
        _signal.complete(status);
        _condition = !_condition;
      }
    });
}

b) Sync version:

() {
    if (_condition) {
      _signal.complete(status);
      _condition = !_condition;
    }
}

From my understanding of the Dart concurrency model these are equivalent. I prefer b) because it is simple. However, this requires that there cannot be a race condition between two calls to my sync event handler. I have used concurrency in languages with GIL and MT but not with the event-loop paradigm.

Upvotes: 0

Views: 829

Answers (1)

jamesdlin
jamesdlin

Reputation: 90125

a) Async: An asynchronous function will run without interruption until it gets to the await keyword. At this point, it may release control of the instruction pointer or continue its routine. (i.e. async functions can be but are not required to be interrupted on await)

await always yields. It's equivalent to setting up a Future.then() callback and returning to the Dart event loop.

For your simple example, there's no reason to use _lock.synchronized(). Synchronous code cannot be interrupted, and isolates (as their name imply) don't share memory. You would want some form of locking mechanism if your callback did asynchronous work and you needed to prevent concurrent asynchronous operations from being interleaved.

Upvotes: 1

Related Questions