[dart:io] update return type of native calls

Some cleans up coming from https://dart-review.googlesource.com/c/sdk/+/136322.
Update some inaccurate return types of native calls.
Also update null checks for resourceInfo with nnbd flavor.

Change-Id: I937f204e5cd8331df454c81d58e5893be616862e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/137140
Commit-Queue: Zichang Guo <zichangguo@google.com>
Reviewed-by: Siva Annamalai <asiva@google.com>
This commit is contained in:
Zichang Guo 2020-03-02 18:06:32 +00:00 committed by commit-bot@chromium.org
parent 86845cabb8
commit 0b819161d7
6 changed files with 297 additions and 323 deletions

View file

@ -344,8 +344,7 @@ void FUNCTION_NAME(Socket_Read)(Dart_NativeArguments args) {
uint8_t* buffer = NULL;
Dart_Handle result = IOBuffer::Allocate(length, &buffer);
if (Dart_IsNull(result)) {
Dart_SetReturnValue(args, DartUtils::NewDartOSError());
return;
Dart_ThrowException(DartUtils::NewDartOSError());
}
if (Dart_IsError(result)) {
Dart_PropagateError(result);
@ -359,8 +358,7 @@ void FUNCTION_NAME(Socket_Read)(Dart_NativeArguments args) {
uint8_t* new_buffer = NULL;
Dart_Handle new_result = IOBuffer::Allocate(bytes_read, &new_buffer);
if (Dart_IsNull(new_result)) {
Dart_SetReturnValue(args, DartUtils::NewDartOSError());
return;
Dart_ThrowException(DartUtils::NewDartOSError());
}
if (Dart_IsError(new_result)) {
Dart_PropagateError(new_result);
@ -374,11 +372,11 @@ void FUNCTION_NAME(Socket_Read)(Dart_NativeArguments args) {
Dart_SetReturnValue(args, Dart_Null());
} else {
ASSERT(bytes_read == -1);
Dart_SetReturnValue(args, DartUtils::NewDartOSError());
Dart_ThrowException(DartUtils::NewDartOSError());
}
} else {
OSError os_error(-1, "Invalid argument", OSError::kUnknown);
Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
Dart_ThrowException(DartUtils::NewDartOSError(&os_error));
}
}
@ -407,8 +405,7 @@ void FUNCTION_NAME(Socket_RecvFrom)(Dart_NativeArguments args) {
}
if (bytes_read < 0) {
ASSERT(bytes_read == -1);
Dart_SetReturnValue(args, DartUtils::NewDartOSError());
return;
Dart_ThrowException(DartUtils::NewDartOSError());
}
// Datagram data read. Copy into buffer of the exact size,
@ -416,8 +413,7 @@ void FUNCTION_NAME(Socket_RecvFrom)(Dart_NativeArguments args) {
uint8_t* data_buffer = NULL;
Dart_Handle data = IOBuffer::Allocate(bytes_read, &data_buffer);
if (Dart_IsNull(data)) {
Dart_SetReturnValue(args, DartUtils::NewDartOSError());
return;
Dart_ThrowException(DartUtils::NewDartOSError());
}
if (Dart_IsError(data)) {
Dart_PropagateError(data);
@ -497,9 +493,13 @@ void FUNCTION_NAME(Socket_WriteList)(Dart_NativeArguments args) {
}
} else {
// Extract OSError before we release data, as it may override the error.
OSError os_error;
Dart_TypedDataReleaseData(buffer_obj);
Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
Dart_Handle error;
{
OSError os_error;
Dart_TypedDataReleaseData(buffer_obj);
error = DartUtils::NewDartOSError(&os_error);
}
Dart_ThrowException(error);
}
}
@ -533,28 +533,30 @@ void FUNCTION_NAME(Socket_SendTo)(Dart_NativeArguments args) {
Dart_SetIntegerReturnValue(args, bytes_written);
} else {
// Extract OSError before we release data, as it may override the error.
OSError os_error;
Dart_TypedDataReleaseData(buffer_obj);
Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
Dart_Handle error;
{
OSError os_error;
Dart_TypedDataReleaseData(buffer_obj);
error = DartUtils::NewDartOSError(&os_error);
}
Dart_ThrowException(error);
}
}
void FUNCTION_NAME(Socket_GetPort)(Dart_NativeArguments args) {
Socket* socket =
Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
OSError os_error;
intptr_t port = SocketBase::GetPort(socket->fd());
if (port > 0) {
Dart_SetIntegerReturnValue(args, port);
} else {
Dart_SetReturnValue(args, DartUtils::NewDartOSError());
Dart_ThrowException(DartUtils::NewDartOSError());
}
}
void FUNCTION_NAME(Socket_GetRemotePeer)(Dart_NativeArguments args) {
Socket* socket =
Socket::GetSocketIdNativeField(Dart_GetNativeArgument(args, 0));
OSError os_error;
intptr_t port = 0;
SocketAddress* addr = SocketBase::GetRemotePeer(socket->fd(), &port);
if (addr != NULL) {
@ -572,7 +574,7 @@ void FUNCTION_NAME(Socket_GetRemotePeer)(Dart_NativeArguments args) {
Dart_SetReturnValue(args, list);
delete addr;
} else {
Dart_SetReturnValue(args, DartUtils::NewDartOSError());
Dart_ThrowException(DartUtils::NewDartOSError());
}
}
@ -660,7 +662,7 @@ void FUNCTION_NAME(ServerSocket_Accept)(Dart_NativeArguments args) {
} else if (new_socket == ServerSocket::kTemporaryFailure) {
Dart_SetReturnValue(args, Dart_False());
} else {
Dart_SetReturnValue(args, DartUtils::NewDartOSError());
Dart_ThrowException(DartUtils::NewDartOSError());
}
}
@ -840,7 +842,7 @@ void FUNCTION_NAME(Socket_GetOption)(Dart_NativeArguments args) {
}
// In case of failure the return value is not set above.
if (!ok) {
Dart_SetReturnValue(args, DartUtils::NewDartOSError());
Dart_ThrowException(DartUtils::NewDartOSError());
}
}
@ -881,10 +883,8 @@ void FUNCTION_NAME(Socket_SetOption)(Dart_NativeArguments args) {
Dart_PropagateError(Dart_NewApiError("Value outside expected range"));
break;
}
if (result) {
Dart_SetReturnValue(args, Dart_Null());
} else {
Dart_SetReturnValue(args, DartUtils::NewDartOSError());
if (!result) {
Dart_ThrowException(DartUtils::NewDartOSError());
}
}
@ -910,10 +910,8 @@ void FUNCTION_NAME(Socket_SetRawOption)(Dart_NativeArguments args) {
Dart_TypedDataReleaseData(data_obj);
if (result) {
Dart_SetReturnValue(args, Dart_Null());
} else {
Dart_SetReturnValue(args, DartUtils::NewDartOSError());
if (!result) {
Dart_ThrowException(DartUtils::NewDartOSError());
}
}
@ -938,11 +936,8 @@ void FUNCTION_NAME(Socket_GetRawOption)(Dart_NativeArguments args) {
static_cast<int>(option), data, &int_length);
Dart_TypedDataReleaseData(data_obj);
if (result) {
Dart_SetReturnValue(args, Dart_Null());
} else {
Dart_SetReturnValue(args, DartUtils::NewDartOSError());
if (!result) {
Dart_ThrowException(DartUtils::NewDartOSError());
}
}
@ -999,11 +994,9 @@ void FUNCTION_NAME(Socket_JoinMulticast)(Dart_NativeArguments args) {
}
int interfaceIndex =
DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 3));
if (SocketBase::JoinMulticast(socket->fd(), addr, interface,
interfaceIndex)) {
Dart_SetReturnValue(args, Dart_Null());
} else {
Dart_SetReturnValue(args, DartUtils::NewDartOSError());
if (!SocketBase::JoinMulticast(socket->fd(), addr, interface,
interfaceIndex)) {
Dart_ThrowException(DartUtils::NewDartOSError());
}
}
@ -1018,11 +1011,9 @@ void FUNCTION_NAME(Socket_LeaveMulticast)(Dart_NativeArguments args) {
}
int interfaceIndex =
DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 3));
if (SocketBase::LeaveMulticast(socket->fd(), addr, interface,
interfaceIndex)) {
Dart_SetReturnValue(args, Dart_Null());
} else {
Dart_SetReturnValue(args, DartUtils::NewDartOSError());
if (!SocketBase::LeaveMulticast(socket->fd(), addr, interface,
interfaceIndex)) {
Dart_ThrowException(DartUtils::NewDartOSError());
}
}

View file

@ -164,7 +164,7 @@ typedef struct _Dart_Isolate* Dart_Isolate;
* 2 intptr_t* length = 0;
* 3 result = Dart_StringLength(arg, &length);
* 4 if (Dart_IsError(result)) {
* 5 return result
* 5 return result;
* 6 }
* 7 return Dart_NewBoolean(length > 100);
* 8 }

View file

@ -711,70 +711,62 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject {
throw ArgumentError("Illegal length $count");
}
if (isClosing || isClosed) return null;
var length = count == null ? available : min(available, count);
if (length == 0) return null;
var result = nativeRead(length);
if (result is OSError) {
reportError(result, StackTrace.current, "Read failed");
return null;
}
final list = result as Uint8List;
if (list != null) {
if (count == null) {
// If count is not specified, read as many bytes as possible.
// This checks remaining bytes, if available > 0, issue() in
// issueReadEvent() will keep reading.
available = nativeAvailable();
} else {
available -= list.length;
try {
var length = count == null ? available : min(available, count);
if (length == 0) return null;
Uint8List list = nativeRead(length);
if (list != null) {
if (count == null) {
// If count is not specified, read as many bytes as possible.
// This checks remaining bytes, if available > 0, issue() in
// issueReadEvent() will keep reading.
available = nativeAvailable();
} else {
available -= list.length;
}
if (resourceInfo != null) {
resourceInfo.totalRead += list.length;
}
}
// TODO(ricow): Remove when we track internal and pipe uses.
assert(resourceInfo != null || isPipe || isInternal || isInternalSignal);
if (resourceInfo != null) {
resourceInfo.totalRead += list.length;
resourceInfo.didRead();
}
if (!const bool.fromEnvironment("dart.vm.product")) {
_SocketProfile.collectStatistic(
nativeGetSocketId(), _SocketProfileType.readBytes, list?.length);
}
return list;
} catch (e) {
reportError(e, StackTrace.current, "Read failed");
}
// TODO(ricow): Remove when we track internal and pipe uses.
assert(resourceInfo != null || isPipe || isInternal || isInternalSignal);
if (resourceInfo != null) {
resourceInfo.didRead();
}
if (!const bool.fromEnvironment("dart.vm.product")) {
_SocketProfile.collectStatistic(
nativeGetSocketId(), _SocketProfileType.readBytes, list?.length);
}
return list;
}
Datagram receive() {
if (isClosing || isClosed) return null;
var result = nativeRecvFrom();
if (result is OSError) {
reportError(result, StackTrace.current, "Receive failed");
try {
Datagram result = nativeRecvFrom();
if (result != null) {
// Read the next available. Available is only for the next datagram, not
// the sum of all datagrams pending, so we need to call after each
// receive. If available becomes > 0, the _NativeSocket will continue to
// emit read events.
available = nativeAvailable();
if (resourceInfo != null) {
resourceInfo.totalRead += result.data.length;
}
}
if (resourceInfo != null) {
resourceInfo.didRead();
}
if (!const bool.fromEnvironment("dart.vm.product")) {
_SocketProfile.collectStatistic(nativeGetSocketId(),
_SocketProfileType.readBytes, result?.data?.length);
}
return result;
} catch (e) {
reportError(e, StackTrace.current, "Receive failed");
return null;
}
if (result != null) {
// Read the next available. Available is only for the next datagram, not
// the sum of all datagrams pending, so we need to call after each
// receive. If available becomes > 0, the _NativeSocket will continue to
// emit read events.
available = nativeAvailable();
// TODO(ricow): Remove when we track internal and pipe uses.
assert(resourceInfo != null || isPipe || isInternal || isInternalSignal);
if (resourceInfo != null) {
resourceInfo.totalRead += result.data.length;
}
}
// TODO(ricow): Remove when we track internal and pipe uses.
assert(resourceInfo != null || isPipe || isInternal || isInternalSignal);
if (resourceInfo != null) {
resourceInfo.didRead();
}
if (!const bool.fromEnvironment("dart.vm.product")) {
_SocketProfile.collectStatistic(nativeGetSocketId(),
_SocketProfileType.readBytes, result?.data?.length);
}
return result;
}
int write(List<int> buffer, int offset, int bytes) {
@ -796,64 +788,62 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject {
}
if (isClosing || isClosed) return 0;
if (bytes == 0) return 0;
_BufferAndStart bufferAndStart =
_ensureFastAndSerializableByteData(buffer, offset, offset + bytes);
if (!const bool.fromEnvironment("dart.vm.product")) {
_SocketProfile.collectStatistic(
nativeGetSocketId(),
_SocketProfileType.writeBytes,
bufferAndStart.buffer.length - bufferAndStart.start);
}
var result =
nativeWrite(bufferAndStart.buffer, bufferAndStart.start, bytes);
if (result is OSError) {
OSError osError = result;
try {
_BufferAndStart bufferAndStart =
_ensureFastAndSerializableByteData(buffer, offset, offset + bytes);
if (!const bool.fromEnvironment("dart.vm.product")) {
_SocketProfile.collectStatistic(
nativeGetSocketId(),
_SocketProfileType.writeBytes,
bufferAndStart.buffer.length - bufferAndStart.start);
}
int result =
nativeWrite(bufferAndStart.buffer, bufferAndStart.start, bytes);
// The result may be negative, if we forced a short write for testing
// purpose. In such case, don't mark writeAvailable as false, as we don't
// know if we'll receive an event. It's better to just retry.
if (result >= 0 && result < bytes) {
writeAvailable = false;
}
// Negate the result, as stated above.
if (result < 0) result = -result;
// TODO(ricow): Remove when we track internal and pipe uses.
assert(resourceInfo != null || isPipe || isInternal || isInternalSignal);
if (resourceInfo != null) {
resourceInfo.addWrite(result);
}
return result;
} catch (e) {
StackTrace st = StackTrace.current;
scheduleMicrotask(() => reportError(osError, st, "Write failed"));
result = 0;
scheduleMicrotask(() => reportError(e, st, "Write failed"));
return 0;
}
// The result may be negative, if we forced a short write for testing
// purpose. In such case, don't mark writeAvailable as false, as we don't
// know if we'll receive an event. It's better to just retry.
if (result >= 0 && result < bytes) {
writeAvailable = false;
}
// Negate the result, as stated above.
if (result < 0) result = -result;
// TODO(ricow): Remove when we track internal and pipe uses.
assert(resourceInfo != null || isPipe || isInternal || isInternalSignal);
if (resourceInfo != null) {
resourceInfo.addWrite(result);
}
return result;
}
int send(List<int> buffer, int offset, int bytes, InternetAddress address,
int port) {
_throwOnBadPort(port);
if (isClosing || isClosed) return 0;
_BufferAndStart bufferAndStart =
_ensureFastAndSerializableByteData(buffer, offset, bytes);
if (!const bool.fromEnvironment("dart.vm.product")) {
_SocketProfile.collectStatistic(
nativeGetSocketId(),
_SocketProfileType.writeBytes,
bufferAndStart.buffer.length - bufferAndStart.start);
}
var result = nativeSendTo(bufferAndStart.buffer, bufferAndStart.start,
bytes, (address as _InternetAddress)._in_addr, port);
if (result is OSError) {
OSError osError = result;
try {
_BufferAndStart bufferAndStart =
_ensureFastAndSerializableByteData(buffer, offset, bytes);
if (!const bool.fromEnvironment("dart.vm.product")) {
_SocketProfile.collectStatistic(
nativeGetSocketId(),
_SocketProfileType.writeBytes,
bufferAndStart.buffer.length - bufferAndStart.start);
}
int result = nativeSendTo(bufferAndStart.buffer, bufferAndStart.start,
bytes, (address as _InternetAddress)._in_addr, port);
if (resourceInfo != null) {
resourceInfo.addWrite(result);
}
return result;
} catch (e) {
StackTrace st = StackTrace.current;
scheduleMicrotask(() => reportError(osError, st, "Send failed"));
result = 0;
scheduleMicrotask(() => reportError(e, st, "Send failed"));
return 0;
}
// TODO(ricow): Remove when we track internal and pipe uses.
assert(resourceInfo != null || isPipe || isInternal || isInternalSignal);
if (resourceInfo != null) {
resourceInfo.addWrite(result);
}
return result;
}
_NativeSocket accept() {
@ -880,16 +870,12 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject {
int get port {
if (localPort != 0) return localPort;
if (isClosing || isClosed) throw const SocketException.closed();
var result = nativeGetPort();
if (result is OSError) throw result;
return localPort = result;
return localPort = nativeGetPort();
}
int get remotePort {
if (isClosing || isClosed) throw const SocketException.closed();
var result = nativeGetRemotePeer();
if (result is OSError) throw result;
return result[1];
return nativeGetRemotePeer()[1];
}
InternetAddress get address => localAddress;
@ -897,7 +883,6 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject {
InternetAddress get remoteAddress {
if (isClosing || isClosed) throw const SocketException.closed();
var result = nativeGetRemotePeer();
if (result is OSError) throw result;
var addr = result[0];
var type = new InternetAddressType._from(addr[0]);
return new _InternetAddress(addr[1], null, addr[2]);
@ -1173,15 +1158,12 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject {
getOption(SocketOption option) {
if (option == null) throw new ArgumentError.notNull("option");
var result = nativeGetOption(option._value, address.type._value);
if (result is OSError) throw result;
return result;
return nativeGetOption(option._value, address.type._value);
}
bool setOption(SocketOption option, value) {
if (option == null) throw new ArgumentError.notNull("option");
var result = nativeSetOption(option._value, address.type._value, value);
if (result != null) throw result;
nativeSetOption(option._value, address.type._value, value);
return true;
}
@ -1189,8 +1171,7 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject {
if (option == null) throw new ArgumentError.notNull("option");
if (option.value == null) throw new ArgumentError.notNull("option.value");
var result = nativeGetRawOption(option.level, option.option, option.value);
if (result != null) throw result;
nativeGetRawOption(option.level, option.option, option.value);
return option.value;
}
@ -1198,8 +1179,7 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject {
if (option == null) throw new ArgumentError.notNull("option");
if (option.value == null) throw new ArgumentError.notNull("option.value");
var result = nativeSetRawOption(option.level, option.option, option.value);
if (result != null) throw result;
nativeSetRawOption(option.level, option.option, option.value);
}
InternetAddress multicastAddress(
@ -1229,26 +1209,24 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject {
void joinMulticast(InternetAddress addr, NetworkInterface interface) {
_InternetAddress interfaceAddr = multicastAddress(addr, interface);
var interfaceIndex = interface == null ? 0 : interface.index;
var result = nativeJoinMulticast((addr as _InternetAddress)._in_addr,
nativeJoinMulticast((addr as _InternetAddress)._in_addr,
interfaceAddr?._in_addr, interfaceIndex);
if (result is OSError) throw result;
}
void leaveMulticast(InternetAddress addr, NetworkInterface interface) {
_InternetAddress interfaceAddr = multicastAddress(addr, interface);
var interfaceIndex = interface == null ? 0 : interface.index;
var result = nativeLeaveMulticast((addr as _InternetAddress)._in_addr,
nativeLeaveMulticast((addr as _InternetAddress)._in_addr,
interfaceAddr?._in_addr, interfaceIndex);
if (result is OSError) throw result;
}
void nativeSetSocketId(int id, int typeFlags) native "Socket_SetSocketId";
nativeAvailable() native "Socket_Available";
nativeRead(int len) native "Socket_Read";
nativeRecvFrom() native "Socket_RecvFrom";
nativeWrite(List<int> buffer, int offset, int bytes)
int nativeAvailable() native "Socket_Available";
Uint8List nativeRead(int len) native "Socket_Read";
Datagram nativeRecvFrom() native "Socket_RecvFrom";
int nativeWrite(List<int> buffer, int offset, int bytes)
native "Socket_WriteList";
nativeSendTo(List<int> buffer, int offset, int bytes, Uint8List address,
int nativeSendTo(List<int> buffer, int offset, int bytes, Uint8List address,
int port) native "Socket_SendTo";
nativeCreateConnect(Uint8List addr, int port, int scope_id)
native "Socket_CreateConnect";
@ -1259,21 +1237,21 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject {
bool shared, int scope_id) native "ServerSocket_CreateBindListen";
nativeCreateBindDatagram(Uint8List addr, int port, bool reuseAddress,
bool reusePort, int ttl) native "Socket_CreateBindDatagram";
nativeAccept(_NativeSocket socket) native "ServerSocket_Accept";
bool nativeAccept(_NativeSocket socket) native "ServerSocket_Accept";
int nativeGetPort() native "Socket_GetPort";
List nativeGetRemotePeer() native "Socket_GetRemotePeer";
int nativeGetSocketId() native "Socket_GetSocketId";
OSError nativeGetError() native "Socket_GetError";
nativeGetOption(int option, int protocol) native "Socket_GetOption";
OSError nativeGetRawOption(int level, int option, Uint8List data)
void nativeGetRawOption(int level, int option, Uint8List data)
native "Socket_GetRawOption";
OSError nativeSetOption(int option, int protocol, value)
void nativeSetOption(int option, int protocol, value)
native "Socket_SetOption";
OSError nativeSetRawOption(int level, int option, Uint8List data)
void nativeSetRawOption(int level, int option, Uint8List data)
native "Socket_SetRawOption";
OSError nativeJoinMulticast(Uint8List addr, Uint8List interfaceAddr,
void nativeJoinMulticast(Uint8List addr, Uint8List interfaceAddr,
int interfaceIndex) native "Socket_JoinMulticast";
bool nativeLeaveMulticast(Uint8List addr, Uint8List interfaceAddr,
void nativeLeaveMulticast(Uint8List addr, Uint8List interfaceAddr,
int interfaceIndex) native "Socket_LeaveMulticast";
}

View file

@ -163,5 +163,6 @@ class Stdout {
static _getAnsiSupported(int fd) native "Stdout_AnsiSupported";
}
_getStdioHandle(_NativeSocket socket, int num) native "Socket_GetStdioHandle";
bool _getStdioHandle(_NativeSocket socket, int num)
native "Socket_GetStdioHandle";
_getSocketType(_NativeSocket nativeSocket) native "Socket_GetType";

View file

@ -710,71 +710,73 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject {
throw ArgumentError("Illegal length $count");
}
if (isClosing || isClosed) return null;
var length = count == null ? available : min(available, count);
if (length == 0) return null;
var result = nativeRead(length);
if (result is OSError) {
reportError(result, StackTrace.current, "Read failed");
try {
var length = count == null ? available : min(available, count);
if (length == 0) return null;
Uint8List? list = nativeRead(length);
final resourceInformation = resourceInfo;
assert(resourceInformation != null ||
isPipe ||
isInternal ||
isInternalSignal);
if (list != null) {
if (count == null) {
// If count is not specified, read as many bytes as possible.
// This checks remaining bytes, if available > 0, issue() in
// issueReadEvent() will keep reading.
available = nativeAvailable();
} else {
available -= list.length;
}
if (resourceInformation != null) {
resourceInformation.totalRead += list.length;
}
}
if (resourceInformation != null) {
resourceInformation.didRead();
}
if (!const bool.fromEnvironment("dart.vm.product")) {
_SocketProfile.collectStatistic(
nativeGetSocketId(), _SocketProfileType.readBytes, list?.length);
}
return list;
} catch (e) {
reportError(e, StackTrace.current, "Read failed");
return null;
}
final list = result as Uint8List?;
if (list != null) {
if (count == null) {
// If count is not specified, read as many bytes as possible.
// This checks remaining bytes, if available > 0, issue() in
// issueReadEvent() will keep reading.
available = nativeAvailable();
} else {
available -= list.length;
}
// TODO(ricow): Remove when we track internal and pipe uses.
assert(resourceInfo != null || isPipe || isInternal || isInternalSignal);
if (resourceInfo != null) {
resourceInfo!.totalRead += list.length;
}
}
// TODO(ricow): Remove when we track internal and pipe uses.
assert(resourceInfo != null || isPipe || isInternal || isInternalSignal);
if (resourceInfo != null) {
resourceInfo!.didRead();
}
if (!const bool.fromEnvironment("dart.vm.product")) {
_SocketProfile.collectStatistic(
nativeGetSocketId(), _SocketProfileType.readBytes, list?.length);
}
return list;
}
Datagram? receive() {
if (isClosing || isClosed) return null;
var result = nativeRecvFrom();
if (result is OSError) {
reportError(result, StackTrace.current, "Receive failed");
try {
Datagram? datagram = nativeRecvFrom();
final resourceInformation = resourceInfo;
assert(resourceInformation != null ||
isPipe ||
isInternal ||
isInternalSignal);
if (datagram != null) {
// Read the next available. Available is only for the next datagram, not
// the sum of all datagrams pending, so we need to call after each
// receive. If available becomes > 0, the _NativeSocket will continue to
// emit read events.
available = nativeAvailable();
if (resourceInformation != null) {
resourceInformation.totalRead += datagram.data.length;
}
}
if (resourceInformation != null) {
resourceInformation.didRead();
}
if (!const bool.fromEnvironment("dart.vm.product")) {
_SocketProfile.collectStatistic(nativeGetSocketId(),
_SocketProfileType.readBytes, datagram?.data.length);
}
return datagram;
} catch (e) {
reportError(e, StackTrace.current, "Receive failed");
return null;
}
final datagram = result as Datagram?;
if (datagram != null) {
// Read the next available. Available is only for the next datagram, not
// the sum of all datagrams pending, so we need to call after each
// receive. If available becomes > 0, the _NativeSocket will continue to
// emit read events.
available = nativeAvailable();
// TODO(ricow): Remove when we track internal and pipe uses.
assert(resourceInfo != null || isPipe || isInternal || isInternalSignal);
if (resourceInfo != null) {
resourceInfo!.totalRead += datagram.data.length;
}
}
// TODO(ricow): Remove when we track internal and pipe uses.
assert(resourceInfo != null || isPipe || isInternal || isInternalSignal);
if (resourceInfo != null) {
resourceInfo!.didRead();
}
if (!const bool.fromEnvironment("dart.vm.product")) {
_SocketProfile.collectStatistic(nativeGetSocketId(),
_SocketProfileType.readBytes, datagram?.data.length);
}
return datagram;
}
static int _fixOffset(int? offset) => offset ?? 0;
@ -795,64 +797,70 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject {
}
if (isClosing || isClosed) return 0;
if (bytes == 0) return 0;
_BufferAndStart bufferAndStart =
_ensureFastAndSerializableByteData(buffer, offset, offset + bytes);
if (!const bool.fromEnvironment("dart.vm.product")) {
_SocketProfile.collectStatistic(
nativeGetSocketId(),
_SocketProfileType.writeBytes,
bufferAndStart.buffer.length - bufferAndStart.start);
}
var result =
nativeWrite(bufferAndStart.buffer, bufferAndStart.start, bytes);
if (result is OSError) {
OSError osError = result;
try {
_BufferAndStart bufferAndStart =
_ensureFastAndSerializableByteData(buffer, offset, offset + bytes);
if (!const bool.fromEnvironment("dart.vm.product")) {
_SocketProfile.collectStatistic(
nativeGetSocketId(),
_SocketProfileType.writeBytes,
bufferAndStart.buffer.length - bufferAndStart.start);
}
int result =
nativeWrite(bufferAndStart.buffer, bufferAndStart.start, bytes);
// The result may be negative, if we forced a short write for testing
// purpose. In such case, don't mark writeAvailable as false, as we don't
// know if we'll receive an event. It's better to just retry.
if (result >= 0 && result < bytes) {
writeAvailable = false;
}
// Negate the result, as stated above.
if (result < 0) result = -result;
final resourceInformation = resourceInfo;
assert(resourceInformation != null ||
isPipe ||
isInternal ||
isInternalSignal);
if (resourceInformation != null) {
resourceInformation.addWrite(result);
}
return result;
} catch (e) {
StackTrace st = StackTrace.current;
scheduleMicrotask(() => reportError(osError, st, "Write failed"));
result = 0;
scheduleMicrotask(() => reportError(e, st, "Write failed"));
return 0;
}
// The result may be negative, if we forced a short write for testing
// purpose. In such case, don't mark writeAvailable as false, as we don't
// know if we'll receive an event. It's better to just retry.
if (result >= 0 && result < bytes) {
writeAvailable = false;
}
// Negate the result, as stated above.
if (result < 0) result = -result;
// TODO(ricow): Remove when we track internal and pipe uses.
assert(resourceInfo != null || isPipe || isInternal || isInternalSignal);
if (resourceInfo != null) {
resourceInfo!.addWrite(result);
}
return result;
}
int send(List<int> buffer, int offset, int bytes, InternetAddress address,
int port) {
_throwOnBadPort(port);
if (isClosing || isClosed) return 0;
_BufferAndStart bufferAndStart =
_ensureFastAndSerializableByteData(buffer, offset, bytes);
if (!const bool.fromEnvironment("dart.vm.product")) {
_SocketProfile.collectStatistic(
nativeGetSocketId(),
_SocketProfileType.writeBytes,
bufferAndStart.buffer.length - bufferAndStart.start);
}
var result = nativeSendTo(bufferAndStart.buffer, bufferAndStart.start,
bytes, (address as _InternetAddress)._in_addr, port);
if (result is OSError) {
OSError osError = result;
try {
_BufferAndStart bufferAndStart =
_ensureFastAndSerializableByteData(buffer, offset, bytes);
if (!const bool.fromEnvironment("dart.vm.product")) {
_SocketProfile.collectStatistic(
nativeGetSocketId(),
_SocketProfileType.writeBytes,
bufferAndStart.buffer.length - bufferAndStart.start);
}
int result = nativeSendTo(bufferAndStart.buffer, bufferAndStart.start,
bytes, (address as _InternetAddress)._in_addr, port);
final resourceInformation = resourceInfo;
assert(resourceInformation != null ||
isPipe ||
isInternal ||
isInternalSignal);
if (resourceInformation != null) {
resourceInformation.addWrite(result);
}
return result;
} catch (e) {
StackTrace st = StackTrace.current;
scheduleMicrotask(() => reportError(osError, st, "Send failed"));
result = 0;
scheduleMicrotask(() => reportError(e, st, "Send failed"));
return 0;
}
// TODO(ricow): Remove when we track internal and pipe uses.
assert(resourceInfo != null || isPipe || isInternal || isInternalSignal);
if (resourceInfo != null) {
resourceInfo!.addWrite(result);
}
return result;
}
_NativeSocket? accept() {
@ -867,11 +875,14 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject {
socket.localPort = localPort;
socket.localAddress = address;
setupResourceInfo(socket);
// TODO(ricow): Remove when we track internal and pipe uses.
assert(resourceInfo != null || isPipe || isInternal || isInternalSignal);
if (resourceInfo != null) {
final resourceInformation = resourceInfo;
assert(resourceInformation != null ||
isPipe ||
isInternal ||
isInternalSignal);
if (resourceInformation != null) {
// We track this as read one byte.
resourceInfo!.addRead(1);
resourceInformation.addRead(1);
}
return socket;
}
@ -879,16 +890,12 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject {
int get port {
if (localPort != 0) return localPort;
if (isClosing || isClosed) throw const SocketException.closed();
var result = nativeGetPort();
if (result is OSError) throw result;
return localPort = result;
return localPort = nativeGetPort();
}
int get remotePort {
if (isClosing || isClosed) throw const SocketException.closed();
var result = nativeGetRemotePeer();
if (result is OSError) throw result;
return result[1];
return nativeGetRemotePeer()[1];
}
InternetAddress get address => localAddress;
@ -896,7 +903,6 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject {
InternetAddress get remoteAddress {
if (isClosing || isClosed) throw const SocketException.closed();
var result = nativeGetRemotePeer();
if (result is OSError) throw result;
var addr = result[0];
var type = new InternetAddressType._from(addr[0]);
return new _InternetAddress(addr[1], null, addr[2]);
@ -987,11 +993,13 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject {
if (i == destroyedEvent) {
assert(isClosing);
assert(!isClosed);
// TODO(ricow): Remove/update when we track internal and pipe uses.
assert(
resourceInfo != null || isPipe || isInternal || isInternalSignal);
if (resourceInfo != null) {
_SocketResourceInfo.SocketClosed(resourceInfo!);
final resourceInformation = resourceInfo;
assert(resourceInformation != null ||
isPipe ||
isInternal ||
isInternalSignal);
if (resourceInformation != null) {
_SocketResourceInfo.SocketClosed(resourceInformation!);
}
isClosed = true;
closeCompleter.complete();
@ -1180,8 +1188,7 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject {
bool setOption(SocketOption option, value) {
// TODO: Remove once non-nullability is sound.
ArgumentError.checkNotNull(option, "option");
var result = nativeSetOption(option._value, address.type._value, value);
if (result != null) throw result;
nativeSetOption(option._value, address.type._value, value);
return true;
}
@ -1189,8 +1196,7 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject {
// TODO: Remove once non-nullability is sound.
ArgumentError.checkNotNull(option, "option");
ArgumentError.checkNotNull(option.value, "option.value");
var result = nativeGetRawOption(option.level, option.option, option.value);
if (result != null) throw result;
nativeGetRawOption(option.level, option.option, option.value);
return option.value;
}
@ -1198,8 +1204,7 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject {
// TODO: Remove once non-nullability is sound.
ArgumentError.checkNotNull(option, "option");
ArgumentError.checkNotNull(option.value, "option.value");
var result = nativeSetRawOption(option.level, option.option, option.value);
if (result != null) throw result;
nativeSetRawOption(option.level, option.option, option.value);
}
InternetAddress? multicastAddress(
@ -1230,27 +1235,25 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject {
final interfaceAddr =
multicastAddress(addr, interface) as _InternetAddress?;
var interfaceIndex = interface == null ? 0 : interface.index;
var result = nativeJoinMulticast((addr as _InternetAddress)._in_addr,
nativeJoinMulticast((addr as _InternetAddress)._in_addr,
interfaceAddr?._in_addr, interfaceIndex);
if (result is OSError) throw result;
}
void leaveMulticast(InternetAddress addr, NetworkInterface? interface) {
final interfaceAddr =
multicastAddress(addr, interface) as _InternetAddress?;
var interfaceIndex = interface == null ? 0 : interface.index;
var result = nativeLeaveMulticast((addr as _InternetAddress)._in_addr,
nativeLeaveMulticast((addr as _InternetAddress)._in_addr,
interfaceAddr?._in_addr, interfaceIndex);
if (result is OSError) throw result;
}
void nativeSetSocketId(int id, int typeFlags) native "Socket_SetSocketId";
nativeAvailable() native "Socket_Available";
nativeRead(int len) native "Socket_Read";
nativeRecvFrom() native "Socket_RecvFrom";
nativeWrite(List<int> buffer, int offset, int bytes)
int nativeAvailable() native "Socket_Available";
Uint8List? nativeRead(int len) native "Socket_Read";
Datagram? nativeRecvFrom() native "Socket_RecvFrom";
int nativeWrite(List<int> buffer, int offset, int bytes)
native "Socket_WriteList";
nativeSendTo(List<int> buffer, int offset, int bytes, Uint8List address,
int nativeSendTo(List<int> buffer, int offset, int bytes, Uint8List address,
int port) native "Socket_SendTo";
nativeCreateConnect(Uint8List addr, int port, int scope_id)
native "Socket_CreateConnect";
@ -1261,21 +1264,21 @@ class _NativeSocket extends _NativeSocketNativeWrapper with _ServiceObject {
bool shared, int scope_id) native "ServerSocket_CreateBindListen";
nativeCreateBindDatagram(Uint8List addr, int port, bool reuseAddress,
bool reusePort, int ttl) native "Socket_CreateBindDatagram";
nativeAccept(_NativeSocket socket) native "ServerSocket_Accept";
bool nativeAccept(_NativeSocket socket) native "ServerSocket_Accept";
int nativeGetPort() native "Socket_GetPort";
List nativeGetRemotePeer() native "Socket_GetRemotePeer";
int nativeGetSocketId() native "Socket_GetSocketId";
OSError nativeGetError() native "Socket_GetError";
nativeGetOption(int option, int protocol) native "Socket_GetOption";
OSError nativeGetRawOption(int level, int option, Uint8List data)
void nativeGetRawOption(int level, int option, Uint8List data)
native "Socket_GetRawOption";
OSError nativeSetOption(int option, int protocol, value)
void nativeSetOption(int option, int protocol, value)
native "Socket_SetOption";
OSError nativeSetRawOption(int level, int option, Uint8List data)
void nativeSetRawOption(int level, int option, Uint8List data)
native "Socket_SetRawOption";
OSError nativeJoinMulticast(Uint8List addr, Uint8List? interfaceAddr,
void nativeJoinMulticast(Uint8List addr, Uint8List? interfaceAddr,
int interfaceIndex) native "Socket_JoinMulticast";
bool nativeLeaveMulticast(Uint8List addr, Uint8List? interfaceAddr,
void nativeLeaveMulticast(Uint8List addr, Uint8List? interfaceAddr,
int interfaceIndex) native "Socket_LeaveMulticast";
}

View file

@ -161,5 +161,6 @@ class Stdout {
static _getAnsiSupported(int fd) native "Stdout_AnsiSupported";
}
_getStdioHandle(_NativeSocket socket, int num) native "Socket_GetStdioHandle";
bool _getStdioHandle(_NativeSocket socket, int num)
native "Socket_GetStdioHandle";
_getSocketType(_NativeSocket nativeSocket) native "Socket_GetType";