Breaking change 49878: Throw a StateError if ResourceHandle.to* is called more than once

63 views
Skip to first unread message

Brian Quinlan

unread,
Aug 31, 2022, 2:48:30 PM8/31/22
to anno...@dartlang.org
Discussion at:

Change

Throw a StateError if ResourceHandle.toFile(), ResourceHandle.toSocket(), ResourceHandle.toRawSocket() or ResourceHandle.toRawDatagramSocket() is called more than once.

Rationale

Calling ResourceHandle.toFile()ResourceHandle.toSocket()ResourceHandle.toRawSocket() or ResourceHandle.toRawDatagramSocket() more than once produces two distinct Dart objects that are backed by the same file descriptor, which will become invalid when one object is closed or GCed.

For example:

void main(List<String> args) async {
  final executeInternalCommand = DynamicLibrary.process().lookupFunction<
      Void Function(Pointer<Char>, Pointer<Void>),
      void Function(
          Pointer<Char>, Pointer<Void>)>('Dart_ExecuteInternalCommand');
  final gcNow = "gc-now".toNativeUtf8();

  final file = File('/tmp/file.txt');

  await file.create();
  final openFile = await file.open();

  final handle = ResourceHandle.fromFile(openFile);
  handle.toFile().writeStringSync('test');
  executeInternalCommand(gcNow.cast(), nullptr);  // Will collect the file produced by `toFile` .
  handle.toFile().writeStringSync('test');  // Error because the file descriptor is no longer valid.
}

Impact

It is unlikely that this will break any existing correct code.

Mitigation

Users can save the result of the ResourceHandle.toFile(), etc. and use that instead of calling ResourceHandle.toFile() again.


Reply all
Reply to author
Forward
0 new messages