Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit d1f7562

Browse files
Add support for System.channelWriteEtc and System.channelQueryAndReadEtc.
These use the zx_channel_write_etc and zx_channel_read_etc syscalls, which implements the majority of https://fxbug.dev/68600. Also add HandleDisposition, HandleInfoResult, and ReadEtcResult classes to dart:zircon's API surface. I've added tests to channel_test and handle_disposition_test, and ran them locally.
1 parent 156760e commit d1f7562

File tree

11 files changed

+479
-17
lines changed

11 files changed

+479
-17
lines changed

shell/platform/fuchsia/dart-pkg/zircon/BUILD.gn

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ source_set("zircon") {
1414
sources = [
1515
"sdk_ext/handle.cc",
1616
"sdk_ext/handle.h",
17+
"sdk_ext/handle_disposition.cc",
18+
"sdk_ext/handle_disposition.h",
1719
"sdk_ext/handle_waiter.cc",
1820
"sdk_ext/handle_waiter.h",
1921
"sdk_ext/natives.cc",
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright 2021 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
part of zircon;
6+
7+
// ignore_for_file: native_function_body_in_non_sdk_code
8+
// ignore_for_file: public_member_api_docs
9+
10+
@pragma('vm:entry-point')
11+
class HandleDisposition extends NativeFieldWrapperClass2 {
12+
@pragma('vm:entry-point')
13+
HandleDisposition(int operation, Handle handle, int type, int rights) {
14+
_constructor(operation, handle, type, rights);
15+
}
16+
17+
void _constructor(int operation, Handle handle, int type, int rights)
18+
native 'HandleDisposition_constructor';
19+
20+
int get operation native 'HandleDisposition_operation';
21+
Handle get handle native 'HandleDisposition_handle';
22+
int get type native 'HandleDisposition_type';
23+
int get rights native 'HandleDisposition_rights';
24+
int get result native 'HandleDisposition_result';
25+
26+
@override
27+
String toString() =>
28+
'HandleDisposition(operation=$operation, handle=$handle, type=$type, rights=$rights, result=$result)';
29+
}

shell/platform/fuchsia/dart-pkg/zircon/lib/src/system.dart

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,49 @@ class ReadResult extends _Result {
9898
'ReadResult(status=$status, bytes=$_bytes, numBytes=$_numBytes, handles=$_handles)';
9999
}
100100

101+
@pragma('vm:entry-point')
102+
class HandleInfo {
103+
final Handle handle;
104+
final int type;
105+
final int rights;
106+
107+
@pragma('vm:entry-point')
108+
const HandleInfo(this.handle, this.type, this.rights);
109+
110+
@override
111+
String toString() =>
112+
'HandleInfo(handle=$handle, type=$type, rights=$rights)';
113+
}
114+
115+
@pragma('vm:entry-point')
116+
class ReadEtcResult extends _Result {
117+
final ByteData? _bytes;
118+
final int? _numBytes;
119+
final List<HandleInfo>? _handleInfos;
120+
121+
ByteData get bytes => _bytes!;
122+
int get numBytes => _numBytes!;
123+
List<HandleInfo> get handleInfos => _handleInfos!;
124+
125+
@pragma('vm:entry-point')
126+
const ReadEtcResult(final int status, [this._bytes, this._numBytes, this._handleInfos])
127+
: super(status);
128+
129+
/// Returns the bytes as a Uint8List. If status != OK this will throw
130+
/// an exception.
131+
Uint8List bytesAsUint8List() {
132+
return _bytes!.buffer.asUint8List(_bytes!.offsetInBytes, _numBytes!);
133+
}
134+
135+
/// Returns the bytes as a String. If status != OK this will throw
136+
/// an exception.
137+
String bytesAsUTF8String() => utf8.decode(bytesAsUint8List());
138+
139+
@override
140+
String toString() =>
141+
'ReadEtcResult(status=$status, bytes=$_bytes, numBytes=$_numBytes, handleInfos=$_handleInfos)';
142+
}
143+
101144
@pragma('vm:entry-point')
102145
class WriteResult extends _Result {
103146
final int? _numBytes;
@@ -161,8 +204,12 @@ class System extends NativeFieldWrapperClass2 {
161204
native 'System_ConnectToService';
162205
static int channelWrite(Handle channel, ByteData data, List<Handle> handles)
163206
native 'System_ChannelWrite';
207+
static int channelWriteEtc(Handle channel, ByteData data, List<HandleDisposition> handleDispositions)
208+
native 'System_ChannelWriteEtc';
164209
static ReadResult channelQueryAndRead(Handle channel)
165210
native 'System_ChannelQueryAndRead';
211+
static ReadEtcResult channelQueryAndReadEtc(Handle channel)
212+
native 'System_ChannelQueryAndReadEtc';
166213

167214
// Eventpair operations.
168215
static HandlePairResult eventpairCreate([int options = 0])

shell/platform/fuchsia/dart-pkg/zircon/lib/zircon.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@ import 'dart:nativewrappers';
99
import 'dart:typed_data';
1010

1111
part 'src/handle.dart';
12+
part 'src/handle_disposition.dart';
1213
part 'src/handle_waiter.dart';
1314
part 'src/system.dart';
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// Copyright 2021 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#include "handle_disposition.h"
6+
7+
#include <algorithm>
8+
9+
#include "third_party/tonic/dart_binding_macros.h"
10+
#include "third_party/tonic/dart_class_library.h"
11+
12+
using tonic::ToDart;
13+
14+
namespace zircon {
15+
namespace dart {
16+
17+
IMPLEMENT_WRAPPERTYPEINFO(zircon, HandleDisposition);
18+
19+
void HandleDisposition_constructor(Dart_NativeArguments args) {
20+
DartCallConstructor(&HandleDisposition::create, args);
21+
}
22+
23+
fml::RefPtr<HandleDisposition> HandleDisposition::create(
24+
zx_handle_op_t operation,
25+
fml::RefPtr<dart::Handle> handle,
26+
zx_obj_type_t type,
27+
zx_rights_t rights) {
28+
return fml::MakeRefCounted<HandleDisposition>(operation, handle, type, rights,
29+
ZX_OK);
30+
}
31+
32+
// clang-format: off
33+
34+
#define FOR_EACH_STATIC_BINDING(V) V(HandleDisposition, create)
35+
36+
#define FOR_EACH_BINDING(V) \
37+
V(HandleDisposition, operation) \
38+
V(HandleDisposition, handle) \
39+
V(HandleDisposition, type) \
40+
V(HandleDisposition, rights) \
41+
V(HandleDisposition, result)
42+
43+
// clang-format: on
44+
45+
// Tonic is missing a comma.
46+
#define DART_REGISTER_NATIVE_STATIC_(CLASS, METHOD) \
47+
DART_REGISTER_NATIVE_STATIC(CLASS, METHOD),
48+
49+
FOR_EACH_STATIC_BINDING(DART_NATIVE_CALLBACK_STATIC)
50+
FOR_EACH_BINDING(DART_NATIVE_NO_UI_CHECK_CALLBACK)
51+
52+
void HandleDisposition::RegisterNatives(tonic::DartLibraryNatives* natives) {
53+
natives->Register({{"HandleDisposition_constructor",
54+
HandleDisposition_constructor, 5, true},
55+
FOR_EACH_STATIC_BINDING(DART_REGISTER_NATIVE_STATIC_)
56+
FOR_EACH_BINDING(DART_REGISTER_NATIVE)});
57+
}
58+
59+
} // namespace dart
60+
} // namespace zircon
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// Copyright 2021 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#ifndef FLUTTER_SHELL_PLATFORM_FUCHSIA_DART_PKG_ZIRCON_SDK_EXT_HANDLE_DISPOSITION_H_
6+
#define FLUTTER_SHELL_PLATFORM_FUCHSIA_DART_PKG_ZIRCON_SDK_EXT_HANDLE_DISPOSITION_H_
7+
8+
#include <zircon/syscalls.h>
9+
10+
#include <vector>
11+
12+
#include "flutter/fml/memory/ref_counted.h"
13+
#include "handle.h"
14+
#include "third_party/dart/runtime/include/dart_api.h"
15+
#include "third_party/tonic/dart_library_natives.h"
16+
#include "third_party/tonic/dart_wrappable.h"
17+
18+
namespace zircon {
19+
namespace dart {
20+
/**
21+
* HandleDisposition is the native peer of a Dart object (HandleDisposition
22+
* in dart:zircon) that holds a Handle and additional properties.
23+
*/
24+
class HandleDisposition : public fml::RefCountedThreadSafe<HandleDisposition>,
25+
public tonic::DartWrappable {
26+
DEFINE_WRAPPERTYPEINFO();
27+
FML_FRIEND_REF_COUNTED_THREAD_SAFE(HandleDisposition);
28+
FML_FRIEND_MAKE_REF_COUNTED(HandleDisposition);
29+
30+
public:
31+
static void RegisterNatives(tonic::DartLibraryNatives* natives);
32+
33+
static fml::RefPtr<HandleDisposition> create(zx_handle_op_t operation,
34+
fml::RefPtr<dart::Handle> handle,
35+
zx_obj_type_t type,
36+
zx_rights_t rights);
37+
38+
zx_handle_op_t operation() const { return operation_; }
39+
fml::RefPtr<dart::Handle> handle() const { return handle_; }
40+
zx_obj_type_t type() const { return type_; }
41+
zx_rights_t rights() const { return rights_; }
42+
zx_status_t result() const { return result_; }
43+
void set_result(zx_status_t result) { result_ = result; }
44+
45+
private:
46+
explicit HandleDisposition(zx_handle_op_t operation,
47+
fml::RefPtr<dart::Handle> handle,
48+
zx_obj_type_t type,
49+
zx_rights_t rights,
50+
zx_status_t result)
51+
: operation_(operation),
52+
handle_(handle),
53+
type_(type),
54+
rights_(rights),
55+
result_(result) {}
56+
57+
void RetainDartWrappableReference() const override { AddRef(); }
58+
59+
void ReleaseDartWrappableReference() const override { Release(); }
60+
61+
zx_handle_op_t operation_;
62+
fml::RefPtr<dart::Handle> handle_;
63+
zx_obj_type_t type_;
64+
zx_rights_t rights_;
65+
zx_status_t result_;
66+
};
67+
68+
} // namespace dart
69+
} // namespace zircon
70+
71+
#endif // FLUTTER_SHELL_PLATFORM_FUCHSIA_DART_PKG_ZIRCON_SDK_EXT_HANDLE_DISPOSITION_H_

shell/platform/fuchsia/dart-pkg/zircon/sdk_ext/natives.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <vector>
1212

1313
#include "handle.h"
14+
#include "handle_disposition.h"
1415
#include "handle_waiter.h"
1516
#include "system.h"
1617
#include "third_party/dart/runtime/include/dart_api.h"
@@ -32,6 +33,7 @@ static tonic::DartLibraryNatives* g_natives;
3233

3334
tonic::DartLibraryNatives* InitNatives() {
3435
tonic::DartLibraryNatives* natives = new tonic::DartLibraryNatives();
36+
HandleDisposition::RegisterNatives(natives);
3537
HandleWaiter::RegisterNatives(natives);
3638
Handle::RegisterNatives(natives);
3739
System::RegisterNatives(natives);

0 commit comments

Comments
 (0)