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 |