Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

print and writeln are not thread-safe #53471

Closed
ntkme opened this issue Sep 9, 2023 · 2 comments
Closed

print and writeln are not thread-safe #53471

ntkme opened this issue Sep 9, 2023 · 2 comments
Assignees
Labels
area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. P3 A lower priority bug or feature request triaged Issue has been triaged by sub team

Comments

@ntkme
Copy link
Contributor

ntkme commented Sep 9, 2023

Here is the minimum reproduction:

import 'dart:isolate';

void main() {
  Future.wait([
    for (var i = 0; i < 100; i += 1)
      Isolate.run(() {
        print('test');
      })
  ]);
}

The expected output is 100 lines that each contains a single test, but the actual result is that some of the lines are empty and some of the lines will have testtest.

The underneath issue is that print uses writeln internally, and writeln would output the message and a newline character in two separate calls, causing a race condition between threads.


As a workaround, directly calling write with newline character added to message is thread-safe.

import 'dart:isolate';
import 'dart:io';

void main() {
  Future.wait([
    for (var i = 0; i < 100; i += 1)
      Isolate.run(() {
        stdout.write('test\n');
      })
  ]);
}
@ntkme ntkme changed the title print is not thread-safe print and writeln are not thread-safe Sep 9, 2023
@lrhn
Copy link
Member

lrhn commented Sep 9, 2023

Adding the \n on the string will copy the entire string one extra time. That's definitely unnecessary overhead.
(And on Windows, we'd still have to convert the \n to \r\n afterwards.)

One thing we could perhaps do, is to let the internal implementation of print include the line terminator in the same native memory buffer that we convert the string to UTF-8 into anyway. Then we can emit the line terminator along with the string contents, in the same native write call.

If we give Dart_StringToUTF8 an extra integer argument, the number of extra bytes to make room for in the allocation, after the bytes of the string, then we can insert the newline into that, instead writing it as a second call.

@lrhn lrhn added area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. library-io and removed library-io labels Sep 9, 2023
@a-siva a-siva self-assigned this Sep 11, 2023
@a-siva a-siva added P3 A lower priority bug or feature request triaged Issue has been triaged by sub team labels Oct 12, 2023
@a-siva
Copy link
Contributor

a-siva commented Nov 3, 2023

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-vm Use area-vm for VM related issues, including code coverage, and the AOT and JIT backends. P3 A lower priority bug or feature request triaged Issue has been triaged by sub team
Projects
None yet
Development

No branches or pull requests

4 participants
@ntkme @lrhn @a-siva and others