Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 "chrome/test/chromedriver/net/sync_websocket_impl.h" | 5 #include "chrome/test/chromedriver/net/sync_websocket_impl.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/callback.h" | 8 #include "base/callback.h" |
| 9 #include "base/location.h" | 9 #include "base/location.h" |
| 10 #include "base/single_thread_task_runner.h" | 10 #include "base/single_thread_task_runner.h" |
| 11 #include "base/synchronization/waitable_event.h" | 11 #include "base/synchronization/waitable_event.h" |
| 12 #include "googleurl/src/gurl.h" | 12 #include "googleurl/src/gurl.h" |
| 13 #include "net/base/net_errors.h" | 13 #include "net/base/net_errors.h" |
| 14 #include "net/url_request/url_request_context_getter.h" | 14 #include "net/url_request/url_request_context_getter.h" |
| 15 | 15 |
| 16 SyncWebSocketImpl::SyncWebSocketImpl( | 16 SyncWebSocketImpl::SyncWebSocketImpl( |
| 17 net::URLRequestContextGetter* context_getter) | 17 net::URLRequestContextGetter* context_getter) |
| 18 : core_(new Core(context_getter)) {} | 18 : core_(new Core(context_getter)) {} |
| 19 | 19 |
| 20 SyncWebSocketImpl::~SyncWebSocketImpl() {} | 20 SyncWebSocketImpl::~SyncWebSocketImpl() {} |
| 21 | 21 |
| 22 bool SyncWebSocketImpl::IsConnected() { | |
| 23 return core_->IsConnected(); | |
| 24 } | |
| 25 | |
| 22 bool SyncWebSocketImpl::Connect(const GURL& url) { | 26 bool SyncWebSocketImpl::Connect(const GURL& url) { |
| 23 return core_->Connect(url); | 27 return core_->Connect(url); |
| 24 } | 28 } |
| 25 | 29 |
| 26 bool SyncWebSocketImpl::Send(const std::string& message) { | 30 bool SyncWebSocketImpl::Send(const std::string& message) { |
| 27 return core_->Send(message); | 31 return core_->Send(message); |
| 28 } | 32 } |
| 29 | 33 |
| 30 bool SyncWebSocketImpl::ReceiveNextMessage(std::string* message) { | 34 bool SyncWebSocketImpl::ReceiveNextMessage(std::string* message) { |
| 31 return core_->ReceiveNextMessage(message); | 35 return core_->ReceiveNextMessage(message); |
| 32 } | 36 } |
| 33 | 37 |
| 34 bool SyncWebSocketImpl::HasNextMessage() { | 38 bool SyncWebSocketImpl::HasNextMessage() { |
| 35 return core_->HasNextMessage(); | 39 return core_->HasNextMessage(); |
| 36 } | 40 } |
| 37 | 41 |
| 38 SyncWebSocketImpl::Core::Core(net::URLRequestContextGetter* context_getter) | 42 SyncWebSocketImpl::Core::Core(net::URLRequestContextGetter* context_getter) |
| 39 : context_getter_(context_getter), | 43 : context_getter_(context_getter), |
| 40 closed_(false), | 44 open_(false), |
| 41 on_update_event_(&lock_) {} | 45 on_update_event_(&lock_) {} |
| 42 | 46 |
| 47 bool SyncWebSocketImpl::Core::IsConnected() { | |
| 48 base::AutoLock lock(lock_); | |
| 49 return open_; | |
| 50 } | |
| 51 | |
| 43 bool SyncWebSocketImpl::Core::Connect(const GURL& url) { | 52 bool SyncWebSocketImpl::Core::Connect(const GURL& url) { |
| 44 bool success = false; | 53 bool success = false; |
| 45 base::WaitableEvent event(false, false); | 54 base::WaitableEvent event(false, false); |
| 46 context_getter_->GetNetworkTaskRunner()->PostTask( | 55 context_getter_->GetNetworkTaskRunner()->PostTask( |
| 47 FROM_HERE, | 56 FROM_HERE, |
| 48 base::Bind(&SyncWebSocketImpl::Core::ConnectOnIO, | 57 base::Bind(&SyncWebSocketImpl::Core::ConnectOnIO, |
| 49 this, url, &success, &event)); | 58 this, url, &success, &event)); |
| 50 event.Wait(); | 59 event.Wait(); |
| 51 return success; | 60 return success; |
| 52 } | 61 } |
| 53 | 62 |
| 54 bool SyncWebSocketImpl::Core::Send(const std::string& message) { | 63 bool SyncWebSocketImpl::Core::Send(const std::string& message) { |
| 55 bool success = false; | 64 bool success = false; |
| 56 base::WaitableEvent event(false, false); | 65 base::WaitableEvent event(false, false); |
| 57 context_getter_->GetNetworkTaskRunner()->PostTask( | 66 context_getter_->GetNetworkTaskRunner()->PostTask( |
| 58 FROM_HERE, | 67 FROM_HERE, |
| 59 base::Bind(&SyncWebSocketImpl::Core::SendOnIO, | 68 base::Bind(&SyncWebSocketImpl::Core::SendOnIO, |
| 60 this, message, &success, &event)); | 69 this, message, &success, &event)); |
| 61 event.Wait(); | 70 event.Wait(); |
| 62 return success; | 71 return success; |
| 63 } | 72 } |
| 64 | 73 |
| 65 bool SyncWebSocketImpl::Core::ReceiveNextMessage(std::string* message) { | 74 bool SyncWebSocketImpl::Core::ReceiveNextMessage(std::string* message) { |
| 66 base::AutoLock lock(lock_); | 75 base::AutoLock lock(lock_); |
| 67 while (received_queue_.empty() && !closed_) on_update_event_.Wait(); | 76 while (received_queue_.empty() && open_) on_update_event_.Wait(); |
| 68 if (closed_) | 77 if (!open_) |
| 69 return false; | 78 return false; |
| 70 *message = received_queue_.front(); | 79 *message = received_queue_.front(); |
| 71 received_queue_.pop_front(); | 80 received_queue_.pop_front(); |
| 72 return true; | 81 return true; |
| 73 } | 82 } |
| 74 | 83 |
| 75 bool SyncWebSocketImpl::Core::HasNextMessage() { | 84 bool SyncWebSocketImpl::Core::HasNextMessage() { |
| 76 base::AutoLock lock(lock_); | 85 base::AutoLock lock(lock_); |
| 77 return !received_queue_.empty(); | 86 return !received_queue_.empty(); |
| 78 } | 87 } |
| 79 | 88 |
| 80 void SyncWebSocketImpl::Core::OnMessageReceived(const std::string& message) { | 89 void SyncWebSocketImpl::Core::OnMessageReceived(const std::string& message) { |
| 81 base::AutoLock lock(lock_); | 90 base::AutoLock lock(lock_); |
| 82 received_queue_.push_back(message); | 91 received_queue_.push_back(message); |
| 83 on_update_event_.Signal(); | 92 on_update_event_.Signal(); |
| 84 } | 93 } |
| 85 | 94 |
| 86 void SyncWebSocketImpl::Core::OnClose() { | 95 void SyncWebSocketImpl::Core::OnClose() { |
| 87 base::AutoLock lock(lock_); | 96 base::AutoLock lock(lock_); |
| 88 closed_ = true; | 97 open_ = false; |
| 89 on_update_event_.Signal(); | 98 on_update_event_.Signal(); |
| 90 } | 99 } |
| 91 | 100 |
| 92 SyncWebSocketImpl::Core::~Core() { } | 101 SyncWebSocketImpl::Core::~Core() { } |
| 93 | 102 |
| 94 void SyncWebSocketImpl::Core::ConnectOnIO( | 103 void SyncWebSocketImpl::Core::ConnectOnIO( |
| 95 const GURL& url, | 104 const GURL& url, |
| 96 bool* success, | 105 bool* success, |
| 97 base::WaitableEvent* event) { | 106 base::WaitableEvent* event) { |
| 107 base::AutoLock lock(lock_); | |
|
kkania
2013/03/04 23:33:57
unlock after the queue is cleared, in case WebSock
chrisgao (Use stgao instead)
2013/03/05 06:58:17
Done.
| |
| 108 received_queue_.clear(); | |
| 98 socket_.reset(new WebSocket(context_getter_, url, this)); | 109 socket_.reset(new WebSocket(context_getter_, url, this)); |
| 99 socket_->Connect(base::Bind( | 110 socket_->Connect(base::Bind( |
| 100 &SyncWebSocketImpl::Core::OnConnectCompletedOnIO, | 111 &SyncWebSocketImpl::Core::OnConnectCompletedOnIO, |
| 101 this, success, event)); | 112 this, success, event)); |
| 102 } | 113 } |
| 103 | 114 |
| 104 void SyncWebSocketImpl::Core::OnConnectCompletedOnIO( | 115 void SyncWebSocketImpl::Core::OnConnectCompletedOnIO( |
| 105 bool* success, | 116 bool* success, |
| 106 base::WaitableEvent* event, | 117 base::WaitableEvent* event, |
| 107 int error) { | 118 int error) { |
| 108 *success = (error == net::OK); | 119 *success = (error == net::OK); |
| 120 if (*success) { | |
| 121 base::AutoLock lock(lock_); | |
| 122 open_ = true; | |
| 123 } | |
| 109 event->Signal(); | 124 event->Signal(); |
| 110 } | 125 } |
| 111 | 126 |
| 112 void SyncWebSocketImpl::Core::SendOnIO( | 127 void SyncWebSocketImpl::Core::SendOnIO( |
| 113 const std::string& message, | 128 const std::string& message, |
| 114 bool* success, | 129 bool* success, |
| 115 base::WaitableEvent* event) { | 130 base::WaitableEvent* event) { |
| 116 *success = socket_->Send(message); | 131 *success = socket_->Send(message); |
| 117 event->Signal(); | 132 event->Signal(); |
| 118 } | 133 } |
| 119 | 134 |
| 120 void SyncWebSocketImpl::Core::OnDestruct() const { | 135 void SyncWebSocketImpl::Core::OnDestruct() const { |
| 121 scoped_refptr<base::SingleThreadTaskRunner> network_task_runner = | 136 scoped_refptr<base::SingleThreadTaskRunner> network_task_runner = |
| 122 context_getter_->GetNetworkTaskRunner(); | 137 context_getter_->GetNetworkTaskRunner(); |
| 123 if (network_task_runner->BelongsToCurrentThread()) | 138 if (network_task_runner->BelongsToCurrentThread()) |
| 124 delete this; | 139 delete this; |
| 125 else | 140 else |
| 126 network_task_runner->DeleteSoon(FROM_HERE, this); | 141 network_task_runner->DeleteSoon(FROM_HERE, this); |
| 127 } | 142 } |
| OLD | NEW |