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 "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 |
| 16 TCPServerSocket::TCPServerSocket(BaseSocketSubSystem* sys, int oflag, |
| 17 const char* host, uint16_t port) |
| 18 : ref_(1), oflag_(oflag), factory_(this), socket_(NULL), |
| 19 host_(host), port_(port), resource_(0), sys(sys) { |
| 20 } |
| 21 |
| 22 TCPServerSocket::~TCPServerSocket() { |
| 23 assert(!socket_); |
| 24 assert(!ref_); |
| 25 } |
| 26 |
| 27 void TCPServerSocket::addref() { |
| 28 ++ref_; |
| 29 } |
| 30 |
| 31 void TCPServerSocket::release() { |
| 32 if (!--ref_) |
| 33 delete this; |
| 34 } |
| 35 |
| 36 int TCPServerSocket::read(char* buf, size_t count, size_t* nread) { |
| 37 return -1; |
| 38 } |
| 39 |
| 40 int TCPServerSocket::write(const char* buf, size_t count, size_t* nwrote) { |
| 41 return -1; |
| 42 } |
| 43 |
| 44 void TCPServerSocket::close() { |
| 45 if (socket_) { |
| 46 int32_t result = PP_OK_COMPLETIONPENDING; |
| 47 pp::Module::Get()->core()->CallOnMainThread(0, |
| 48 factory_.NewCallback(&TCPServerSocket::Close, &result)); |
| 49 while (result == PP_OK_COMPLETIONPENDING) |
| 50 sys->cond().wait(sys->mutex()); |
| 51 } |
| 52 } |
| 53 |
| 54 int TCPServerSocket::fcntl(int cmd, va_list ap) { |
| 55 if (cmd == F_GETFL) { |
| 56 return oflag_; |
| 57 } else if (cmd == F_SETFL) { |
| 58 oflag_ = va_arg(ap, long); |
| 59 return 0; |
| 60 } else { |
| 61 return -1; |
| 62 } |
| 63 } |
| 64 |
| 65 bool TCPServerSocket::is_read_ready() { |
| 66 return !is_open() || resource_; |
| 67 } |
| 68 |
| 69 bool TCPServerSocket::is_write_ready() { |
| 70 return !is_open(); |
| 71 } |
| 72 |
| 73 bool TCPServerSocket::is_exception() { |
| 74 return !is_open(); |
| 75 } |
| 76 |
| 77 bool TCPServerSocket::listen(int backlog) { |
| 78 int32_t result = PP_OK_COMPLETIONPENDING; |
| 79 pp::Module::Get()->core()->CallOnMainThread(0, |
| 80 factory_.NewCallback(&TCPServerSocket::Listen, backlog, &result)); |
| 81 while (result == PP_OK_COMPLETIONPENDING) |
| 82 sys->cond().wait(sys->mutex()); |
| 83 return result == PP_OK; |
| 84 } |
| 85 |
| 86 PP_Resource TCPServerSocket::accept() { |
| 87 if (!resource_) |
| 88 return 0; |
| 89 |
| 90 PP_Resource ret = resource_; |
| 91 resource_ = 0; |
| 92 pp::Module::Get()->core()->CallOnMainThread(0, |
| 93 factory_.NewCallback(&TCPServerSocket::Accept, |
| 94 static_cast<int32_t*>(NULL))); |
| 95 |
| 96 return ret; |
| 97 } |
| 98 |
| 99 void TCPServerSocket::Listen(int32_t result, int backlog, int32_t* pres) { |
| 100 Mutex::Lock lock(sys->mutex()); |
| 101 assert(!socket_); |
| 102 socket_ = new pp::TCPServerSocketPrivate(sys->instance()); |
| 103 |
| 104 // Ignore bind address and always bind to localhost. |
| 105 uint8_t localhost_ip[4] = { 127, 0, 0, 1 }; |
| 106 PP_NetAddress_Private localhost = {}; |
| 107 if (pp::NetAddressPrivate::CreateFromIPv4Address( |
| 108 localhost_ip, port_, &localhost)) { |
| 109 LOG("TCPServerSocket::Listen: %s\n", |
| 110 pp::NetAddressPrivate::Describe(localhost, true).c_str()); |
| 111 *pres = socket_->Listen(&localhost, backlog, |
| 112 factory_.NewCallback(&TCPServerSocket::Accept, pres)); |
| 113 } else { |
| 114 *pres = PP_ERROR_FAILED; |
| 115 } |
| 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 |
OLD | NEW |