Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(108)

Unified Diff: native_client_sdk/src/libraries/nacl_io/mount_node_socket.cc

Issue 23498015: [NaCl SDK] Support non blocking TCP/UDP (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Merge Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: native_client_sdk/src/libraries/nacl_io/mount_node_socket.cc
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_node_socket.cc b/native_client_sdk/src/libraries/nacl_io/mount_node_socket.cc
index be524d51e780c8c6e4bacb17d8d0654d7ea088a1..abaf55ba1e9e48ae0a89fa16d08b65d87ce62962 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_node_socket.cc
+++ b/native_client_sdk/src/libraries/nacl_io/mount_node_socket.cc
@@ -7,6 +7,7 @@
#include <errno.h>
#include <string.h>
+#include <sys/fcntl.h>
#include "nacl_io/mount.h"
#include "nacl_io/mount_node_socket.h"
@@ -18,10 +19,12 @@
namespace nacl_io {
MountNodeSocket::MountNodeSocket(Mount* mount)
- : MountNode(mount),
+ : MountNodeStream(mount),
socket_resource_(0),
local_addr_(0),
- remote_addr_(0) {
+ remote_addr_(0),
+ socket_flags_(0),
+ last_errno_(0) {
stat_.st_mode |= S_IFSOCK;
}
@@ -32,11 +35,10 @@ void MountNodeSocket::Destroy() {
mount_->ppapi()->ReleaseResource(local_addr_);
if (remote_addr_)
mount_->ppapi()->ReleaseResource(remote_addr_);
-}
-// Default to always signaled, until socket select support is added.
-uint32_t MountNodeSocket::GetEventStatus() {
- return POLLIN | POLLOUT;
+ socket_resource_ = 0;
+ local_addr_ = 0;
+ remote_addr_ = 0;
}
// Assume that |addr| and |out_addr| are non-NULL.
@@ -49,7 +51,8 @@ Error MountNodeSocket::MMap(void* addr,
return EACCES;
}
-// Normal read/write operations on a file
+// Normal read/write operations on a Socket are equivalent to
+// send/recv with a flag value of 0.
Error MountNodeSocket::Read(size_t offs,
void* buf,
size_t count,
@@ -61,18 +64,36 @@ Error MountNodeSocket::Write(size_t offs,
const void* buf,
size_t count,
int* out_bytes) {
- if (0 == remote_addr_)
- return EDESTADDRREQ;
-
return Send(buf, count, 0, out_bytes);
}
-NetAddressInterface* MountNodeSocket::NetAddress() {
+
+NetAddressInterface* MountNodeSocket::NetInterface() {
+ if (mount_->ppapi() == NULL)
+ return NULL;
+
return mount_->ppapi()->GetNetAddressInterface();
}
+TCPSocketInterface* MountNodeSocket::TCPInterface() {
+ if (mount_->ppapi() == NULL)
+ return NULL;
+
+ return mount_->ppapi()->GetTCPSocketInterface();
+}
+
+UDPSocketInterface* MountNodeSocket::UDPInterface() {
+ if (mount_->ppapi() == NULL)
+ return NULL;
+
+ return mount_->ppapi()->GetUDPSocketInterface();
+}
+
PP_Resource MountNodeSocket::SockAddrToResource(const struct sockaddr* addr,
socklen_t len) {
+ if (NULL == addr)
+ return 0;
+
if (AF_INET == addr->sa_family) {
PP_NetAddress_IPv4 addr4;
const sockaddr_in* sin = reinterpret_cast<const sockaddr_in*>(addr);
@@ -115,7 +136,7 @@ socklen_t MountNodeSocket::ResourceToSockAddr(PP_Resource addr,
PP_NetAddress_IPv4 ipv4;
PP_NetAddress_IPv6 ipv6;
- if (PP_TRUE == NetAddress()->DescribeAsIPv4Address(addr, &ipv4)) {
+ if (PP_TRUE == NetInterface()->DescribeAsIPv4Address(addr, &ipv4)) {
sockaddr_in addr4;
addr4.sin_family = AF_INET;
addr4.sin_port = ipv4.port;
@@ -126,7 +147,7 @@ socklen_t MountNodeSocket::ResourceToSockAddr(PP_Resource addr,
return sizeof(sockaddr_in);
}
- if (PP_TRUE == NetAddress()->DescribeAsIPv6Address(addr, &ipv6)) {
+ if (PP_TRUE == NetInterface()->DescribeAsIPv6Address(addr, &ipv6)) {
sockaddr_in6 addr6;
addr6.sin6_family = AF_INET6;
addr6.sin6_port = ipv6.port;
@@ -197,8 +218,9 @@ Error MountNodeSocket::Bind(const struct sockaddr* addr, socklen_t len) {
return EINVAL;
}
+
Error MountNodeSocket::Recv(void* buf, size_t len, int flags, int* out_len) {
- return EINVAL;
+ return RecvFrom(buf, len, flags, NULL, 0, out_len);
}
Error MountNodeSocket::RecvFrom(void* buf,
@@ -207,14 +229,56 @@ Error MountNodeSocket::RecvFrom(void* buf,
struct sockaddr* src_addr,
socklen_t* addrlen,
int* out_len) {
- return EOPNOTSUPP;
+ PP_Resource addr;
+ Error err = RecvHelper(buf, len, flags, &addr, out_len);
+ if (0 != addr) {
+ if (src_addr)
+ *addrlen = ResourceToSockAddr(addr, *addrlen, src_addr);
+
+ mount_->ppapi()->ReleaseResource(addr);
+ }
+
+ return err;
}
+Error MountNodeSocket::RecvHelper(void* buf,
+ size_t len,
+ int flags,
+ PP_Resource* addr,
+ int* out_len) {
+ if (0 == socket_resource_)
+ return EBADF;
+
+ int ms = read_timeout_;
+ if ((flags & MSG_DONTWAIT) || (GetMode() & O_NONBLOCK))
+ ms = 0;
+
+ //TODO(noelallen) BUG=295177
+ //For UDP we should support filtering packets when using connect
+ EventListenerLock wait(GetEventEmitter());
+ Error err = wait.WaitOnEvent(POLLIN, ms);
+
+ // Timeout is treated as a would block for sockets.
+ if (ETIMEDOUT == err)
+ return EWOULDBLOCK;
+
+ if (err)
+ return err;
+
+ err = Recv_Locked(buf, len, addr, out_len);
+
+ // We must have read from then inputbuffer, so Q up some receive work.
+ if ((err == 0) && *out_len)
+ QueueInput();
+ return err;
+}
+
+
Error MountNodeSocket::Send(const void* buf,
- size_t len,
- int flags,
- int* out_len) {
- return EOPNOTSUPP;
+ size_t len,
+ int flags,
+ int* out_len) {
+ return SendHelper(buf, len, flags, remote_addr_, out_len);
}
Error MountNodeSocket::SendTo(const void* buf,
@@ -223,7 +287,56 @@ Error MountNodeSocket::SendTo(const void* buf,
const struct sockaddr* dest_addr,
socklen_t addrlen,
int* out_len) {
- return EOPNOTSUPP;
+ if ((NULL == dest_addr) && (0 == remote_addr_))
+ return EDESTADDRREQ;
+
+ PP_Resource addr = SockAddrToResource(dest_addr, addrlen);
+ if (addr) {
+ Error err = SendHelper(buf, len, flags, addr, out_len);
+ mount_->ppapi()->ReleaseResource(addr);
+ return err;
+ }
+
+ return EINVAL;
+}
+
+Error MountNodeSocket::SendHelper(const void* buf,
+ size_t len,
+ int flags,
+ PP_Resource addr,
+ int* out_len) {
+ if (0 == socket_resource_)
+ return EBADF;
+
+ if (0 == addr)
+ return ENOTCONN;
+
+ int ms = write_timeout_;
+ if ((flags & MSG_DONTWAIT) || (GetMode() & O_NONBLOCK))
+ ms = 0;
+
+ EventListenerLock wait(GetEventEmitter());
+ Error err = wait.WaitOnEvent(POLLOUT, ms);
+
+ // Timeout is treated as a would block for sockets.
+ if (ETIMEDOUT == err)
+ return EWOULDBLOCK;
+
+ if (err)
+ return err;
+
+ err = Send_Locked(buf, len, addr, out_len);
+
+ // We must have added to the output buffer, so Q up some transmit work.
+ if ((err == 0) && *out_len)
+ QueueOutput();
+ return err;
+}
+
+void MountNodeSocket::SetError_Locked(int pp_error_num) {
+ SetStreamFlags(SSF_ERROR | SSF_CLOSED);
+ ClearStreamFlags(SSF_CAN_SEND | SSF_CAN_RECV);
+ last_errno_ = PPErrorToErrno(pp_error_num);
}
Error MountNodeSocket::Shutdown(int how) {
@@ -257,7 +370,6 @@ Error MountNodeSocket::GetSockName(struct sockaddr* addr, socklen_t* len) {
return ENOTCONN;
}
-
} // namespace nacl_io
#endif // PROVIDES_SOCKET_API

Powered by Google App Engine
This is Rietveld 408576698