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 #ifdef __GLIBC__ |
| 6 #include "net/TcpServerSocket.h" |
| 7 |
| 8 #include <assert.h> |
| 9 #include <string.h> |
| 10 |
| 11 #include "include/ppapi/cpp/private/net_address_private.h" |
| 12 #include "net/SocketSubSystem.h" |
| 13 #include "ppapi/c/pp_errors.h" |
| 14 #include "ppapi/cpp/module.h" |
| 15 #include "util/DebugPrint.h" |
| 16 |
| 17 TCPServerSocket::TCPServerSocket(SocketSubSystem* sys, int oflag, |
| 18 const char* host, uint16_t port) |
| 19 : ref_(1), oflag_(oflag), factory_(this), socket_(NULL), |
| 20 host_(host), port_(port), resource_(0), sys_(sys) { |
| 21 } |
| 22 |
| 23 TCPServerSocket::~TCPServerSocket() { |
| 24 assert(!socket_); |
| 25 assert(!ref_); |
| 26 } |
| 27 |
| 28 void TCPServerSocket::addref() { |
| 29 ++ref_; |
| 30 } |
| 31 |
| 32 void TCPServerSocket::release() { |
| 33 if (!--ref_) |
| 34 delete this; |
| 35 } |
| 36 |
| 37 int TCPServerSocket::read(char* buf, size_t count, size_t* nread) { |
| 38 return -1; |
| 39 } |
| 40 |
| 41 int TCPServerSocket::write(const char* buf, size_t count, size_t* nwrote) { |
| 42 return -1; |
| 43 } |
| 44 |
| 45 void TCPServerSocket::close() { |
| 46 if (socket_) { |
| 47 int32_t result = PP_OK_COMPLETIONPENDING; |
| 48 pp::Module::Get()->core()->CallOnMainThread(0, |
| 49 factory_.NewCallback(&TCPServerSocket::Close, &result)); |
| 50 while (result == PP_OK_COMPLETIONPENDING) |
| 51 sys_->cond().wait(sys_->mutex()); |
| 52 } |
| 53 } |
| 54 |
| 55 int TCPServerSocket::fcntl(int cmd, va_list ap) { |
| 56 if (cmd == F_GETFL) { |
| 57 return oflag_; |
| 58 } else if (cmd == F_SETFL) { |
| 59 oflag_ = va_arg(ap, long); |
| 60 return 0; |
| 61 } else { |
| 62 return -1; |
| 63 } |
| 64 } |
| 65 |
| 66 bool TCPServerSocket::is_read_ready() { |
| 67 return !is_open() || resource_; |
| 68 } |
| 69 |
| 70 bool TCPServerSocket::is_write_ready() { |
| 71 return !is_open(); |
| 72 } |
| 73 |
| 74 bool TCPServerSocket::is_exception() { |
| 75 return !is_open(); |
| 76 } |
| 77 |
| 78 bool TCPServerSocket::listen(int backlog) { |
| 79 int32_t result = PP_OK_COMPLETIONPENDING; |
| 80 pp::Module::Get()->core()->CallOnMainThread(0, |
| 81 factory_.NewCallback(&TCPServerSocket::Listen, backlog, &result)); |
| 82 while (result == PP_OK_COMPLETIONPENDING) |
| 83 sys_->cond().wait(sys_->mutex()); |
| 84 return result == PP_OK; |
| 85 } |
| 86 |
| 87 PP_Resource TCPServerSocket::accept() { |
| 88 if (!resource_) |
| 89 return 0; |
| 90 |
| 91 PP_Resource ret = resource_; |
| 92 resource_ = 0; |
| 93 pp::Module::Get()->core()->CallOnMainThread(0, |
| 94 factory_.NewCallback(&TCPServerSocket::Accept, |
| 95 static_cast<int32_t*>(NULL))); |
| 96 |
| 97 return ret; |
| 98 } |
| 99 |
| 100 void TCPServerSocket::Listen(int32_t result, int backlog, int32_t* pres) { |
| 101 Mutex::Lock lock(sys_->mutex()); |
| 102 assert(!socket_); |
| 103 socket_ = new pp::TCPServerSocketPrivate(sys_->instance()); |
| 104 |
| 105 // Ignore bind address and always bind to localhost. |
| 106 uint8_t localhost_ip[4] = { 127, 0, 0, 1 }; |
| 107 PP_NetAddress_Private localhost = {}; |
| 108 if (pp::NetAddressPrivate::CreateFromIPv4Address( |
| 109 localhost_ip, port_, &localhost)) { |
| 110 LOG("TCPServerSocket::Listen: %s\n", |
| 111 pp::NetAddressPrivate::Describe(localhost, true).c_str()); |
| 112 *pres = socket_->Listen(&localhost, backlog, |
| 113 factory_.NewCallback(&TCPServerSocket::Accept, pres)); |
| 114 } else { |
| 115 *pres = PP_ERROR_FAILED; |
| 116 } |
| 117 if (*pres != PP_OK_COMPLETIONPENDING) { |
| 118 sys_->cond().broadcast(); |
| 119 } |
| 120 } |
| 121 |
| 122 void TCPServerSocket::Accept(int32_t result, int32_t* pres) { |
| 123 Mutex::Lock lock(sys_->mutex()); |
| 124 assert(socket_); |
| 125 if (result == PP_OK) { |
| 126 result = socket_->Accept(&resource_, |
| 127 factory_.NewCallback(&TCPServerSocket::OnAccept)); |
| 128 if (result == PP_OK_COMPLETIONPENDING) |
| 129 result = PP_OK; |
| 130 } |
| 131 if (pres) |
| 132 *pres = result; |
| 133 sys_->cond().broadcast(); |
| 134 } |
| 135 |
| 136 void TCPServerSocket::OnAccept(int32_t result) { |
| 137 Mutex::Lock lock(sys_->mutex()); |
| 138 assert(socket_); |
| 139 sys_->cond().broadcast(); |
| 140 } |
| 141 |
| 142 void TCPServerSocket::Close(int32_t result, int32_t* pres) { |
| 143 Mutex::Lock lock(sys_->mutex()); |
| 144 delete socket_; |
| 145 socket_ = NULL; |
| 146 *pres = PP_OK; |
| 147 sys_->cond().broadcast(); |
| 148 } |
| 149 |
| 150 #endif // __GLIBC |
| 151 |
OLD | NEW |