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

Unified Diff: libraries/nacl-mounts/net/TcpServerSocket.cc

Issue 10392070: Socket subsystem implementation (Closed) Base URL: http://naclports.googlecode.com/svn/trunk/src/
Patch Set: Created 8 years, 6 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
« no previous file with comments | « libraries/nacl-mounts/net/TcpServerSocket.h ('k') | libraries/nacl-mounts/net/TcpSocket.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: libraries/nacl-mounts/net/TcpServerSocket.cc
===================================================================
--- libraries/nacl-mounts/net/TcpServerSocket.cc (revision 0)
+++ libraries/nacl-mounts/net/TcpServerSocket.cc (revision 0)
@@ -0,0 +1,172 @@
+// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/TcpServerSocket.h"
+
+#include <assert.h>
+#include <string.h>
+
+#include "../net/SocketSubSystem.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/private/net_address_private.h"
+#include "../util/DebugPrint.h"
+#include "../util/PthreadHelpers.h"
+
+TCPServerSocket::TCPServerSocket(SocketSubSystem* sys, int oflag,
+ const sockaddr* saddr, socklen_t addrlen)
+ : ref_(1), oflag_(oflag), factory_(this), socket_(NULL),
+ resource_(0), sys_(sys) {
+ assert(sizeof(sin6_) >= addrlen);
+ memcpy(&sin6_, saddr, std::min(sizeof(sin6_), addrlen));
+}
+
+TCPServerSocket::~TCPServerSocket() {
+ assert(!socket_);
+ assert(!ref_);
+}
+
+void TCPServerSocket::addref() {
+ ++ref_;
+}
+
+void TCPServerSocket::release() {
+ if (!--ref_)
+ delete this;
+}
+
+int TCPServerSocket::read(char* buf, size_t count, size_t* nread) {
+ return -1;
+}
+
+int TCPServerSocket::write(const char* buf, size_t count, size_t* nwrote) {
+ return -1;
+}
+
+void TCPServerSocket::close() {
+ SimpleAutoLock lock(sys_->mutex());
+ if (socket_) {
+ int32_t result = PP_OK_COMPLETIONPENDING;
+ pp::Module::Get()->core()->CallOnMainThread(0,
+ factory_.NewCallback(&TCPServerSocket::Close, &result));
+ while (result == PP_OK_COMPLETIONPENDING)
+ sys_->cond().wait(sys_->mutex());
+ }
+}
+
+int TCPServerSocket::fcntl(int cmd, va_list ap) {
+ if (cmd == F_GETFL) {
+ return oflag_;
+ } else if (cmd == F_SETFL) {
+ oflag_ = va_arg(ap, long);
+ return 0;
+ } else {
+ return -1;
+ }
+}
+
+bool TCPServerSocket::is_read_ready() {
+ return !is_open() || resource_;
+}
+
+bool TCPServerSocket::is_write_ready() {
+ return !is_open();
+}
+
+bool TCPServerSocket::is_exception() {
+ return !is_open();
+}
+
+bool TCPServerSocket::listen(int backlog) {
+ SimpleAutoLock lock(sys_->mutex());
+ int32_t result = PP_OK_COMPLETIONPENDING;
+ pp::Module::Get()->core()->CallOnMainThread(0,
+ factory_.NewCallback(&TCPServerSocket::Listen, backlog, &result));
+ while (result == PP_OK_COMPLETIONPENDING)
+ sys_->cond().wait(sys_->mutex());
+ return result == PP_OK;
+}
+
+PP_Resource TCPServerSocket::accept() {
+ if (!resource_)
+ return 0;
+
+ PP_Resource ret = resource_;
+ resource_ = 0;
+ pp::Module::Get()->core()->CallOnMainThread(0,
+ factory_.NewCallback(&TCPServerSocket::Accept,
+ static_cast<int32_t*>(NULL)));
+
+ return ret;
+}
+
+bool TCPServerSocket::CreateNetAddress(const sockaddr* saddr,
+ PP_NetAddress_Private* addr) {
+ if (saddr->sa_family == AF_INET) {
+ const sockaddr_in* sin4 = reinterpret_cast<const sockaddr_in*>(saddr);
+ if (!pp::NetAddressPrivate::CreateFromIPv4Address(
+ reinterpret_cast<const uint8_t*>(&sin4->sin_addr),
+ ntohs(sin4->sin_port), addr)) {
+ return false;
+ }
+ } else {
+ const sockaddr_in6* sin6 = reinterpret_cast<const sockaddr_in6*>(saddr);
+ if (!pp::NetAddressPrivate::CreateFromIPv6Address(
+ reinterpret_cast<const uint8_t*>(&sin6->sin6_addr), 0,
+ ntohs(sin6->sin6_port), addr)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+void TCPServerSocket::Listen(int32_t result, int backlog, int32_t* pres) {
+ SimpleAutoLock lock(sys_->mutex());
+ assert(!socket_);
+ socket_ = new pp::TCPServerSocketPrivate(sys_->instance());
+
+ PP_NetAddress_Private addr = {};
+ if (CreateNetAddress(reinterpret_cast<const sockaddr*>(&sin6_), &addr)) {
+ dbgprintf("TCPServerSocket::Listen: %s\n",
+ pp::NetAddressPrivate::Describe(addr, true).c_str());
+ *pres = socket_->Listen(&addr, backlog,
+ factory_.NewCallback(&TCPServerSocket::Accept, pres));
+ } else {
+ dbgprintf("Listen failed: %s\n",
+ pp::NetAddressPrivate::Describe(addr, true).c_str());
+ *pres = PP_ERROR_FAILED;
+ }
+ if (*pres != PP_OK_COMPLETIONPENDING) {
+ sys_->cond().broadcast();
+ }
+}
+
+void TCPServerSocket::Accept(int32_t result, int32_t* pres) {
+ SimpleAutoLock lock(sys_->mutex());
+ assert(socket_);
+ if (result == PP_OK) {
+ result = socket_->Accept(&resource_,
+ factory_.NewCallback(&TCPServerSocket::OnAccept));
+ if (result == PP_OK_COMPLETIONPENDING)
+ result = PP_OK;
+ }
+ if (pres)
+ *pres = result;
+ sys_->cond().broadcast();
+}
+
+void TCPServerSocket::OnAccept(int32_t result) {
+ SimpleAutoLock lock(sys_->mutex());
+ assert(socket_);
+ sys_->cond().broadcast();
+}
+
+void TCPServerSocket::Close(int32_t result, int32_t* pres) {
+ SimpleAutoLock lock(sys_->mutex());
+ delete socket_;
+ socket_ = NULL;
+ *pres = PP_OK;
+ sys_->cond().broadcast();
+}
+
« no previous file with comments | « libraries/nacl-mounts/net/TcpServerSocket.h ('k') | libraries/nacl-mounts/net/TcpSocket.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698