| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 <vector> | 5 #include <vector> |
| 6 | 6 |
| 7 #include "webkit/tools/test_shell/simple_socket_stream_bridge.h" | 7 #include "webkit/tools/test_shell/simple_socket_stream_bridge.h" |
| 8 | 8 |
| 9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
| 10 #include "base/ref_counted.h" | 10 #include "base/ref_counted.h" |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 | 51 |
| 52 // Runs on |g_io_thread|; | 52 // Runs on |g_io_thread|; |
| 53 void DoConnect(const GURL& url); | 53 void DoConnect(const GURL& url); |
| 54 void DoSend(std::vector<char>* data); | 54 void DoSend(std::vector<char>* data); |
| 55 void DoClose(); | 55 void DoClose(); |
| 56 | 56 |
| 57 // Runs on |message_loop_|; | 57 // Runs on |message_loop_|; |
| 58 void DoOnConnected(int max_amount_send_allowed); | 58 void DoOnConnected(int max_amount_send_allowed); |
| 59 void DoOnSentData(int amount_sent); | 59 void DoOnSentData(int amount_sent); |
| 60 void DoOnReceivedData(std::vector<char>* data); | 60 void DoOnReceivedData(std::vector<char>* data); |
| 61 void DoOnClose(webkit_glue::WebSocketStreamHandleDelegate* delegate); | 61 void DoOnClose(); |
| 62 | 62 |
| 63 int socket_id_; | 63 int socket_id_; |
| 64 MessageLoop* message_loop_; | 64 MessageLoop* message_loop_; |
| 65 WebKit::WebSocketStreamHandle* handle_; | 65 WebKit::WebSocketStreamHandle* handle_; |
| 66 webkit_glue::WebSocketStreamHandleDelegate* delegate_; | 66 webkit_glue::WebSocketStreamHandleDelegate* delegate_; |
| 67 | 67 |
| 68 scoped_refptr<net::SocketStream> socket_; | 68 scoped_refptr<net::SocketStream> socket_; |
| 69 // Number of pending tasks to handle net::SocketStream::Delegate methods. |
| 70 int num_pending_tasks_; |
| 69 | 71 |
| 70 DISALLOW_COPY_AND_ASSIGN(WebSocketStreamHandleBridgeImpl); | 72 DISALLOW_COPY_AND_ASSIGN(WebSocketStreamHandleBridgeImpl); |
| 71 }; | 73 }; |
| 72 | 74 |
| 73 WebSocketStreamHandleBridgeImpl::WebSocketStreamHandleBridgeImpl( | 75 WebSocketStreamHandleBridgeImpl::WebSocketStreamHandleBridgeImpl( |
| 74 WebKit::WebSocketStreamHandle* handle, | 76 WebKit::WebSocketStreamHandle* handle, |
| 75 webkit_glue::WebSocketStreamHandleDelegate* delegate) | 77 webkit_glue::WebSocketStreamHandleDelegate* delegate) |
| 76 : socket_id_(kNoSocketId), | 78 : socket_id_(kNoSocketId), |
| 77 message_loop_(MessageLoop::current()), | 79 message_loop_(MessageLoop::current()), |
| 78 handle_(handle), | 80 handle_(handle), |
| 79 delegate_(delegate) { | 81 delegate_(delegate), |
| 82 num_pending_tasks_(0) { |
| 80 } | 83 } |
| 81 | 84 |
| 82 WebSocketStreamHandleBridgeImpl::~WebSocketStreamHandleBridgeImpl() { | 85 WebSocketStreamHandleBridgeImpl::~WebSocketStreamHandleBridgeImpl() { |
| 83 CHECK(socket_id_ == kNoSocketId); | 86 DCHECK_EQ(socket_id_, kNoSocketId); |
| 84 } | 87 } |
| 85 | 88 |
| 86 void WebSocketStreamHandleBridgeImpl::Connect(const GURL& url) { | 89 void WebSocketStreamHandleBridgeImpl::Connect(const GURL& url) { |
| 87 CHECK(g_io_thread); | 90 DCHECK(g_io_thread); |
| 88 AddRef(); // Released in DoOnClose(). | 91 AddRef(); // Released in DoOnClose(). |
| 89 g_io_thread->PostTask( | 92 g_io_thread->PostTask( |
| 90 FROM_HERE, | 93 FROM_HERE, |
| 91 NewRunnableMethod(this, &WebSocketStreamHandleBridgeImpl::DoConnect, | 94 NewRunnableMethod(this, &WebSocketStreamHandleBridgeImpl::DoConnect, |
| 92 url)); | 95 url)); |
| 93 if (delegate_) | 96 if (delegate_) |
| 94 delegate_->WillOpenStream(handle_, url); | 97 delegate_->WillOpenStream(handle_, url); |
| 95 } | 98 } |
| 96 | 99 |
| 97 bool WebSocketStreamHandleBridgeImpl::Send( | 100 bool WebSocketStreamHandleBridgeImpl::Send( |
| 98 const std::vector<char>& data) { | 101 const std::vector<char>& data) { |
| 99 CHECK(g_io_thread); | 102 DCHECK(g_io_thread); |
| 100 g_io_thread->PostTask( | 103 g_io_thread->PostTask( |
| 101 FROM_HERE, | 104 FROM_HERE, |
| 102 NewRunnableMethod(this, &WebSocketStreamHandleBridgeImpl::DoSend, | 105 NewRunnableMethod(this, &WebSocketStreamHandleBridgeImpl::DoSend, |
| 103 new std::vector<char>(data))); | 106 new std::vector<char>(data))); |
| 104 return true; | 107 return true; |
| 105 } | 108 } |
| 106 | 109 |
| 107 void WebSocketStreamHandleBridgeImpl::Close() { | 110 void WebSocketStreamHandleBridgeImpl::Close() { |
| 108 CHECK(g_io_thread); | 111 DCHECK(g_io_thread); |
| 109 g_io_thread->PostTask( | 112 g_io_thread->PostTask( |
| 110 FROM_HERE, | 113 FROM_HERE, |
| 111 NewRunnableMethod(this, &WebSocketStreamHandleBridgeImpl::DoClose)); | 114 NewRunnableMethod(this, &WebSocketStreamHandleBridgeImpl::DoClose)); |
| 112 } | 115 } |
| 113 | 116 |
| 114 void WebSocketStreamHandleBridgeImpl::OnConnected( | 117 void WebSocketStreamHandleBridgeImpl::OnConnected( |
| 115 net::SocketStream* socket, int max_pending_send_allowed) { | 118 net::SocketStream* socket, int max_pending_send_allowed) { |
| 119 ++num_pending_tasks_; |
| 116 message_loop_->PostTask( | 120 message_loop_->PostTask( |
| 117 FROM_HERE, | 121 FROM_HERE, |
| 118 NewRunnableMethod(this, &WebSocketStreamHandleBridgeImpl::DoOnConnected, | 122 NewRunnableMethod(this, &WebSocketStreamHandleBridgeImpl::DoOnConnected, |
| 119 max_pending_send_allowed)); | 123 max_pending_send_allowed)); |
| 120 } | 124 } |
| 121 | 125 |
| 122 void WebSocketStreamHandleBridgeImpl::OnSentData( | 126 void WebSocketStreamHandleBridgeImpl::OnSentData( |
| 123 net::SocketStream* socket, int amount_sent) { | 127 net::SocketStream* socket, int amount_sent) { |
| 128 ++num_pending_tasks_; |
| 124 message_loop_->PostTask( | 129 message_loop_->PostTask( |
| 125 FROM_HERE, | 130 FROM_HERE, |
| 126 NewRunnableMethod(this, &WebSocketStreamHandleBridgeImpl::DoOnSentData, | 131 NewRunnableMethod(this, &WebSocketStreamHandleBridgeImpl::DoOnSentData, |
| 127 amount_sent)); | 132 amount_sent)); |
| 128 } | 133 } |
| 129 | 134 |
| 130 void WebSocketStreamHandleBridgeImpl::OnReceivedData( | 135 void WebSocketStreamHandleBridgeImpl::OnReceivedData( |
| 131 net::SocketStream* socket, const char* data, int len) { | 136 net::SocketStream* socket, const char* data, int len) { |
| 137 ++num_pending_tasks_; |
| 132 message_loop_->PostTask( | 138 message_loop_->PostTask( |
| 133 FROM_HERE, | 139 FROM_HERE, |
| 134 NewRunnableMethod(this, | 140 NewRunnableMethod(this, |
| 135 &WebSocketStreamHandleBridgeImpl::DoOnReceivedData, | 141 &WebSocketStreamHandleBridgeImpl::DoOnReceivedData, |
| 136 new std::vector<char>(data, data + len))); | 142 new std::vector<char>(data, data + len))); |
| 137 } | 143 } |
| 138 | 144 |
| 139 void WebSocketStreamHandleBridgeImpl::OnClose(net::SocketStream* socket) { | 145 void WebSocketStreamHandleBridgeImpl::OnClose(net::SocketStream* socket) { |
| 140 webkit_glue::WebSocketStreamHandleDelegate* delegate = delegate_; | 146 ++num_pending_tasks_; |
| 141 delegate_ = NULL; | 147 // Release socket_ on IO thread. |
| 142 socket_ = 0; | 148 socket_ = NULL; |
| 143 socket_id_ = kNoSocketId; | 149 socket_id_ = kNoSocketId; |
| 144 message_loop_->PostTask( | 150 message_loop_->PostTask( |
| 145 FROM_HERE, | 151 FROM_HERE, |
| 146 NewRunnableMethod(this, &WebSocketStreamHandleBridgeImpl::DoOnClose, | 152 NewRunnableMethod(this, &WebSocketStreamHandleBridgeImpl::DoOnClose)); |
| 147 delegate)); | |
| 148 } | 153 } |
| 149 | 154 |
| 150 void WebSocketStreamHandleBridgeImpl::DoConnect(const GURL& url) { | 155 void WebSocketStreamHandleBridgeImpl::DoConnect(const GURL& url) { |
| 151 CHECK(MessageLoop::current() == g_io_thread); | 156 DCHECK(MessageLoop::current() == g_io_thread); |
| 152 socket_ = new net::SocketStream(url, this); | 157 socket_ = new net::SocketStream(url, this); |
| 153 socket_->set_context(g_request_context); | 158 socket_->set_context(g_request_context); |
| 154 socket_->Connect(); | 159 socket_->Connect(); |
| 155 } | 160 } |
| 156 | 161 |
| 157 void WebSocketStreamHandleBridgeImpl::DoSend(std::vector<char>* data) { | 162 void WebSocketStreamHandleBridgeImpl::DoSend(std::vector<char>* data) { |
| 158 CHECK(MessageLoop::current() == g_io_thread); | 163 DCHECK(MessageLoop::current() == g_io_thread); |
| 159 scoped_ptr<std::vector<char> > scoped_data(data); | 164 scoped_ptr<std::vector<char> > scoped_data(data); |
| 160 if (!socket_) | 165 if (!socket_) |
| 161 return; | 166 return; |
| 162 if (!socket_->SendData(&(data->at(0)), data->size())) | 167 if (!socket_->SendData(&(data->at(0)), data->size())) |
| 163 socket_->Close(); | 168 socket_->Close(); |
| 164 } | 169 } |
| 165 | 170 |
| 166 void WebSocketStreamHandleBridgeImpl::DoClose() { | 171 void WebSocketStreamHandleBridgeImpl::DoClose() { |
| 167 CHECK(MessageLoop::current() == g_io_thread); | 172 DCHECK(MessageLoop::current() == g_io_thread); |
| 168 if (!socket_) | 173 if (!socket_) |
| 169 return; | 174 return; |
| 170 socket_->Close(); | 175 socket_->Close(); |
| 171 } | 176 } |
| 172 | 177 |
| 173 void WebSocketStreamHandleBridgeImpl::DoOnConnected( | 178 void WebSocketStreamHandleBridgeImpl::DoOnConnected( |
| 174 int max_pending_send_allowed) { | 179 int max_pending_send_allowed) { |
| 175 CHECK(MessageLoop::current() == message_loop_); | 180 DCHECK(MessageLoop::current() == message_loop_); |
| 181 --num_pending_tasks_; |
| 176 if (delegate_) | 182 if (delegate_) |
| 177 delegate_->DidOpenStream(handle_, max_pending_send_allowed); | 183 delegate_->DidOpenStream(handle_, max_pending_send_allowed); |
| 178 } | 184 } |
| 179 | 185 |
| 180 void WebSocketStreamHandleBridgeImpl::DoOnSentData(int amount_sent) { | 186 void WebSocketStreamHandleBridgeImpl::DoOnSentData(int amount_sent) { |
| 181 CHECK(MessageLoop::current() == message_loop_); | 187 DCHECK(MessageLoop::current() == message_loop_); |
| 188 --num_pending_tasks_; |
| 182 if (delegate_) | 189 if (delegate_) |
| 183 delegate_->DidSendData(handle_, amount_sent); | 190 delegate_->DidSendData(handle_, amount_sent); |
| 184 } | 191 } |
| 185 | 192 |
| 186 void WebSocketStreamHandleBridgeImpl::DoOnReceivedData( | 193 void WebSocketStreamHandleBridgeImpl::DoOnReceivedData( |
| 187 std::vector<char>* data) { | 194 std::vector<char>* data) { |
| 188 CHECK(MessageLoop::current() == message_loop_); | 195 DCHECK(MessageLoop::current() == message_loop_); |
| 196 --num_pending_tasks_; |
| 189 scoped_ptr<std::vector<char> > scoped_data(data); | 197 scoped_ptr<std::vector<char> > scoped_data(data); |
| 190 if (delegate_) | 198 if (delegate_) |
| 191 delegate_->DidReceiveData(handle_, &(data->at(0)), data->size()); | 199 delegate_->DidReceiveData(handle_, &(data->at(0)), data->size()); |
| 192 } | 200 } |
| 193 | 201 |
| 194 void WebSocketStreamHandleBridgeImpl::DoOnClose( | 202 void WebSocketStreamHandleBridgeImpl::DoOnClose() { |
| 195 webkit_glue::WebSocketStreamHandleDelegate* delegate) { | 203 DCHECK(MessageLoop::current() == message_loop_); |
| 196 CHECK(MessageLoop::current() == message_loop_); | 204 --num_pending_tasks_; |
| 197 CHECK(!socket_); | 205 // Don't handle OnClose if there are pending tasks. |
| 206 DCHECK_EQ(num_pending_tasks_, 0); |
| 207 DCHECK(!socket_); |
| 208 DCHECK_EQ(socket_id_, kNoSocketId); |
| 209 webkit_glue::WebSocketStreamHandleDelegate* delegate = delegate_; |
| 210 delegate_ = NULL; |
| 198 if (delegate) | 211 if (delegate) |
| 199 delegate->DidClose(handle_); | 212 delegate->DidClose(handle_); |
| 200 Release(); | 213 Release(); |
| 201 } | 214 } |
| 202 | 215 |
| 203 } // namespace | 216 } // namespace |
| 204 | 217 |
| 205 /* static */ | 218 /* static */ |
| 206 void SimpleSocketStreamBridge::InitializeOnIOThread( | 219 void SimpleSocketStreamBridge::InitializeOnIOThread( |
| 207 URLRequestContext* request_context) { | 220 URLRequestContext* request_context) { |
| 208 g_io_thread = MessageLoop::current(); | 221 g_io_thread = MessageLoop::current(); |
| 209 g_request_context = request_context; | 222 g_request_context = request_context; |
| 210 } | 223 } |
| 211 | 224 |
| 212 void SimpleSocketStreamBridge::Cleanup() { | 225 void SimpleSocketStreamBridge::Cleanup() { |
| 213 g_io_thread = NULL; | 226 g_io_thread = NULL; |
| 214 g_request_context = NULL; | 227 g_request_context = NULL; |
| 215 } | 228 } |
| 216 | 229 |
| 217 namespace webkit_glue { | 230 namespace webkit_glue { |
| 218 | 231 |
| 219 /* static */ | 232 /* static */ |
| 220 WebSocketStreamHandleBridge* WebSocketStreamHandleBridge::Create( | 233 WebSocketStreamHandleBridge* WebSocketStreamHandleBridge::Create( |
| 221 WebKit::WebSocketStreamHandle* handle, | 234 WebKit::WebSocketStreamHandle* handle, |
| 222 WebSocketStreamHandleDelegate* delegate) { | 235 WebSocketStreamHandleDelegate* delegate) { |
| 223 return new WebSocketStreamHandleBridgeImpl(handle, delegate); | 236 return new WebSocketStreamHandleBridgeImpl(handle, delegate); |
| 224 } | 237 } |
| 225 | 238 |
| 226 } // namespace webkit_glue | 239 } // namespace webkit_glue |
| OLD | NEW |