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

Side by Side Diff: remoting/client/plugin/pepper_packet_socket_factory.cc

Issue 10900028: Fix UdpPacketSocket to handle callbacks after the socket is destroyed. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "remoting/client/plugin/pepper_packet_socket_factory.h" 5 #include "remoting/client/plugin/pepper_packet_socket_factory.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/memory/weak_ptr.h"
9 #include "net/base/io_buffer.h" 10 #include "net/base/io_buffer.h"
10 #include "ppapi/cpp/private/net_address_private.h" 11 #include "ppapi/cpp/private/net_address_private.h"
11 #include "ppapi/cpp/private/udp_socket_private.h" 12 #include "ppapi/cpp/private/udp_socket_private.h"
12 #include "remoting/client/plugin/pepper_util.h" 13 #include "remoting/client/plugin/pepper_util.h"
13 #include "third_party/libjingle/source/talk/base/asyncpacketsocket.h" 14 #include "third_party/libjingle/source/talk/base/asyncpacketsocket.h"
14 15
15 namespace remoting { 16 namespace remoting {
16 17
17 namespace { 18 namespace {
18 19
19 // Size of the buffer to allocate for RecvFrom(). 20 // Size of the buffer to allocate for RecvFrom().
20 const int kReceiveBufferSize = 65536; 21 const int kReceiveBufferSize = 65536;
21 22
22 // Maximum amount of data in the send buffers. This is necessary to 23 // Maximum amount of data in the send buffers. This is necessary to
23 // prevent out-of-memory crashes if the caller sends data faster than 24 // prevent out-of-memory crashes if the caller sends data faster than
24 // Pepper's UDP API can handle it. This maximum should never be 25 // Pepper's UDP API can handle it. This maximum should never be
25 // reached under normal conditions. 26 // reached under normal conditions.
26 const int kMaxSendBufferSize = 256 * 1024; 27 const int kMaxSendBufferSize = 256 * 1024;
27 28
28 class UdpPacketSocket : public talk_base::AsyncPacketSocket { 29 class UdpPacketSocket : public talk_base::AsyncPacketSocket {
29 public: 30 public:
30 explicit UdpPacketSocket(const pp::InstanceHandle& instance); 31 explicit UdpPacketSocket(const pp::InstanceHandle& instance);
31 virtual ~UdpPacketSocket(); 32 virtual ~UdpPacketSocket();
32 33
33 // |min_port| and |max_port| are set to zero if the port number 34 // |min_port| and |max_port| are set to zero if the port number
34 // |should be assigned by the OS. 35 // should be assigned by the OS.
35 bool Init(const talk_base::SocketAddress& local_address, 36 bool Init(const talk_base::SocketAddress& local_address,
36 int min_port, 37 int min_port,
37 int max_port); 38 int max_port);
38 39
39 // talk_base::AsyncPacketSocket interface. 40 // talk_base::AsyncPacketSocket interface.
40 virtual talk_base::SocketAddress GetLocalAddress() const; 41 virtual talk_base::SocketAddress GetLocalAddress() const;
41 virtual talk_base::SocketAddress GetRemoteAddress() const; 42 virtual talk_base::SocketAddress GetRemoteAddress() const;
42 virtual int Send(const void* data, size_t data_size); 43 virtual int Send(const void* data, size_t data_size);
43 virtual int SendTo(const void* data, 44 virtual int SendTo(const void* data,
44 size_t data_size, 45 size_t data_size,
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 // the port number is assigned by OS. 81 // the port number is assigned by OS.
81 uint16_t min_port_; 82 uint16_t min_port_;
82 uint16_t max_port_; 83 uint16_t max_port_;
83 84
84 std::vector<char> receive_buffer_; 85 std::vector<char> receive_buffer_;
85 86
86 bool send_pending_; 87 bool send_pending_;
87 std::list<PendingPacket> send_queue_; 88 std::list<PendingPacket> send_queue_;
88 int send_queue_size_; 89 int send_queue_size_;
89 90
91 base::WeakPtrFactory<UdpPacketSocket> weak_factory_;
92
90 DISALLOW_COPY_AND_ASSIGN(UdpPacketSocket); 93 DISALLOW_COPY_AND_ASSIGN(UdpPacketSocket);
91 }; 94 };
92 95
93 UdpPacketSocket::PendingPacket::PendingPacket( 96 UdpPacketSocket::PendingPacket::PendingPacket(
94 const void* buffer, 97 const void* buffer,
95 int buffer_size, 98 int buffer_size,
96 const PP_NetAddress_Private& address) 99 const PP_NetAddress_Private& address)
97 : data(new net::IOBufferWithSize(buffer_size)), 100 : data(new net::IOBufferWithSize(buffer_size)),
98 address(address) { 101 address(address) {
99 memcpy(data->data(), buffer, buffer_size); 102 memcpy(data->data(), buffer, buffer_size);
100 } 103 }
101 104
102 UdpPacketSocket::UdpPacketSocket(const pp::InstanceHandle& instance) 105 UdpPacketSocket::UdpPacketSocket(const pp::InstanceHandle& instance)
103 : socket_(instance), 106 : socket_(instance),
104 state_(STATE_CLOSED), 107 state_(STATE_CLOSED),
105 error_(0), 108 error_(0),
106 min_port_(0), 109 min_port_(0),
107 max_port_(0), 110 max_port_(0),
108 send_pending_(false), 111 send_pending_(false),
109 send_queue_size_(0) { 112 send_queue_size_(0),
113 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
110 } 114 }
111 115
112 UdpPacketSocket::~UdpPacketSocket() { 116 UdpPacketSocket::~UdpPacketSocket() {
113 Close(); 117 Close();
114 } 118 }
115 119
116 bool UdpPacketSocket::Init(const talk_base::SocketAddress& local_address, 120 bool UdpPacketSocket::Init(const talk_base::SocketAddress& local_address,
117 int min_port, 121 int min_port,
118 int max_port) { 122 int max_port) {
119 if (socket_.is_null()) { 123 if (socket_.is_null()) {
120 return false; 124 return false;
121 } 125 }
122 126
123 local_address_ = local_address; 127 local_address_ = local_address;
124 max_port_ = max_port; 128 max_port_ = max_port;
125 min_port_ = min_port; 129 min_port_ = min_port;
126 130
127 PP_NetAddress_Private pp_local_address; 131 PP_NetAddress_Private pp_local_address;
128 if (!SocketAddressToPpAddressWithPort(local_address_, &pp_local_address, 132 if (!SocketAddressToPpAddressWithPort(local_address_, &pp_local_address,
129 min_port_)) { 133 min_port_)) {
130 return false; 134 return false;
131 } 135 }
132 136
133 int result = socket_.Bind(&pp_local_address, PpCompletionCallback( 137 int result = socket_.Bind(&pp_local_address, PpCompletionCallback(
134 base::Bind(&UdpPacketSocket::OnBindCompleted, base::Unretained(this)))); 138 base::Bind(&UdpPacketSocket::OnBindCompleted,
139 weak_factory_.GetWeakPtr())));
135 DCHECK_EQ(result, PP_OK_COMPLETIONPENDING); 140 DCHECK_EQ(result, PP_OK_COMPLETIONPENDING);
136 state_ = STATE_BINDING; 141 state_ = STATE_BINDING;
137 142
138 return true; 143 return true;
139 } 144 }
140 145
141 void UdpPacketSocket::OnBindCompleted(int result) { 146 void UdpPacketSocket::OnBindCompleted(int result) {
142 DCHECK(state_ == STATE_BINDING || state_ == STATE_CLOSED); 147 DCHECK(state_ == STATE_BINDING || state_ == STATE_CLOSED);
143 148
144 if (result == PP_ERROR_ABORTED) { 149 if (result == PP_ERROR_ABORTED) {
(...skipping 17 matching lines...) Expand all
162 } 167 }
163 168
164 if (min_port_ < max_port_) { 169 if (min_port_ < max_port_) {
165 // Try to bind to the next available port. 170 // Try to bind to the next available port.
166 ++min_port_; 171 ++min_port_;
167 PP_NetAddress_Private pp_local_address; 172 PP_NetAddress_Private pp_local_address;
168 if (SocketAddressToPpAddressWithPort(local_address_, &pp_local_address, 173 if (SocketAddressToPpAddressWithPort(local_address_, &pp_local_address,
169 min_port_)) { 174 min_port_)) {
170 int result = socket_.Bind(&pp_local_address, PpCompletionCallback( 175 int result = socket_.Bind(&pp_local_address, PpCompletionCallback(
171 base::Bind(&UdpPacketSocket::OnBindCompleted, 176 base::Bind(&UdpPacketSocket::OnBindCompleted,
172 base::Unretained(this)))); 177 weak_factory_.GetWeakPtr())));
173 DCHECK_EQ(result, PP_OK_COMPLETIONPENDING); 178 DCHECK_EQ(result, PP_OK_COMPLETIONPENDING);
174 } 179 }
175 } else { 180 } else {
176 LOG(ERROR) << "Failed to bind UDP socket: " << result; 181 LOG(ERROR) << "Failed to bind UDP socket: " << result;
177 } 182 }
178 } 183 }
179 184
180 talk_base::SocketAddress UdpPacketSocket::GetLocalAddress() const { 185 talk_base::SocketAddress UdpPacketSocket::GetLocalAddress() const {
181 DCHECK_EQ(state_, STATE_BOUND); 186 DCHECK_EQ(state_, STATE_BOUND);
182 return local_address_; 187 return local_address_;
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 } 256 }
252 257
253 void UdpPacketSocket::DoSend() { 258 void UdpPacketSocket::DoSend() {
254 if (send_pending_ || send_queue_.empty()) 259 if (send_pending_ || send_queue_.empty())
255 return; 260 return;
256 261
257 int result = socket_.SendTo( 262 int result = socket_.SendTo(
258 send_queue_.front().data->data(), send_queue_.front().data->size(), 263 send_queue_.front().data->data(), send_queue_.front().data->size(),
259 &send_queue_.front().address, 264 &send_queue_.front().address,
260 PpCompletionCallback(base::Bind(&UdpPacketSocket::OnSendCompleted, 265 PpCompletionCallback(base::Bind(&UdpPacketSocket::OnSendCompleted,
261 base::Unretained(this)))); 266 weak_factory_.GetWeakPtr())));
262 DCHECK_EQ(result, PP_OK_COMPLETIONPENDING); 267 DCHECK_EQ(result, PP_OK_COMPLETIONPENDING);
263 send_pending_ = true; 268 send_pending_ = true;
264 } 269 }
265 270
266 void UdpPacketSocket::OnSendCompleted(int result) { 271 void UdpPacketSocket::OnSendCompleted(int result) {
267 if (result == PP_ERROR_ABORTED) { 272 if (result == PP_ERROR_ABORTED) {
268 // Send is aborted when the socket is being destroyed. 273 // Send is aborted when the socket is being destroyed.
269 // |send_queue_| may be already destroyed, it's not safe to access 274 // |send_queue_| may be already destroyed, it's not safe to access
270 // it here. 275 // it here.
271 return; 276 return;
(...skipping 26 matching lines...) Expand all
298 send_queue_size_ -= send_queue_.front().data->size(); 303 send_queue_size_ -= send_queue_.front().data->size();
299 send_queue_.pop_front(); 304 send_queue_.pop_front();
300 DoSend(); 305 DoSend();
301 } 306 }
302 307
303 void UdpPacketSocket::DoRead() { 308 void UdpPacketSocket::DoRead() {
304 receive_buffer_.resize(kReceiveBufferSize); 309 receive_buffer_.resize(kReceiveBufferSize);
305 int result = socket_.RecvFrom( 310 int result = socket_.RecvFrom(
306 &receive_buffer_[0], receive_buffer_.size(), 311 &receive_buffer_[0], receive_buffer_.size(),
307 PpCompletionCallback(base::Bind(&UdpPacketSocket::OnReadCompleted, 312 PpCompletionCallback(base::Bind(&UdpPacketSocket::OnReadCompleted,
308 base::Unretained(this)))); 313 weak_factory_.GetWeakPtr())));
309 DCHECK_EQ(result, PP_OK_COMPLETIONPENDING); 314 DCHECK_EQ(result, PP_OK_COMPLETIONPENDING);
310 } 315 }
311 316
312 void UdpPacketSocket::OnReadCompleted(int result) { 317 void UdpPacketSocket::OnReadCompleted(int result) {
313 HandleReadResult(result); 318 HandleReadResult(result);
314 if (result > 0) { 319 if (result > 0) {
315 DoRead(); 320 DoRead();
316 } 321 }
317 } 322 }
318 323
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 const talk_base::SocketAddress& remote_address, 374 const talk_base::SocketAddress& remote_address,
370 const talk_base::ProxyInfo& proxy_info, 375 const talk_base::ProxyInfo& proxy_info,
371 const std::string& user_agent, 376 const std::string& user_agent,
372 bool ssl) { 377 bool ssl) {
373 // We don't use TCP sockets for remoting connections. 378 // We don't use TCP sockets for remoting connections.
374 NOTREACHED(); 379 NOTREACHED();
375 return NULL; 380 return NULL;
376 } 381 }
377 382
378 } // namespace remoting 383 } // namespace remoting
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698