mirror of
https://github.com/dart-lang/sdk
synced 2024-09-18 21:41:19 +00:00
[dart:io][windows] Implements RawSynchronousSocket
related #29343 fixes #29333 R=asiva@google.com Review-Url: https://codereview.chromium.org/2830273002 .
This commit is contained in:
parent
c21653c0c4
commit
bdb4eb6338
|
@ -157,7 +157,6 @@ class OverlappedBuffer {
|
|||
DISALLOW_COPY_AND_ASSIGN(OverlappedBuffer);
|
||||
};
|
||||
|
||||
|
||||
// Abstract super class for holding information on listen and connected
|
||||
// sockets.
|
||||
class Handle : public ReferenceCounted<Handle>, public DescriptorInfoBase {
|
||||
|
|
|
@ -110,7 +110,8 @@ Dart_Handle FileSystemWatcher::ReadEvents(intptr_t id, intptr_t path_id) {
|
|||
const intptr_t kEventSize = sizeof(struct inotify_event);
|
||||
const intptr_t kBufferSize = kEventSize + NAME_MAX + 1;
|
||||
uint8_t buffer[kBufferSize];
|
||||
intptr_t bytes = SocketBase::Read(id, buffer, kBufferSize);
|
||||
intptr_t bytes =
|
||||
SocketBase::Read(id, buffer, kBufferSize, SocketBase::kAsync);
|
||||
if (bytes < 0) {
|
||||
return DartUtils::NewDartOSError();
|
||||
}
|
||||
|
|
|
@ -978,7 +978,7 @@ BOOL WINAPI SignalHandler(DWORD signal) {
|
|||
while (handler != NULL) {
|
||||
if (handler->signal() == signal) {
|
||||
int value = 0;
|
||||
SocketBase::Write(handler->fd(), &value, 1);
|
||||
SocketBase::Write(handler->fd(), &value, 1, SocketBase::kAsync);
|
||||
handled = true;
|
||||
}
|
||||
handler = handler->next();
|
||||
|
|
|
@ -353,7 +353,8 @@ void FUNCTION_NAME(Socket_Read)(Dart_NativeArguments args) {
|
|||
Dart_PropagateError(result);
|
||||
}
|
||||
ASSERT(buffer != NULL);
|
||||
intptr_t bytes_read = SocketBase::Read(socket->fd(), buffer, length);
|
||||
intptr_t bytes_read =
|
||||
SocketBase::Read(socket->fd(), buffer, length, SocketBase::kAsync);
|
||||
if (bytes_read == length) {
|
||||
Dart_SetReturnValue(args, result);
|
||||
} else if (bytes_read > 0) {
|
||||
|
@ -393,8 +394,9 @@ void FUNCTION_NAME(Socket_RecvFrom)(Dart_NativeArguments args) {
|
|||
reinterpret_cast<uint8_t*>(malloc(65536));
|
||||
}
|
||||
RawAddr addr;
|
||||
intptr_t bytes_read = SocketBase::RecvFrom(
|
||||
socket->fd(), isolate_data->udp_receive_buffer, 65536, &addr);
|
||||
intptr_t bytes_read =
|
||||
SocketBase::RecvFrom(socket->fd(), isolate_data->udp_receive_buffer,
|
||||
65536, &addr, SocketBase::kAsync);
|
||||
if (bytes_read == 0) {
|
||||
Dart_SetReturnValue(args, Dart_Null());
|
||||
return;
|
||||
|
@ -474,7 +476,8 @@ void FUNCTION_NAME(Socket_WriteList)(Dart_NativeArguments args) {
|
|||
}
|
||||
ASSERT((offset + length) <= len);
|
||||
buffer += offset;
|
||||
intptr_t bytes_written = SocketBase::Write(socket->fd(), buffer, length);
|
||||
intptr_t bytes_written =
|
||||
SocketBase::Write(socket->fd(), buffer, length, SocketBase::kAsync);
|
||||
if (bytes_written >= 0) {
|
||||
Dart_TypedDataReleaseData(buffer_obj);
|
||||
if (short_write) {
|
||||
|
@ -516,8 +519,8 @@ void FUNCTION_NAME(Socket_SendTo)(Dart_NativeArguments args) {
|
|||
}
|
||||
ASSERT((offset + length) <= len);
|
||||
buffer += offset;
|
||||
intptr_t bytes_written =
|
||||
SocketBase::SendTo(socket->fd(), buffer, length, addr);
|
||||
intptr_t bytes_written = SocketBase::SendTo(socket->fd(), buffer, length,
|
||||
addr, SocketBase::kAsync);
|
||||
if (bytes_written >= 0) {
|
||||
Dart_TypedDataReleaseData(buffer_obj);
|
||||
Dart_SetReturnValue(args, Dart_NewInteger(bytes_written));
|
||||
|
|
|
@ -21,6 +21,139 @@
|
|||
namespace dart {
|
||||
namespace bin {
|
||||
|
||||
int SocketAddress::GetType() {
|
||||
if (addr_.ss.ss_family == AF_INET6) {
|
||||
return TYPE_IPV6;
|
||||
}
|
||||
return TYPE_IPV4;
|
||||
}
|
||||
|
||||
|
||||
intptr_t SocketAddress::GetAddrLength(const RawAddr& addr) {
|
||||
ASSERT((addr.ss.ss_family == AF_INET) || (addr.ss.ss_family == AF_INET6));
|
||||
return (addr.ss.ss_family == AF_INET6) ? sizeof(struct sockaddr_in6)
|
||||
: sizeof(struct sockaddr_in);
|
||||
}
|
||||
|
||||
|
||||
intptr_t SocketAddress::GetInAddrLength(const RawAddr& addr) {
|
||||
ASSERT((addr.ss.ss_family == AF_INET) || (addr.ss.ss_family == AF_INET6));
|
||||
return (addr.ss.ss_family == AF_INET6) ? sizeof(struct in6_addr)
|
||||
: sizeof(struct in_addr);
|
||||
}
|
||||
|
||||
|
||||
bool SocketAddress::AreAddressesEqual(const RawAddr& a, const RawAddr& b) {
|
||||
if (a.ss.ss_family == AF_INET) {
|
||||
if (b.ss.ss_family != AF_INET) {
|
||||
return false;
|
||||
}
|
||||
return memcmp(&a.in.sin_addr, &b.in.sin_addr, sizeof(a.in.sin_addr)) == 0;
|
||||
} else if (a.ss.ss_family == AF_INET6) {
|
||||
if (b.ss.ss_family != AF_INET6) {
|
||||
return false;
|
||||
}
|
||||
return memcmp(&a.in6.sin6_addr, &b.in6.sin6_addr,
|
||||
sizeof(a.in6.sin6_addr)) == 0;
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SocketAddress::GetSockAddr(Dart_Handle obj, RawAddr* addr) {
|
||||
Dart_TypedData_Type data_type;
|
||||
uint8_t* data = NULL;
|
||||
intptr_t len;
|
||||
Dart_Handle result = Dart_TypedDataAcquireData(
|
||||
obj, &data_type, reinterpret_cast<void**>(&data), &len);
|
||||
if (Dart_IsError(result)) {
|
||||
Dart_PropagateError(result);
|
||||
}
|
||||
if ((data_type != Dart_TypedData_kUint8) ||
|
||||
((len != sizeof(in_addr)) && (len != sizeof(in6_addr)))) {
|
||||
Dart_PropagateError(Dart_NewApiError("Unexpected type for socket address"));
|
||||
}
|
||||
memset(reinterpret_cast<void*>(addr), 0, sizeof(RawAddr));
|
||||
if (len == sizeof(in_addr)) {
|
||||
addr->in.sin_family = AF_INET;
|
||||
memmove(reinterpret_cast<void*>(&addr->in.sin_addr), data, len);
|
||||
} else {
|
||||
ASSERT(len == sizeof(in6_addr));
|
||||
addr->in6.sin6_family = AF_INET6;
|
||||
memmove(reinterpret_cast<void*>(&addr->in6.sin6_addr), data, len);
|
||||
}
|
||||
Dart_TypedDataReleaseData(obj);
|
||||
}
|
||||
|
||||
|
||||
int16_t SocketAddress::FromType(int type) {
|
||||
if (type == TYPE_ANY) {
|
||||
return AF_UNSPEC;
|
||||
}
|
||||
if (type == TYPE_IPV4) {
|
||||
return AF_INET;
|
||||
}
|
||||
ASSERT((type == TYPE_IPV6) && "Invalid type");
|
||||
return AF_INET6;
|
||||
}
|
||||
|
||||
|
||||
void SocketAddress::SetAddrPort(RawAddr* addr, intptr_t port) {
|
||||
if (addr->ss.ss_family == AF_INET) {
|
||||
addr->in.sin_port = htons(port);
|
||||
} else {
|
||||
addr->in6.sin6_port = htons(port);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
intptr_t SocketAddress::GetAddrPort(const RawAddr& addr) {
|
||||
if (addr.ss.ss_family == AF_INET) {
|
||||
return ntohs(addr.in.sin_port);
|
||||
} else {
|
||||
return ntohs(addr.in6.sin6_port);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Dart_Handle SocketAddress::ToTypedData(const RawAddr& addr) {
|
||||
int len = GetInAddrLength(addr);
|
||||
Dart_Handle result = Dart_NewTypedData(Dart_TypedData_kUint8, len);
|
||||
if (Dart_IsError(result)) {
|
||||
Dart_PropagateError(result);
|
||||
}
|
||||
Dart_Handle err;
|
||||
if (addr.addr.sa_family == AF_INET6) {
|
||||
err = Dart_ListSetAsBytes(
|
||||
result, 0, reinterpret_cast<const uint8_t*>(&addr.in6.sin6_addr), len);
|
||||
} else {
|
||||
err = Dart_ListSetAsBytes(
|
||||
result, 0, reinterpret_cast<const uint8_t*>(&addr.in.sin_addr), len);
|
||||
}
|
||||
if (Dart_IsError(err)) {
|
||||
Dart_PropagateError(err);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
CObjectUint8Array* SocketAddress::ToCObject(const RawAddr& addr) {
|
||||
int in_addr_len = SocketAddress::GetInAddrLength(addr);
|
||||
const void* in_addr;
|
||||
CObjectUint8Array* data =
|
||||
new CObjectUint8Array(CObject::NewUint8Array(in_addr_len));
|
||||
if (addr.addr.sa_family == AF_INET6) {
|
||||
in_addr = reinterpret_cast<const void*>(&addr.in6.sin6_addr);
|
||||
} else {
|
||||
in_addr = reinterpret_cast<const void*>(&addr.in.sin_addr);
|
||||
}
|
||||
memmove(data->Buffer(), in_addr, in_addr_len);
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
void FUNCTION_NAME(InternetAddress_Parse)(Dart_NativeArguments args) {
|
||||
const char* address =
|
||||
DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0));
|
||||
|
|
|
@ -63,133 +63,20 @@ class SocketAddress {
|
|||
|
||||
~SocketAddress() {}
|
||||
|
||||
int GetType() {
|
||||
if (addr_.ss.ss_family == AF_INET6) {
|
||||
return TYPE_IPV6;
|
||||
}
|
||||
return TYPE_IPV4;
|
||||
}
|
||||
int GetType();
|
||||
|
||||
const char* as_string() const { return as_string_; }
|
||||
const RawAddr& addr() const { return addr_; }
|
||||
|
||||
static intptr_t GetAddrLength(const RawAddr& addr) {
|
||||
ASSERT((addr.ss.ss_family == AF_INET) || (addr.ss.ss_family == AF_INET6));
|
||||
return (addr.ss.ss_family == AF_INET6) ? sizeof(struct sockaddr_in6)
|
||||
: sizeof(struct sockaddr_in);
|
||||
}
|
||||
|
||||
static intptr_t GetInAddrLength(const RawAddr& addr) {
|
||||
ASSERT((addr.ss.ss_family == AF_INET) || (addr.ss.ss_family == AF_INET6));
|
||||
return (addr.ss.ss_family == AF_INET6) ? sizeof(struct in6_addr)
|
||||
: sizeof(struct in_addr);
|
||||
}
|
||||
|
||||
static bool AreAddressesEqual(const RawAddr& a, const RawAddr& b) {
|
||||
if (a.ss.ss_family == AF_INET) {
|
||||
if (b.ss.ss_family != AF_INET) {
|
||||
return false;
|
||||
}
|
||||
return memcmp(&a.in.sin_addr, &b.in.sin_addr, sizeof(a.in.sin_addr)) == 0;
|
||||
} else if (a.ss.ss_family == AF_INET6) {
|
||||
if (b.ss.ss_family != AF_INET6) {
|
||||
return false;
|
||||
}
|
||||
return memcmp(&a.in6.sin6_addr, &b.in6.sin6_addr,
|
||||
sizeof(a.in6.sin6_addr)) == 0;
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static void GetSockAddr(Dart_Handle obj, RawAddr* addr) {
|
||||
Dart_TypedData_Type data_type;
|
||||
uint8_t* data = NULL;
|
||||
intptr_t len;
|
||||
Dart_Handle result = Dart_TypedDataAcquireData(
|
||||
obj, &data_type, reinterpret_cast<void**>(&data), &len);
|
||||
if (Dart_IsError(result)) {
|
||||
Dart_PropagateError(result);
|
||||
}
|
||||
if ((data_type != Dart_TypedData_kUint8) ||
|
||||
((len != sizeof(in_addr)) && (len != sizeof(in6_addr)))) {
|
||||
Dart_PropagateError(
|
||||
Dart_NewApiError("Unexpected type for socket address"));
|
||||
}
|
||||
memset(reinterpret_cast<void*>(addr), 0, sizeof(RawAddr));
|
||||
if (len == sizeof(in_addr)) {
|
||||
addr->in.sin_family = AF_INET;
|
||||
memmove(reinterpret_cast<void*>(&addr->in.sin_addr), data, len);
|
||||
} else {
|
||||
ASSERT(len == sizeof(in6_addr));
|
||||
addr->in6.sin6_family = AF_INET6;
|
||||
memmove(reinterpret_cast<void*>(&addr->in6.sin6_addr), data, len);
|
||||
}
|
||||
Dart_TypedDataReleaseData(obj);
|
||||
}
|
||||
|
||||
static int16_t FromType(int type) {
|
||||
if (type == TYPE_ANY) {
|
||||
return AF_UNSPEC;
|
||||
}
|
||||
if (type == TYPE_IPV4) {
|
||||
return AF_INET;
|
||||
}
|
||||
ASSERT((type == TYPE_IPV6) && "Invalid type");
|
||||
return AF_INET6;
|
||||
}
|
||||
|
||||
static void SetAddrPort(RawAddr* addr, intptr_t port) {
|
||||
if (addr->ss.ss_family == AF_INET) {
|
||||
addr->in.sin_port = htons(port);
|
||||
} else {
|
||||
addr->in6.sin6_port = htons(port);
|
||||
}
|
||||
}
|
||||
|
||||
static intptr_t GetAddrPort(const RawAddr& addr) {
|
||||
if (addr.ss.ss_family == AF_INET) {
|
||||
return ntohs(addr.in.sin_port);
|
||||
} else {
|
||||
return ntohs(addr.in6.sin6_port);
|
||||
}
|
||||
}
|
||||
|
||||
static Dart_Handle ToTypedData(const RawAddr& addr) {
|
||||
int len = GetInAddrLength(addr);
|
||||
Dart_Handle result = Dart_NewTypedData(Dart_TypedData_kUint8, len);
|
||||
if (Dart_IsError(result)) {
|
||||
Dart_PropagateError(result);
|
||||
}
|
||||
Dart_Handle err;
|
||||
if (addr.addr.sa_family == AF_INET6) {
|
||||
err = Dart_ListSetAsBytes(
|
||||
result, 0, reinterpret_cast<const uint8_t*>(&addr.in6.sin6_addr),
|
||||
len);
|
||||
} else {
|
||||
err = Dart_ListSetAsBytes(
|
||||
result, 0, reinterpret_cast<const uint8_t*>(&addr.in.sin_addr), len);
|
||||
}
|
||||
if (Dart_IsError(err)) {
|
||||
Dart_PropagateError(err);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static CObjectUint8Array* ToCObject(const RawAddr& addr) {
|
||||
int in_addr_len = SocketAddress::GetInAddrLength(addr);
|
||||
const void* in_addr;
|
||||
CObjectUint8Array* data =
|
||||
new CObjectUint8Array(CObject::NewUint8Array(in_addr_len));
|
||||
if (addr.addr.sa_family == AF_INET6) {
|
||||
in_addr = reinterpret_cast<const void*>(&addr.in6.sin6_addr);
|
||||
} else {
|
||||
in_addr = reinterpret_cast<const void*>(&addr.in.sin_addr);
|
||||
}
|
||||
memmove(data->Buffer(), in_addr, in_addr_len);
|
||||
return data;
|
||||
}
|
||||
static intptr_t GetAddrLength(const RawAddr& addr);
|
||||
static intptr_t GetInAddrLength(const RawAddr& addr);
|
||||
static bool AreAddressesEqual(const RawAddr& a, const RawAddr& b);
|
||||
static void GetSockAddr(Dart_Handle obj, RawAddr* addr);
|
||||
static int16_t FromType(int type);
|
||||
static void SetAddrPort(RawAddr* addr, intptr_t port);
|
||||
static intptr_t GetAddrPort(const RawAddr& addr);
|
||||
static Dart_Handle ToTypedData(const RawAddr& addr);
|
||||
static CObjectUint8Array* ToCObject(const RawAddr& addr);
|
||||
|
||||
private:
|
||||
char as_string_[INET6_ADDRSTRLEN];
|
||||
|
@ -198,7 +85,6 @@ class SocketAddress {
|
|||
DISALLOW_COPY_AND_ASSIGN(SocketAddress);
|
||||
};
|
||||
|
||||
|
||||
class InterfaceSocketAddress {
|
||||
public:
|
||||
InterfaceSocketAddress(struct sockaddr* sa,
|
||||
|
@ -222,7 +108,6 @@ class InterfaceSocketAddress {
|
|||
DISALLOW_COPY_AND_ASSIGN(InterfaceSocketAddress);
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
class AddressList {
|
||||
public:
|
||||
|
@ -255,22 +140,35 @@ class SocketBase : public AllStatic {
|
|||
kReverseLookupRequest = 2,
|
||||
};
|
||||
|
||||
enum SocketOpKind {
|
||||
kSync,
|
||||
kAsync,
|
||||
};
|
||||
|
||||
// TODO(dart:io): Convert these to instance methods where possible.
|
||||
static bool Initialize();
|
||||
static intptr_t Available(intptr_t fd);
|
||||
static intptr_t Read(intptr_t fd, void* buffer, intptr_t num_bytes);
|
||||
static intptr_t Write(intptr_t fd, const void* buffer, intptr_t num_bytes);
|
||||
static intptr_t Read(intptr_t fd,
|
||||
void* buffer,
|
||||
intptr_t num_bytes,
|
||||
SocketOpKind sync);
|
||||
static intptr_t Write(intptr_t fd,
|
||||
const void* buffer,
|
||||
intptr_t num_bytes,
|
||||
SocketOpKind sync);
|
||||
// Send data on a socket. The port to send to is specified in the port
|
||||
// component of the passed RawAddr structure. The RawAddr structure is only
|
||||
// used for datagram sockets.
|
||||
static intptr_t SendTo(intptr_t fd,
|
||||
const void* buffer,
|
||||
intptr_t num_bytes,
|
||||
const RawAddr& addr);
|
||||
const RawAddr& addr,
|
||||
SocketOpKind sync);
|
||||
static intptr_t RecvFrom(intptr_t fd,
|
||||
void* buffer,
|
||||
intptr_t num_bytes,
|
||||
RawAddr* addr);
|
||||
RawAddr* addr,
|
||||
SocketOpKind sync);
|
||||
// Returns true if the given error-number is because the system was not able
|
||||
// to bind the socket to a specific IP.
|
||||
static bool IsBindError(intptr_t error_number);
|
||||
|
|
|
@ -62,11 +62,14 @@ intptr_t SocketBase::Available(intptr_t fd) {
|
|||
}
|
||||
|
||||
|
||||
intptr_t SocketBase::Read(intptr_t fd, void* buffer, intptr_t num_bytes) {
|
||||
intptr_t SocketBase::Read(intptr_t fd,
|
||||
void* buffer,
|
||||
intptr_t num_bytes,
|
||||
SocketOpKind sync) {
|
||||
ASSERT(fd >= 0);
|
||||
ssize_t read_bytes = TEMP_FAILURE_RETRY(read(fd, buffer, num_bytes));
|
||||
ASSERT(EAGAIN == EWOULDBLOCK);
|
||||
if ((read_bytes == -1) && (errno == EWOULDBLOCK)) {
|
||||
if ((sync == kAsync) && (read_bytes == -1) && (errno == EWOULDBLOCK)) {
|
||||
// If the read would block we need to retry and therefore return 0
|
||||
// as the number of bytes written.
|
||||
read_bytes = 0;
|
||||
|
@ -78,12 +81,13 @@ intptr_t SocketBase::Read(intptr_t fd, void* buffer, intptr_t num_bytes) {
|
|||
intptr_t SocketBase::RecvFrom(intptr_t fd,
|
||||
void* buffer,
|
||||
intptr_t num_bytes,
|
||||
RawAddr* addr) {
|
||||
RawAddr* addr,
|
||||
SocketOpKind sync) {
|
||||
ASSERT(fd >= 0);
|
||||
socklen_t addr_len = sizeof(addr->ss);
|
||||
ssize_t read_bytes = TEMP_FAILURE_RETRY(
|
||||
recvfrom(fd, buffer, num_bytes, 0, &addr->addr, &addr_len));
|
||||
if ((read_bytes == -1) && (errno == EWOULDBLOCK)) {
|
||||
if ((sync == kAsync) && (read_bytes == -1) && (errno == EWOULDBLOCK)) {
|
||||
// If the read would block we need to retry and therefore return 0
|
||||
// as the number of bytes written.
|
||||
read_bytes = 0;
|
||||
|
@ -94,11 +98,12 @@ intptr_t SocketBase::RecvFrom(intptr_t fd,
|
|||
|
||||
intptr_t SocketBase::Write(intptr_t fd,
|
||||
const void* buffer,
|
||||
intptr_t num_bytes) {
|
||||
intptr_t num_bytes,
|
||||
SocketOpKind sync) {
|
||||
ASSERT(fd >= 0);
|
||||
ssize_t written_bytes = TEMP_FAILURE_RETRY(write(fd, buffer, num_bytes));
|
||||
ASSERT(EAGAIN == EWOULDBLOCK);
|
||||
if ((written_bytes == -1) && (errno == EWOULDBLOCK)) {
|
||||
if ((sync == kAsync) && (written_bytes == -1) && (errno == EWOULDBLOCK)) {
|
||||
// If the would block we need to retry and therefore return 0 as
|
||||
// the number of bytes written.
|
||||
written_bytes = 0;
|
||||
|
@ -110,13 +115,14 @@ intptr_t SocketBase::Write(intptr_t fd,
|
|||
intptr_t SocketBase::SendTo(intptr_t fd,
|
||||
const void* buffer,
|
||||
intptr_t num_bytes,
|
||||
const RawAddr& addr) {
|
||||
const RawAddr& addr,
|
||||
SocketOpKind sync) {
|
||||
ASSERT(fd >= 0);
|
||||
ssize_t written_bytes =
|
||||
TEMP_FAILURE_RETRY(sendto(fd, buffer, num_bytes, 0, &addr.addr,
|
||||
SocketAddress::GetAddrLength(addr)));
|
||||
ASSERT(EAGAIN == EWOULDBLOCK);
|
||||
if ((written_bytes == -1) && (errno == EWOULDBLOCK)) {
|
||||
if ((sync == kAsync) && (written_bytes == -1) && (errno == EWOULDBLOCK)) {
|
||||
// If the would block we need to retry and therefore return 0 as
|
||||
// the number of bytes written.
|
||||
written_bytes = 0;
|
||||
|
|
|
@ -93,13 +93,16 @@ intptr_t SocketBase::Available(intptr_t fd) {
|
|||
}
|
||||
|
||||
|
||||
intptr_t SocketBase::Read(intptr_t fd, void* buffer, intptr_t num_bytes) {
|
||||
intptr_t SocketBase::Read(intptr_t fd,
|
||||
void* buffer,
|
||||
intptr_t num_bytes,
|
||||
SocketOpKind sync) {
|
||||
ASSERT(fd >= 0);
|
||||
LOG_INFO("SocketBase::Read: calling read(%ld, %p, %ld)\n", fd, buffer,
|
||||
num_bytes);
|
||||
ssize_t read_bytes = NO_RETRY_EXPECTED(read(fd, buffer, num_bytes));
|
||||
ASSERT(EAGAIN == EWOULDBLOCK);
|
||||
if ((read_bytes == -1) && (errno == EWOULDBLOCK)) {
|
||||
if ((sync == kAsync) && (read_bytes == -1) && (errno == EWOULDBLOCK)) {
|
||||
// If the read would block we need to retry and therefore return 0
|
||||
// as the number of bytes written.
|
||||
read_bytes = 0;
|
||||
|
@ -117,7 +120,8 @@ intptr_t SocketBase::Read(intptr_t fd, void* buffer, intptr_t num_bytes) {
|
|||
intptr_t SocketBase::RecvFrom(intptr_t fd,
|
||||
void* buffer,
|
||||
intptr_t num_bytes,
|
||||
RawAddr* addr) {
|
||||
RawAddr* addr,
|
||||
SocketOpKind sync) {
|
||||
LOG_ERR("SocketBase::RecvFrom is unimplemented\n");
|
||||
UNIMPLEMENTED();
|
||||
return -1;
|
||||
|
@ -126,13 +130,14 @@ intptr_t SocketBase::RecvFrom(intptr_t fd,
|
|||
|
||||
intptr_t SocketBase::Write(intptr_t fd,
|
||||
const void* buffer,
|
||||
intptr_t num_bytes) {
|
||||
intptr_t num_bytes,
|
||||
SocketOpKind sync) {
|
||||
ASSERT(fd >= 0);
|
||||
LOG_INFO("SocketBase::Write: calling write(%ld, %p, %ld)\n", fd, buffer,
|
||||
num_bytes);
|
||||
ssize_t written_bytes = NO_RETRY_EXPECTED(write(fd, buffer, num_bytes));
|
||||
ASSERT(EAGAIN == EWOULDBLOCK);
|
||||
if ((written_bytes == -1) && (errno == EWOULDBLOCK)) {
|
||||
if ((sync == kAsync) && (written_bytes == -1) && (errno == EWOULDBLOCK)) {
|
||||
// If the would block we need to retry and therefore return 0 as
|
||||
// the number of bytes written.
|
||||
written_bytes = 0;
|
||||
|
@ -150,7 +155,8 @@ intptr_t SocketBase::Write(intptr_t fd,
|
|||
intptr_t SocketBase::SendTo(intptr_t fd,
|
||||
const void* buffer,
|
||||
intptr_t num_bytes,
|
||||
const RawAddr& addr) {
|
||||
const RawAddr& addr,
|
||||
SocketOpKind sync) {
|
||||
LOG_ERR("SocketBase::SendTo is unimplemented\n");
|
||||
UNIMPLEMENTED();
|
||||
return -1;
|
||||
|
|
|
@ -65,11 +65,14 @@ intptr_t SocketBase::Available(intptr_t fd) {
|
|||
}
|
||||
|
||||
|
||||
intptr_t SocketBase::Read(intptr_t fd, void* buffer, intptr_t num_bytes) {
|
||||
intptr_t SocketBase::Read(intptr_t fd,
|
||||
void* buffer,
|
||||
intptr_t num_bytes,
|
||||
SocketOpKind sync) {
|
||||
ASSERT(fd >= 0);
|
||||
ssize_t read_bytes = TEMP_FAILURE_RETRY(read(fd, buffer, num_bytes));
|
||||
ASSERT(EAGAIN == EWOULDBLOCK);
|
||||
if ((read_bytes == -1) && (errno == EWOULDBLOCK)) {
|
||||
if ((sync == kAsync) && (read_bytes == -1) && (errno == EWOULDBLOCK)) {
|
||||
// If the read would block we need to retry and therefore return 0
|
||||
// as the number of bytes written.
|
||||
read_bytes = 0;
|
||||
|
@ -81,12 +84,13 @@ intptr_t SocketBase::Read(intptr_t fd, void* buffer, intptr_t num_bytes) {
|
|||
intptr_t SocketBase::RecvFrom(intptr_t fd,
|
||||
void* buffer,
|
||||
intptr_t num_bytes,
|
||||
RawAddr* addr) {
|
||||
RawAddr* addr,
|
||||
SocketOpKind sync) {
|
||||
ASSERT(fd >= 0);
|
||||
socklen_t addr_len = sizeof(addr->ss);
|
||||
ssize_t read_bytes = TEMP_FAILURE_RETRY(
|
||||
recvfrom(fd, buffer, num_bytes, 0, &addr->addr, &addr_len));
|
||||
if ((read_bytes == -1) && (errno == EWOULDBLOCK)) {
|
||||
if ((sync == kAsync) && (read_bytes == -1) && (errno == EWOULDBLOCK)) {
|
||||
// If the read would block we need to retry and therefore return 0
|
||||
// as the number of bytes written.
|
||||
read_bytes = 0;
|
||||
|
@ -97,11 +101,12 @@ intptr_t SocketBase::RecvFrom(intptr_t fd,
|
|||
|
||||
intptr_t SocketBase::Write(intptr_t fd,
|
||||
const void* buffer,
|
||||
intptr_t num_bytes) {
|
||||
intptr_t num_bytes,
|
||||
SocketOpKind sync) {
|
||||
ASSERT(fd >= 0);
|
||||
ssize_t written_bytes = TEMP_FAILURE_RETRY(write(fd, buffer, num_bytes));
|
||||
ASSERT(EAGAIN == EWOULDBLOCK);
|
||||
if ((written_bytes == -1) && (errno == EWOULDBLOCK)) {
|
||||
if ((sync == kAsync) && (written_bytes == -1) && (errno == EWOULDBLOCK)) {
|
||||
// If the would block we need to retry and therefore return 0 as
|
||||
// the number of bytes written.
|
||||
written_bytes = 0;
|
||||
|
@ -113,13 +118,14 @@ intptr_t SocketBase::Write(intptr_t fd,
|
|||
intptr_t SocketBase::SendTo(intptr_t fd,
|
||||
const void* buffer,
|
||||
intptr_t num_bytes,
|
||||
const RawAddr& addr) {
|
||||
const RawAddr& addr,
|
||||
SocketOpKind sync) {
|
||||
ASSERT(fd >= 0);
|
||||
ssize_t written_bytes =
|
||||
TEMP_FAILURE_RETRY(sendto(fd, buffer, num_bytes, 0, &addr.addr,
|
||||
SocketAddress::GetAddrLength(addr)));
|
||||
ASSERT(EAGAIN == EWOULDBLOCK);
|
||||
if ((written_bytes == -1) && (errno == EWOULDBLOCK)) {
|
||||
if ((sync == kAsync) && (written_bytes == -1) && (errno == EWOULDBLOCK)) {
|
||||
// If the would block we need to retry and therefore return 0 as
|
||||
// the number of bytes written.
|
||||
written_bytes = 0;
|
||||
|
|
|
@ -64,11 +64,14 @@ intptr_t SocketBase::Available(intptr_t fd) {
|
|||
}
|
||||
|
||||
|
||||
intptr_t SocketBase::Read(intptr_t fd, void* buffer, intptr_t num_bytes) {
|
||||
intptr_t SocketBase::Read(intptr_t fd,
|
||||
void* buffer,
|
||||
intptr_t num_bytes,
|
||||
SocketOpKind sync) {
|
||||
ASSERT(fd >= 0);
|
||||
ssize_t read_bytes = TEMP_FAILURE_RETRY(read(fd, buffer, num_bytes));
|
||||
ASSERT(EAGAIN == EWOULDBLOCK);
|
||||
if ((read_bytes == -1) && (errno == EWOULDBLOCK)) {
|
||||
if ((sync == kAsync) && (read_bytes == -1) && (errno == EWOULDBLOCK)) {
|
||||
// If the read would block we need to retry and therefore return 0
|
||||
// as the number of bytes written.
|
||||
read_bytes = 0;
|
||||
|
@ -80,12 +83,13 @@ intptr_t SocketBase::Read(intptr_t fd, void* buffer, intptr_t num_bytes) {
|
|||
intptr_t SocketBase::RecvFrom(intptr_t fd,
|
||||
void* buffer,
|
||||
intptr_t num_bytes,
|
||||
RawAddr* addr) {
|
||||
RawAddr* addr,
|
||||
SocketOpKind sync) {
|
||||
ASSERT(fd >= 0);
|
||||
socklen_t addr_len = sizeof(addr->ss);
|
||||
ssize_t read_bytes = TEMP_FAILURE_RETRY(
|
||||
recvfrom(fd, buffer, num_bytes, 0, &addr->addr, &addr_len));
|
||||
if ((read_bytes == -1) && (errno == EWOULDBLOCK)) {
|
||||
if ((sync == kAsync) && (read_bytes == -1) && (errno == EWOULDBLOCK)) {
|
||||
// If the read would block we need to retry and therefore return 0
|
||||
// as the number of bytes written.
|
||||
read_bytes = 0;
|
||||
|
@ -96,11 +100,12 @@ intptr_t SocketBase::RecvFrom(intptr_t fd,
|
|||
|
||||
intptr_t SocketBase::Write(intptr_t fd,
|
||||
const void* buffer,
|
||||
intptr_t num_bytes) {
|
||||
intptr_t num_bytes,
|
||||
SocketOpKind sync) {
|
||||
ASSERT(fd >= 0);
|
||||
ssize_t written_bytes = TEMP_FAILURE_RETRY(write(fd, buffer, num_bytes));
|
||||
ASSERT(EAGAIN == EWOULDBLOCK);
|
||||
if ((written_bytes == -1) && (errno == EWOULDBLOCK)) {
|
||||
if ((sync == kAsync) && (written_bytes == -1) && (errno == EWOULDBLOCK)) {
|
||||
// If the would block we need to retry and therefore return 0 as
|
||||
// the number of bytes written.
|
||||
written_bytes = 0;
|
||||
|
@ -112,13 +117,14 @@ intptr_t SocketBase::Write(intptr_t fd,
|
|||
intptr_t SocketBase::SendTo(intptr_t fd,
|
||||
const void* buffer,
|
||||
intptr_t num_bytes,
|
||||
const RawAddr& addr) {
|
||||
const RawAddr& addr,
|
||||
SocketOpKind sync) {
|
||||
ASSERT(fd >= 0);
|
||||
ssize_t written_bytes =
|
||||
TEMP_FAILURE_RETRY(sendto(fd, buffer, num_bytes, 0, &addr.addr,
|
||||
SocketAddress::GetAddrLength(addr)));
|
||||
ASSERT(EAGAIN == EWOULDBLOCK);
|
||||
if ((written_bytes == -1) && (errno == EWOULDBLOCK)) {
|
||||
if ((sync == kAsync) && (written_bytes == -1) && (errno == EWOULDBLOCK)) {
|
||||
// If the would block we need to retry and therefore return 0 as
|
||||
// the number of bytes written.
|
||||
written_bytes = 0;
|
||||
|
|
|
@ -76,7 +76,10 @@ intptr_t SocketBase::Available(intptr_t fd) {
|
|||
}
|
||||
|
||||
|
||||
intptr_t SocketBase::Read(intptr_t fd, void* buffer, intptr_t num_bytes) {
|
||||
intptr_t SocketBase::Read(intptr_t fd,
|
||||
void* buffer,
|
||||
intptr_t num_bytes,
|
||||
SocketOpKind sync) {
|
||||
Handle* handle = reinterpret_cast<Handle*>(fd);
|
||||
return handle->Read(buffer, num_bytes);
|
||||
}
|
||||
|
@ -85,7 +88,8 @@ intptr_t SocketBase::Read(intptr_t fd, void* buffer, intptr_t num_bytes) {
|
|||
intptr_t SocketBase::RecvFrom(intptr_t fd,
|
||||
void* buffer,
|
||||
intptr_t num_bytes,
|
||||
RawAddr* addr) {
|
||||
RawAddr* addr,
|
||||
SocketOpKind sync) {
|
||||
Handle* handle = reinterpret_cast<Handle*>(fd);
|
||||
socklen_t addr_len = sizeof(addr->ss);
|
||||
return handle->RecvFrom(buffer, num_bytes, &addr->addr, addr_len);
|
||||
|
@ -94,7 +98,8 @@ intptr_t SocketBase::RecvFrom(intptr_t fd,
|
|||
|
||||
intptr_t SocketBase::Write(intptr_t fd,
|
||||
const void* buffer,
|
||||
intptr_t num_bytes) {
|
||||
intptr_t num_bytes,
|
||||
SocketOpKind sync) {
|
||||
Handle* handle = reinterpret_cast<Handle*>(fd);
|
||||
return handle->Write(buffer, num_bytes);
|
||||
}
|
||||
|
@ -103,7 +108,8 @@ intptr_t SocketBase::Write(intptr_t fd,
|
|||
intptr_t SocketBase::SendTo(intptr_t fd,
|
||||
const void* buffer,
|
||||
intptr_t num_bytes,
|
||||
const RawAddr& addr) {
|
||||
const RawAddr& addr,
|
||||
SocketOpKind sync) {
|
||||
Handle* handle = reinterpret_cast<Handle*>(fd);
|
||||
RawAddr& raw = const_cast<RawAddr&>(addr);
|
||||
return handle->SendTo(buffer, num_bytes, &raw.addr,
|
||||
|
|
|
@ -143,7 +143,8 @@ void FUNCTION_NAME(SynchronousSocket_WriteList)(Dart_NativeArguments args) {
|
|||
DART_CHECK_ERROR(result);
|
||||
ASSERT((offset + length) <= len);
|
||||
buffer += offset;
|
||||
intptr_t bytes_written = SocketBase::Write(socket->fd(), buffer, length);
|
||||
intptr_t bytes_written =
|
||||
SynchronousSocket::Write(socket->fd(), buffer, length);
|
||||
if (bytes_written >= 0) {
|
||||
Dart_SetIntegerReturnValue(args, bytes_written);
|
||||
} else {
|
||||
|
@ -174,7 +175,7 @@ void FUNCTION_NAME(SynchronousSocket_ReadList)(Dart_NativeArguments args) {
|
|||
DART_CHECK_ERROR(result);
|
||||
|
||||
uint8_t* buffer = Dart_ScopeAllocate(bytes);
|
||||
intptr_t bytes_read = SocketBase::Read(socket->fd(), buffer, bytes);
|
||||
intptr_t bytes_read = SynchronousSocket::Read(socket->fd(), buffer, bytes);
|
||||
if (bytes_read < 0) {
|
||||
Dart_SetReturnValue(args, DartUtils::NewDartOSError());
|
||||
return;
|
||||
|
@ -193,7 +194,7 @@ void FUNCTION_NAME(SynchronousSocket_Available)(Dart_NativeArguments args) {
|
|||
Dart_GetNativeArgument(args, 0), &socket);
|
||||
DART_CHECK_ERROR(result);
|
||||
|
||||
intptr_t available = SocketBase::Available(socket->fd());
|
||||
intptr_t available = SynchronousSocket::Available(socket->fd());
|
||||
if (available >= 0) {
|
||||
Dart_SetIntegerReturnValue(args, available);
|
||||
} else {
|
||||
|
@ -208,7 +209,7 @@ void FUNCTION_NAME(SynchronousSocket_CloseSync)(Dart_NativeArguments args) {
|
|||
Dart_GetNativeArgument(args, 0), &socket);
|
||||
DART_CHECK_ERROR(result);
|
||||
|
||||
SocketBase::Close(socket->fd());
|
||||
SynchronousSocket::Close(socket->fd());
|
||||
socket->SetClosedFd();
|
||||
}
|
||||
|
||||
|
@ -228,7 +229,7 @@ void FUNCTION_NAME(SynchronousSocket_Read)(Dart_NativeArguments args) {
|
|||
uint8_t* buffer = NULL;
|
||||
result = IOBuffer::Allocate(length, &buffer);
|
||||
ASSERT(buffer != NULL);
|
||||
intptr_t bytes_read = SocketBase::Read(socket->fd(), buffer, length);
|
||||
intptr_t bytes_read = SynchronousSocket::Read(socket->fd(), buffer, length);
|
||||
if (bytes_read == length) {
|
||||
Dart_SetReturnValue(args, result);
|
||||
} else if (bytes_read > 0) {
|
||||
|
@ -269,7 +270,7 @@ void FUNCTION_NAME(SynchronousSocket_GetPort)(Dart_NativeArguments args) {
|
|||
Dart_GetNativeArgument(args, 0), &socket);
|
||||
DART_CHECK_ERROR(result);
|
||||
|
||||
intptr_t port = SocketBase::GetPort(socket->fd());
|
||||
intptr_t port = SynchronousSocket::GetPort(socket->fd());
|
||||
if (port > 0) {
|
||||
Dart_SetReturnValue(args, Dart_NewInteger(port));
|
||||
} else {
|
||||
|
@ -285,7 +286,7 @@ void FUNCTION_NAME(SynchronousSocket_GetRemotePeer)(Dart_NativeArguments args) {
|
|||
DART_CHECK_ERROR(result);
|
||||
|
||||
intptr_t port = 0;
|
||||
SocketAddress* addr = SocketBase::GetRemotePeer(socket->fd(), &port);
|
||||
SocketAddress* addr = SynchronousSocket::GetRemotePeer(socket->fd(), &port);
|
||||
if (addr == NULL) {
|
||||
Dart_SetReturnValue(args, DartUtils::NewDartOSError());
|
||||
return;
|
||||
|
@ -321,7 +322,7 @@ static void SynchronousSocketFinalizer(void* isolate_data,
|
|||
void* data) {
|
||||
SynchronousSocket* socket = reinterpret_cast<SynchronousSocket*>(data);
|
||||
if (socket->fd() >= 0) {
|
||||
SocketBase::Close(socket->fd());
|
||||
SynchronousSocket::Close(socket->fd());
|
||||
socket->SetClosedFd();
|
||||
}
|
||||
delete socket;
|
||||
|
|
|
@ -17,11 +17,11 @@ namespace bin {
|
|||
|
||||
class SynchronousSocket {
|
||||
public:
|
||||
explicit SynchronousSocket(intptr_t fd);
|
||||
explicit SynchronousSocket(intptr_t fd) : fd_(fd) {}
|
||||
~SynchronousSocket() { ASSERT(fd_ == kClosedFd); }
|
||||
|
||||
intptr_t fd() const { return fd_; }
|
||||
void SetClosedFd();
|
||||
void SetClosedFd() { fd_ = kClosedFd; }
|
||||
|
||||
static bool Initialize();
|
||||
|
||||
|
@ -32,8 +32,15 @@ class SynchronousSocket {
|
|||
static Dart_Handle GetSocketIdNativeField(Dart_Handle socket_obj,
|
||||
SynchronousSocket** socket);
|
||||
|
||||
static intptr_t Available(intptr_t fd);
|
||||
static intptr_t GetPort(intptr_t fd);
|
||||
static SocketAddress* GetRemotePeer(intptr_t fd, intptr_t* port);
|
||||
static intptr_t Read(intptr_t fd, void* buffer, intptr_t num_bytes);
|
||||
static intptr_t Write(intptr_t fd, const void* buffer, intptr_t num_bytes);
|
||||
|
||||
static void ShutdownRead(intptr_t fd);
|
||||
static void ShutdownWrite(intptr_t fd);
|
||||
static void Close(intptr_t fd);
|
||||
|
||||
private:
|
||||
static const int kClosedFd = -1;
|
||||
|
|
|
@ -12,19 +12,12 @@
|
|||
#include <errno.h> // NOLINT
|
||||
|
||||
#include "bin/fdutils.h"
|
||||
#include "bin/socket_base.h"
|
||||
#include "platform/signal_blocker.h"
|
||||
|
||||
namespace dart {
|
||||
namespace bin {
|
||||
|
||||
SynchronousSocket::SynchronousSocket(intptr_t fd) : fd_(fd) {}
|
||||
|
||||
|
||||
void SynchronousSocket::SetClosedFd() {
|
||||
fd_ = kClosedFd;
|
||||
}
|
||||
|
||||
|
||||
bool SynchronousSocket::Initialize() {
|
||||
// Nothing to do on Android.
|
||||
return true;
|
||||
|
@ -63,6 +56,35 @@ intptr_t SynchronousSocket::CreateConnect(const RawAddr& addr) {
|
|||
}
|
||||
|
||||
|
||||
intptr_t SynchronousSocket::Available(intptr_t fd) {
|
||||
return SocketBase::Available(fd);
|
||||
}
|
||||
|
||||
|
||||
intptr_t SynchronousSocket::GetPort(intptr_t fd) {
|
||||
return SocketBase::GetPort(fd);
|
||||
}
|
||||
|
||||
|
||||
SocketAddress* SynchronousSocket::GetRemotePeer(intptr_t fd, intptr_t* port) {
|
||||
return SocketBase::GetRemotePeer(fd, port);
|
||||
}
|
||||
|
||||
|
||||
intptr_t SynchronousSocket::Read(intptr_t fd,
|
||||
void* buffer,
|
||||
intptr_t num_bytes) {
|
||||
return SocketBase::Read(fd, buffer, num_bytes, SocketBase::kSync);
|
||||
}
|
||||
|
||||
|
||||
intptr_t SynchronousSocket::Write(intptr_t fd,
|
||||
const void* buffer,
|
||||
intptr_t num_bytes) {
|
||||
return SocketBase::Write(fd, buffer, num_bytes, SocketBase::kSync);
|
||||
}
|
||||
|
||||
|
||||
void SynchronousSocket::ShutdownRead(intptr_t fd) {
|
||||
VOID_NO_RETRY_EXPECTED(shutdown(fd, SHUT_RD));
|
||||
}
|
||||
|
@ -72,6 +94,11 @@ void SynchronousSocket::ShutdownWrite(intptr_t fd) {
|
|||
VOID_NO_RETRY_EXPECTED(shutdown(fd, SHUT_WR));
|
||||
}
|
||||
|
||||
|
||||
void SynchronousSocket::Close(intptr_t fd) {
|
||||
return SocketBase::Close(fd);
|
||||
}
|
||||
|
||||
} // namespace bin
|
||||
} // namespace dart
|
||||
|
||||
|
|
|
@ -12,19 +12,12 @@
|
|||
#include <errno.h> // NOLINT
|
||||
|
||||
#include "bin/fdutils.h"
|
||||
#include "bin/socket_base.h"
|
||||
#include "platform/signal_blocker.h"
|
||||
|
||||
namespace dart {
|
||||
namespace bin {
|
||||
|
||||
SynchronousSocket::SynchronousSocket(intptr_t fd) : fd_(fd) {}
|
||||
|
||||
|
||||
void SynchronousSocket::SetClosedFd() {
|
||||
fd_ = kClosedFd;
|
||||
}
|
||||
|
||||
|
||||
bool SynchronousSocket::Initialize() {
|
||||
// Nothing to do on Fuchsia.
|
||||
return true;
|
||||
|
@ -63,6 +56,35 @@ intptr_t SynchronousSocket::CreateConnect(const RawAddr& addr) {
|
|||
}
|
||||
|
||||
|
||||
intptr_t SynchronousSocket::Available(intptr_t fd) {
|
||||
return SocketBase::Available(fd);
|
||||
}
|
||||
|
||||
|
||||
intptr_t SynchronousSocket::GetPort(intptr_t fd) {
|
||||
return SocketBase::GetPort(fd);
|
||||
}
|
||||
|
||||
|
||||
SocketAddress* SynchronousSocket::GetRemotePeer(intptr_t fd, intptr_t* port) {
|
||||
return SocketBase::GetRemotePeer(fd, port);
|
||||
}
|
||||
|
||||
|
||||
intptr_t SynchronousSocket::Read(intptr_t fd,
|
||||
void* buffer,
|
||||
intptr_t num_bytes) {
|
||||
return SocketBase::Read(fd, buffer, num_bytes, SocketBase::kSync);
|
||||
}
|
||||
|
||||
|
||||
intptr_t SynchronousSocket::Write(intptr_t fd,
|
||||
const void* buffer,
|
||||
intptr_t num_bytes) {
|
||||
return SocketBase::Write(fd, buffer, num_bytes, SocketBase::kSync);
|
||||
}
|
||||
|
||||
|
||||
void SynchronousSocket::ShutdownRead(intptr_t fd) {
|
||||
VOID_NO_RETRY_EXPECTED(shutdown(fd, SHUT_RD));
|
||||
}
|
||||
|
@ -72,6 +94,11 @@ void SynchronousSocket::ShutdownWrite(intptr_t fd) {
|
|||
VOID_NO_RETRY_EXPECTED(shutdown(fd, SHUT_WR));
|
||||
}
|
||||
|
||||
|
||||
void SynchronousSocket::Close(intptr_t fd) {
|
||||
return SocketBase::Close(fd);
|
||||
}
|
||||
|
||||
} // namespace bin
|
||||
} // namespace dart
|
||||
|
||||
|
|
|
@ -12,19 +12,12 @@
|
|||
#include <errno.h> // NOLINT
|
||||
|
||||
#include "bin/fdutils.h"
|
||||
#include "bin/socket_base.h"
|
||||
#include "platform/signal_blocker.h"
|
||||
|
||||
namespace dart {
|
||||
namespace bin {
|
||||
|
||||
SynchronousSocket::SynchronousSocket(intptr_t fd) : fd_(fd) {}
|
||||
|
||||
|
||||
void SynchronousSocket::SetClosedFd() {
|
||||
fd_ = kClosedFd;
|
||||
}
|
||||
|
||||
|
||||
bool SynchronousSocket::Initialize() {
|
||||
// Nothing to do on Linux.
|
||||
return true;
|
||||
|
@ -63,6 +56,35 @@ intptr_t SynchronousSocket::CreateConnect(const RawAddr& addr) {
|
|||
}
|
||||
|
||||
|
||||
intptr_t SynchronousSocket::Available(intptr_t fd) {
|
||||
return SocketBase::Available(fd);
|
||||
}
|
||||
|
||||
|
||||
intptr_t SynchronousSocket::GetPort(intptr_t fd) {
|
||||
return SocketBase::GetPort(fd);
|
||||
}
|
||||
|
||||
|
||||
SocketAddress* SynchronousSocket::GetRemotePeer(intptr_t fd, intptr_t* port) {
|
||||
return SocketBase::GetRemotePeer(fd, port);
|
||||
}
|
||||
|
||||
|
||||
intptr_t SynchronousSocket::Read(intptr_t fd,
|
||||
void* buffer,
|
||||
intptr_t num_bytes) {
|
||||
return SocketBase::Read(fd, buffer, num_bytes, SocketBase::kSync);
|
||||
}
|
||||
|
||||
|
||||
intptr_t SynchronousSocket::Write(intptr_t fd,
|
||||
const void* buffer,
|
||||
intptr_t num_bytes) {
|
||||
return SocketBase::Write(fd, buffer, num_bytes, SocketBase::kSync);
|
||||
}
|
||||
|
||||
|
||||
void SynchronousSocket::ShutdownRead(intptr_t fd) {
|
||||
VOID_NO_RETRY_EXPECTED(shutdown(fd, SHUT_RD));
|
||||
}
|
||||
|
@ -72,6 +94,11 @@ void SynchronousSocket::ShutdownWrite(intptr_t fd) {
|
|||
VOID_NO_RETRY_EXPECTED(shutdown(fd, SHUT_WR));
|
||||
}
|
||||
|
||||
|
||||
void SynchronousSocket::Close(intptr_t fd) {
|
||||
return SocketBase::Close(fd);
|
||||
}
|
||||
|
||||
} // namespace bin
|
||||
} // namespace dart
|
||||
|
||||
|
|
|
@ -12,16 +12,15 @@
|
|||
#include <errno.h> // NOLINT
|
||||
|
||||
#include "bin/fdutils.h"
|
||||
#include "bin/socket_base.h"
|
||||
#include "platform/signal_blocker.h"
|
||||
|
||||
namespace dart {
|
||||
namespace bin {
|
||||
|
||||
SynchronousSocket::SynchronousSocket(intptr_t fd) : fd_(fd) {}
|
||||
|
||||
|
||||
void SynchronousSocket::SetClosedFd() {
|
||||
fd_ = kClosedFd;
|
||||
bool SynchronousSocket::Initialize() {
|
||||
// Nothing to do on Linux.
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -60,6 +59,35 @@ intptr_t SynchronousSocket::CreateConnect(const RawAddr& addr) {
|
|||
}
|
||||
|
||||
|
||||
intptr_t SynchronousSocket::Available(intptr_t fd) {
|
||||
return SocketBase::Available(fd);
|
||||
}
|
||||
|
||||
|
||||
intptr_t SynchronousSocket::GetPort(intptr_t fd) {
|
||||
return SocketBase::GetPort(fd);
|
||||
}
|
||||
|
||||
|
||||
SocketAddress* SynchronousSocket::GetRemotePeer(intptr_t fd, intptr_t* port) {
|
||||
return SocketBase::GetRemotePeer(fd, port);
|
||||
}
|
||||
|
||||
|
||||
intptr_t SynchronousSocket::Read(intptr_t fd,
|
||||
void* buffer,
|
||||
intptr_t num_bytes) {
|
||||
return SocketBase::Read(fd, buffer, num_bytes, SocketBase::kSync);
|
||||
}
|
||||
|
||||
|
||||
intptr_t SynchronousSocket::Write(intptr_t fd,
|
||||
const void* buffer,
|
||||
intptr_t num_bytes) {
|
||||
return SocketBase::Write(fd, buffer, num_bytes, SocketBase::kSync);
|
||||
}
|
||||
|
||||
|
||||
void SynchronousSocket::ShutdownRead(intptr_t fd) {
|
||||
VOID_NO_RETRY_EXPECTED(shutdown(fd, SHUT_RD));
|
||||
}
|
||||
|
@ -69,6 +97,11 @@ void SynchronousSocket::ShutdownWrite(intptr_t fd) {
|
|||
VOID_NO_RETRY_EXPECTED(shutdown(fd, SHUT_WR));
|
||||
}
|
||||
|
||||
|
||||
void SynchronousSocket::Close(intptr_t fd) {
|
||||
return SocketBase::Close(fd);
|
||||
}
|
||||
|
||||
} // namespace bin
|
||||
} // namespace dart
|
||||
|
||||
|
|
|
@ -7,69 +7,105 @@
|
|||
#include "platform/globals.h"
|
||||
#if defined(HOST_OS_WINDOWS)
|
||||
|
||||
#include "bin/socket_base.h"
|
||||
#include "bin/sync_socket.h"
|
||||
|
||||
#include "bin/builtin.h"
|
||||
#include "bin/log.h"
|
||||
#include "bin/utils.h"
|
||||
#include "bin/utils_win.h"
|
||||
|
||||
// #define SOCKET_LOG_ERROR 1
|
||||
|
||||
// define SOCKET_LOG_ERROR to get log messages only for errors.
|
||||
#if defined(SOCKET_LOG_ERROR)
|
||||
#define LOG_ERR(msg, ...) \
|
||||
{ \
|
||||
int err = errno; \
|
||||
Log::PrintErr("Dart Socket ERROR: %s:%d: " msg, __FILE__, __LINE__, \
|
||||
##__VA_ARGS__); \
|
||||
errno = err; \
|
||||
}
|
||||
#else
|
||||
#define LOG_ERR(msg, ...)
|
||||
#endif // defined(SOCKET_LOG_ERROR)
|
||||
|
||||
namespace dart {
|
||||
namespace bin {
|
||||
|
||||
SynchronousSocket::SynchronousSocket(intptr_t fd) {
|
||||
LOG_ERR("SynchronousSocket is unimplemented\n");
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
|
||||
bool SynchronousSocket::Initialize() {
|
||||
LOG_ERR("SynchronousSocket::Initialize is unimplemented\n");
|
||||
UNIMPLEMENTED();
|
||||
return false;
|
||||
return SocketBase::Initialize();
|
||||
}
|
||||
|
||||
|
||||
void SynchronousSocket::SetClosedFd() {
|
||||
LOG_ERR("SynchronousSocket::SetClosedFd is unimplemented\n");
|
||||
UNIMPLEMENTED();
|
||||
static intptr_t Create(const RawAddr& addr) {
|
||||
const intptr_t type = SOCK_STREAM;
|
||||
SOCKET s = WSASocket(addr.ss.ss_family, type, 0, NULL, 0, 0);
|
||||
return (s == INVALID_SOCKET) ? -1 : s;
|
||||
}
|
||||
|
||||
|
||||
static intptr_t Connect(intptr_t fd, const RawAddr& addr) {
|
||||
SOCKET socket = static_cast<SOCKET>(fd);
|
||||
intptr_t result =
|
||||
connect(socket, &addr.addr, SocketAddress::GetAddrLength(addr));
|
||||
return (result == SOCKET_ERROR) ? -1 : socket;
|
||||
}
|
||||
|
||||
|
||||
intptr_t SynchronousSocket::CreateConnect(const RawAddr& addr) {
|
||||
LOG_ERR("SynchronousSocket::CreateConnect is unimplemented\n");
|
||||
UNIMPLEMENTED();
|
||||
return -1;
|
||||
intptr_t fd = Create(addr);
|
||||
return (fd < 0) ? fd : Connect(fd, addr);
|
||||
}
|
||||
|
||||
|
||||
intptr_t SynchronousSocket::Available(intptr_t fd) {
|
||||
SOCKET socket = static_cast<SOCKET>(fd);
|
||||
DWORD available;
|
||||
intptr_t result = ioctlsocket(socket, FIONREAD, &available);
|
||||
return (result == SOCKET_ERROR) ? -1 : static_cast<intptr_t>(available);
|
||||
}
|
||||
|
||||
|
||||
intptr_t SynchronousSocket::GetPort(intptr_t fd) {
|
||||
SOCKET socket = static_cast<SOCKET>(fd);
|
||||
RawAddr raw;
|
||||
socklen_t size = sizeof(raw);
|
||||
if (getsockname(socket, &raw.addr, &size) == SOCKET_ERROR) {
|
||||
return 0;
|
||||
}
|
||||
return SocketAddress::GetAddrPort(raw);
|
||||
}
|
||||
|
||||
|
||||
SocketAddress* SynchronousSocket::GetRemotePeer(intptr_t fd, intptr_t* port) {
|
||||
SOCKET socket = static_cast<SOCKET>(fd);
|
||||
RawAddr raw;
|
||||
socklen_t size = sizeof(raw);
|
||||
if (getpeername(socket, &raw.addr, &size)) {
|
||||
return NULL;
|
||||
}
|
||||
*port = SocketAddress::GetAddrPort(raw);
|
||||
// Clear the port before calling WSAAddressToString as WSAAddressToString
|
||||
// includes the port in the formatted string.
|
||||
SocketAddress::SetAddrPort(&raw, 0);
|
||||
return new SocketAddress(&raw.addr);
|
||||
}
|
||||
|
||||
|
||||
intptr_t SynchronousSocket::Read(intptr_t fd,
|
||||
void* buffer,
|
||||
intptr_t num_bytes) {
|
||||
SOCKET socket = static_cast<SOCKET>(fd);
|
||||
return recv(socket, reinterpret_cast<char*>(buffer), num_bytes, 0);
|
||||
}
|
||||
|
||||
|
||||
intptr_t SynchronousSocket::Write(intptr_t fd,
|
||||
const void* buffer,
|
||||
intptr_t num_bytes) {
|
||||
SOCKET socket = static_cast<SOCKET>(fd);
|
||||
return send(socket, reinterpret_cast<const char*>(buffer), num_bytes, 0);
|
||||
}
|
||||
|
||||
|
||||
void SynchronousSocket::ShutdownRead(intptr_t fd) {
|
||||
LOG_ERR("SynchronousSocket::ShutdownRead is unimplemented\n");
|
||||
UNIMPLEMENTED();
|
||||
SOCKET socket = static_cast<SOCKET>(fd);
|
||||
shutdown(socket, SD_RECEIVE);
|
||||
}
|
||||
|
||||
|
||||
void SynchronousSocket::ShutdownWrite(intptr_t fd) {
|
||||
LOG_ERR("SynchronousSocket::ShutdownWrite is unimplemented\n");
|
||||
UNIMPLEMENTED();
|
||||
SOCKET socket = static_cast<SOCKET>(fd);
|
||||
shutdown(socket, SD_SEND);
|
||||
}
|
||||
|
||||
|
||||
void SynchronousSocket::Close(intptr_t fd) {
|
||||
SOCKET socket = static_cast<SOCKET>(fd);
|
||||
closesocket(socket);
|
||||
}
|
||||
|
||||
} // namespace bin
|
||||
} // namespace dart
|
||||
|
||||
|
|
|
@ -397,7 +397,6 @@ Future testShutdown() async {
|
|||
// Throws exception when the socket is closed for RECEIVE.
|
||||
Expect.throws(
|
||||
() => socket.readSync(data.length), (e) => e is SocketException);
|
||||
Expect.isTrue(socket.available() == 0);
|
||||
socket.closeSync();
|
||||
|
||||
// Close the socket for writing and try to do a write. This should cause an
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
io/raw_socket_test: Pass, RuntimeError # Issue 28288
|
||||
io/http_close_test: Pass, RuntimeError # Issue 28380
|
||||
io/raw_synchronous_socket_test: Pass, RuntimeError # Issue 29343
|
||||
packages_file_test: Skip # Issue 26715
|
||||
packages_file_test/none: Skip # contains no tests.
|
||||
|
||||
|
@ -232,7 +231,6 @@ io/process_stdin_transform_unsubscribe_test: Pass, Timeout # Issue #28558
|
|||
io/platform_resolved_executable_test/06: RuntimeError # Issue 23641
|
||||
io/skipping_dart2js_compilations_test: Fail # Issue 19551.
|
||||
io/socket_info_ipv6_test: RuntimeError # Issue 27876
|
||||
io/raw_synchronous_socket_test: Crash # Issue 29333, currently unsupported
|
||||
|
||||
[ $system == windows && $compiler == dart2analyzer ]
|
||||
package/package_isolate_test: Crash # Issue 28645
|
||||
|
|
Loading…
Reference in a new issue