OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2012 The Chromium OS Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "net/TcpServerSocket.h" |
| 6 |
| 7 #include <assert.h> |
| 8 #include <string.h> |
| 9 |
| 10 #include "ppapi/cpp/private/net_address_private.h" |
| 11 #include "../net/SocketSubSystem.h" |
| 12 #include "ppapi/c/pp_errors.h" |
| 13 #include "ppapi/cpp/module.h" |
| 14 #include "../util/DebugPrint.h" |
| 15 #include "../util/PthreadHelpers.h" |
| 16 |
| 17 TCPServerSocket::TCPServerSocket(SocketSubSystem* sys, int oflag, |
| 18 const sockaddr* saddr, socklen_t addrlen) |
| 19 : ref_(1), oflag_(oflag), factory_(this), socket_(NULL), |
| 20 resource_(0), sys_(sys) { |
| 21 assert(sizeof(sin6_) >= addrlen); |
| 22 memcpy(&sin6_, saddr, std::min(sizeof(sin6_), addrlen)); |
| 23 } |
| 24 |
| 25 TCPServerSocket::~TCPServerSocket() { |
| 26 assert(!socket_); |
| 27 assert(!ref_); |
| 28 } |
| 29 |
| 30 void TCPServerSocket::addref() { |
| 31 ++ref_; |
| 32 } |
| 33 |
| 34 void TCPServerSocket::release() { |
| 35 if (!--ref_) |
| 36 delete this; |
| 37 } |
| 38 |
| 39 int TCPServerSocket::read(char* buf, size_t count, size_t* nread) { |
| 40 return -1; |
| 41 } |
| 42 |
| 43 int TCPServerSocket::write(const char* buf, size_t count, size_t* nwrote) { |
| 44 return -1; |
| 45 } |
| 46 |
| 47 void TCPServerSocket::close() { |
| 48 SimpleAutoLock lock(sys_->mutex()); |
| 49 if (socket_) { |
| 50 int32_t result = PP_OK_COMPLETIONPENDING; |
| 51 pp::Module::Get()->core()->CallOnMainThread(0, |
| 52 factory_.NewCallback(&TCPServerSocket::Close, &result)); |
| 53 while (result == PP_OK_COMPLETIONPENDING) |
| 54 sys_->cond().wait(sys_->mutex()); |
| 55 } |
| 56 } |
| 57 |
| 58 int TCPServerSocket::fcntl(int cmd, va_list ap) { |
| 59 if (cmd == F_GETFL) { |
| 60 return oflag_; |
| 61 } else if (cmd == F_SETFL) { |
| 62 oflag_ = va_arg(ap, long); |
| 63 return 0; |
| 64 } else { |
| 65 return -1; |
| 66 } |
| 67 } |
| 68 |
| 69 bool TCPServerSocket::is_read_ready() { |
| 70 return !is_open() || resource_; |
| 71 } |
| 72 |
| 73 bool TCPServerSocket::is_write_ready() { |
| 74 return !is_open(); |
| 75 } |
| 76 |
| 77 bool TCPServerSocket::is_exception() { |
| 78 return !is_open(); |
| 79 } |
| 80 |
| 81 bool TCPServerSocket::listen(int backlog) { |
| 82 SimpleAutoLock lock(sys_->mutex()); |
| 83 int32_t result = PP_OK_COMPLETIONPENDING; |
| 84 pp::Module::Get()->core()->CallOnMainThread(0, |
| 85 factory_.NewCallback(&TCPServerSocket::Listen, backlog, &result)); |
| 86 while (result == PP_OK_COMPLETIONPENDING) |
| 87 sys_->cond().wait(sys_->mutex()); |
| 88 return result == PP_OK; |
| 89 } |
| 90 |
| 91 PP_Resource TCPServerSocket::accept() { |
| 92 if (!resource_) |
| 93 return 0; |
| 94 |
| 95 PP_Resource ret = resource_; |
| 96 resource_ = 0; |
| 97 pp::Module::Get()->core()->CallOnMainThread(0, |
| 98 factory_.NewCallback(&TCPServerSocket::Accept, |
| 99 static_cast<int32_t*>(NULL))); |
| 100 |
| 101 return ret; |
| 102 } |
| 103 |
| 104 bool TCPServerSocket::CreateNetAddress(const sockaddr* saddr, |
| 105 PP_NetAddress_Private* addr) { |
| 106 if (saddr->sa_family == AF_INET) { |
| 107 const sockaddr_in* sin4 = reinterpret_cast<const sockaddr_in*>(saddr); |
| 108 if (!pp::NetAddressPrivate::CreateFromIPv4Address( |
| 109 reinterpret_cast<const uint8_t*>(&sin4->sin_addr), |
| 110 ntohs(sin4->sin_port), addr)) { |
| 111 return false; |
| 112 } |
| 113 } else { |
| 114 const sockaddr_in6* sin6 = reinterpret_cast<const sockaddr_in6*>(saddr); |
| 115 if (!pp::NetAddressPrivate::CreateFromIPv6Address( |
| 116 reinterpret_cast<const uint8_t*>(&sin6->sin6_addr), 0, |
| 117 ntohs(sin6->sin6_port), addr)) { |
| 118 return false; |
| 119 } |
| 120 } |
| 121 return true; |
| 122 } |
| 123 |
| 124 void TCPServerSocket::Listen(int32_t result, int backlog, int32_t* pres) { |
| 125 SimpleAutoLock lock(sys_->mutex()); |
| 126 assert(!socket_); |
| 127 socket_ = new pp::TCPServerSocketPrivate(sys_->instance()); |
| 128 |
| 129 PP_NetAddress_Private addr = {}; |
| 130 if (CreateNetAddress(reinterpret_cast<const sockaddr*>(&sin6_), &addr)) { |
| 131 dbgprintf("TCPServerSocket::Listen: %s\n", |
| 132 pp::NetAddressPrivate::Describe(addr, true).c_str()); |
| 133 *pres = socket_->Listen(&addr, backlog, |
| 134 factory_.NewCallback(&TCPServerSocket::Accept, pres)); |
| 135 } else { |
| 136 dbgprintf("Listen failed: %s\n", |
| 137 pp::NetAddressPrivate::Describe(addr, true).c_str()); |
| 138 *pres = PP_ERROR_FAILED; |
| 139 } |
| 140 if (*pres != PP_OK_COMPLETIONPENDING) { |
| 141 sys_->cond().broadcast(); |
| 142 } |
| 143 } |
| 144 |
| 145 void TCPServerSocket::Accept(int32_t result, int32_t* pres) { |
| 146 SimpleAutoLock lock(sys_->mutex()); |
| 147 assert(socket_); |
| 148 if (result == PP_OK) { |
| 149 result = socket_->Accept(&resource_, |
| 150 factory_.NewCallback(&TCPServerSocket::OnAccept)); |
| 151 if (result == PP_OK_COMPLETIONPENDING) |
| 152 result = PP_OK; |
| 153 } |
| 154 if (pres) |
| 155 *pres = result; |
| 156 sys_->cond().broadcast(); |
| 157 } |
| 158 |
| 159 void TCPServerSocket::OnAccept(int32_t result) { |
| 160 SimpleAutoLock lock(sys_->mutex()); |
| 161 assert(socket_); |
| 162 sys_->cond().broadcast(); |
| 163 } |
| 164 |
| 165 void TCPServerSocket::Close(int32_t result, int32_t* pres) { |
| 166 SimpleAutoLock lock(sys_->mutex()); |
| 167 delete socket_; |
| 168 socket_ = NULL; |
| 169 *pres = PP_OK; |
| 170 sys_->cond().broadcast(); |
| 171 } |
| 172 |
OLD | NEW |