OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "ppapi/proxy/udp_socket_resource_base.h" | 5 #include "ppapi/proxy/udp_socket_resource_base.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <cstring> | 8 #include <cstring> |
9 | 9 |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 16 matching lines...) Expand all Loading... |
27 1024 * UDPSocketResourceBase::kMaxWriteSize; | 27 1024 * UDPSocketResourceBase::kMaxWriteSize; |
28 const int32_t UDPSocketResourceBase::kMaxReceiveBufferSize = | 28 const int32_t UDPSocketResourceBase::kMaxReceiveBufferSize = |
29 1024 * UDPSocketResourceBase::kMaxReadSize; | 29 1024 * UDPSocketResourceBase::kMaxReadSize; |
30 const size_t UDPSocketResourceBase::kPluginReceiveBufferSlots = 32u; | 30 const size_t UDPSocketResourceBase::kPluginReceiveBufferSlots = 32u; |
31 | 31 |
32 UDPSocketResourceBase::UDPSocketResourceBase(Connection connection, | 32 UDPSocketResourceBase::UDPSocketResourceBase(Connection connection, |
33 PP_Instance instance, | 33 PP_Instance instance, |
34 bool private_api) | 34 bool private_api) |
35 : PluginResource(connection, instance), | 35 : PluginResource(connection, instance), |
36 private_api_(private_api), | 36 private_api_(private_api), |
| 37 bind_called_(false), |
37 bound_(false), | 38 bound_(false), |
38 closed_(false), | 39 closed_(false), |
39 read_buffer_(NULL), | 40 read_buffer_(NULL), |
40 bytes_to_read_(-1), | 41 bytes_to_read_(-1), |
41 recvfrom_addr_resource_(NULL) { | 42 recvfrom_addr_resource_(NULL) { |
42 recvfrom_addr_.size = 0; | 43 recvfrom_addr_.size = 0; |
43 memset(recvfrom_addr_.data, 0, | 44 memset(recvfrom_addr_.data, 0, |
44 arraysize(recvfrom_addr_.data) * sizeof(*recvfrom_addr_.data)); | 45 arraysize(recvfrom_addr_.data) * sizeof(*recvfrom_addr_.data)); |
45 bound_addr_.size = 0; | 46 bound_addr_.size = 0; |
46 memset(bound_addr_.data, 0, | 47 memset(bound_addr_.data, 0, |
47 arraysize(bound_addr_.data) * sizeof(*bound_addr_.data)); | 48 arraysize(bound_addr_.data) * sizeof(*bound_addr_.data)); |
48 | 49 |
49 if (private_api) | 50 if (private_api) |
50 SendCreate(BROWSER, PpapiHostMsg_UDPSocket_CreatePrivate()); | 51 SendCreate(BROWSER, PpapiHostMsg_UDPSocket_CreatePrivate()); |
51 else | 52 else |
52 SendCreate(BROWSER, PpapiHostMsg_UDPSocket_Create()); | 53 SendCreate(BROWSER, PpapiHostMsg_UDPSocket_Create()); |
53 | 54 |
54 PluginGlobals::Get()->resource_reply_thread_registrar()->HandleOnIOThread( | 55 PluginGlobals::Get()->resource_reply_thread_registrar()->HandleOnIOThread( |
55 PpapiPluginMsg_UDPSocket_PushRecvResult::ID); | 56 PpapiPluginMsg_UDPSocket_PushRecvResult::ID); |
56 } | 57 } |
57 | 58 |
58 UDPSocketResourceBase::~UDPSocketResourceBase() { | 59 UDPSocketResourceBase::~UDPSocketResourceBase() { |
59 } | 60 } |
60 | 61 |
61 int32_t UDPSocketResourceBase::SetOptionImpl( | 62 int32_t UDPSocketResourceBase::SetOptionImpl( |
62 PP_UDPSocket_Option name, | 63 PP_UDPSocket_Option name, |
63 const PP_Var& value, | 64 const PP_Var& value, |
| 65 bool check_bind_state, |
64 scoped_refptr<TrackedCallback> callback) { | 66 scoped_refptr<TrackedCallback> callback) { |
65 if (closed_) | 67 if (closed_) |
66 return PP_ERROR_FAILED; | 68 return PP_ERROR_FAILED; |
67 | 69 |
68 SocketOptionData option_data; | 70 SocketOptionData option_data; |
69 switch (name) { | 71 switch (name) { |
70 case PP_UDPSOCKET_OPTION_ADDRESS_REUSE: | 72 case PP_UDPSOCKET_OPTION_ADDRESS_REUSE: |
71 case PP_UDPSOCKET_OPTION_BROADCAST: { | 73 case PP_UDPSOCKET_OPTION_BROADCAST: { |
72 if (bound_) | 74 if ((check_bind_state || name == PP_UDPSOCKET_OPTION_ADDRESS_REUSE) && |
| 75 bind_called_) { |
| 76 // SetOption should fail in this case in order to give predictable |
| 77 // behavior while binding. Note that we use |bind_called_| rather |
| 78 // than |bound_| since the latter is only set on successful completion |
| 79 // of Bind(). |
73 return PP_ERROR_FAILED; | 80 return PP_ERROR_FAILED; |
| 81 } |
74 if (value.type != PP_VARTYPE_BOOL) | 82 if (value.type != PP_VARTYPE_BOOL) |
75 return PP_ERROR_BADARGUMENT; | 83 return PP_ERROR_BADARGUMENT; |
76 option_data.SetBool(PP_ToBool(value.value.as_bool)); | 84 option_data.SetBool(PP_ToBool(value.value.as_bool)); |
77 break; | 85 break; |
78 } | 86 } |
79 case PP_UDPSOCKET_OPTION_SEND_BUFFER_SIZE: | 87 case PP_UDPSOCKET_OPTION_SEND_BUFFER_SIZE: |
80 case PP_UDPSOCKET_OPTION_RECV_BUFFER_SIZE: { | 88 case PP_UDPSOCKET_OPTION_RECV_BUFFER_SIZE: { |
81 if (!bound_) | 89 if (check_bind_state && !bound_) |
82 return PP_ERROR_FAILED; | 90 return PP_ERROR_FAILED; |
83 if (value.type != PP_VARTYPE_INT32) | 91 if (value.type != PP_VARTYPE_INT32) |
84 return PP_ERROR_BADARGUMENT; | 92 return PP_ERROR_BADARGUMENT; |
85 option_data.SetInt32(value.value.as_int); | 93 option_data.SetInt32(value.value.as_int); |
86 break; | 94 break; |
87 } | 95 } |
88 default: { | 96 default: { |
89 NOTREACHED(); | 97 NOTREACHED(); |
90 return PP_ERROR_BADARGUMENT; | 98 return PP_ERROR_BADARGUMENT; |
91 } | 99 } |
(...skipping 12 matching lines...) Expand all Loading... |
104 int32_t UDPSocketResourceBase::BindImpl( | 112 int32_t UDPSocketResourceBase::BindImpl( |
105 const PP_NetAddress_Private* addr, | 113 const PP_NetAddress_Private* addr, |
106 scoped_refptr<TrackedCallback> callback) { | 114 scoped_refptr<TrackedCallback> callback) { |
107 if (!addr) | 115 if (!addr) |
108 return PP_ERROR_BADARGUMENT; | 116 return PP_ERROR_BADARGUMENT; |
109 if (bound_ || closed_) | 117 if (bound_ || closed_) |
110 return PP_ERROR_FAILED; | 118 return PP_ERROR_FAILED; |
111 if (TrackedCallback::IsPending(bind_callback_)) | 119 if (TrackedCallback::IsPending(bind_callback_)) |
112 return PP_ERROR_INPROGRESS; | 120 return PP_ERROR_INPROGRESS; |
113 | 121 |
| 122 bind_called_ = true; |
114 bind_callback_ = callback; | 123 bind_callback_ = callback; |
115 | 124 |
116 // Send the request, the browser will call us back via BindReply. | 125 // Send the request, the browser will call us back via BindReply. |
117 Call<PpapiPluginMsg_UDPSocket_BindReply>( | 126 Call<PpapiPluginMsg_UDPSocket_BindReply>( |
118 BROWSER, | 127 BROWSER, |
119 PpapiHostMsg_UDPSocket_Bind(*addr), | 128 PpapiHostMsg_UDPSocket_Bind(*addr), |
120 base::Bind(&UDPSocketResourceBase::OnPluginMsgBindReply, | 129 base::Bind(&UDPSocketResourceBase::OnPluginMsgBindReply, |
121 base::Unretained(this)), | 130 base::Unretained(this)), |
122 callback); | 131 callback); |
123 return PP_OK_COMPLETIONPENDING; | 132 return PP_OK_COMPLETIONPENDING; |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
344 if (result == PP_OK && !data.empty()) | 353 if (result == PP_OK && !data.empty()) |
345 memcpy(output_buffer, data.c_str(), data.size()); | 354 memcpy(output_buffer, data.c_str(), data.size()); |
346 | 355 |
347 recvfrom_addr_ = addr; | 356 recvfrom_addr_ = addr; |
348 | 357 |
349 return result == PP_OK ? static_cast<int32_t>(data.size()) : result; | 358 return result == PP_OK ? static_cast<int32_t>(data.size()) : result; |
350 } | 359 } |
351 | 360 |
352 } // namespace proxy | 361 } // namespace proxy |
353 } // namespace ppapi | 362 } // namespace ppapi |
OLD | NEW |