1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_TEST_CHROMEDRIVER_NET_SYNC_WEBSOCKET_IMPL_H_
#define CHROME_TEST_CHROMEDRIVER_NET_SYNC_WEBSOCKET_IMPL_H_
#include <list>
#include <memory>
#include <string>
#include "base/functional/callback.h"
#include "base/memory/ref_counted.h"
#include "base/synchronization/condition_variable.h"
#include "base/synchronization/lock.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/sequenced_task_runner_helpers.h"
#include "base/task/single_thread_task_runner.h"
#include "chrome/test/chromedriver/net/sync_websocket.h"
#include "chrome/test/chromedriver/net/websocket.h"
namespace base {
class WaitableEvent;
}
namespace net {
class URLRequestContextGetter;
}
class GURL;
class SyncWebSocketImpl : public SyncWebSocket {
public:
explicit SyncWebSocketImpl(net::URLRequestContextGetter* context_getter);
~SyncWebSocketImpl() override;
void SetId(const std::string& socket_id) override {}
// Overridden from SyncWebSocket:
bool IsConnected() override;
bool Connect(const GURL& url) override;
bool Send(const std::string& message) override;
StatusCode ReceiveNextMessage(std::string* message,
const Timeout& timeout) override;
bool HasNextMessage() override;
// Set the callback to be executed if there any messages available.
// The callback is called in the thread where the socket was created.
// Sporadic calls of the callback are permitted.
void SetNotificationCallback(base::RepeatingClosure callback) override;
void SendNotification();
private:
struct CoreTraits;
class Core : public WebSocketListener,
public base::RefCountedThreadSafe<Core, CoreTraits> {
public:
explicit Core(net::URLRequestContextGetter* context_getter);
bool IsConnected();
bool Connect(const GURL& url);
bool Send(const std::string& message);
SyncWebSocket::StatusCode ReceiveNextMessage(
std::string* message,
const Timeout& timeout);
bool HasNextMessage();
// Overriden from WebSocketListener:
void OnMessageReceived(const std::string& message) override;
void OnClose() override;
void SetNotificationCallback(base::RepeatingClosure callback);
private:
friend class base::RefCountedThreadSafe<Core, CoreTraits>;
friend class base::DeleteHelper<Core>;
friend struct CoreTraits;
~Core() override;
void ConnectOnIO(const GURL& url,
bool* success,
base::WaitableEvent* event);
void OnConnectCompletedOnIO(bool* connected,
base::WaitableEvent* event,
int error);
void SendOnIO(const std::string& message,
bool* result,
base::WaitableEvent* event);
void CloseOnIO(base::WaitableEvent* event);
// Determines the intended recipients of the message received
void DetermineRecipient(const std::string& message,
bool* send_to_chromedriver);
// OnDestruct is meant to ensure deletion on the IO thread.
void OnDestruct() const;
scoped_refptr<net::URLRequestContextGetter> context_getter_;
// Only accessed on IO thread.
std::unique_ptr<WebSocket> socket_;
base::Lock lock_;
// Protected by |lock_|.
bool is_connected_;
// Protected by |lock_|.
std::list<std::string> received_queue_;
// Protected by |lock_|.
// Signaled when the socket closes or a message is received.
base::ConditionVariable on_update_event_;
// Protected by |lock_|.
// Notifies that the queue is not empty.
base::RepeatingClosure notify_;
// Sequence where the instance was created.
// The notifications about new data are emitted in this sequence.
scoped_refptr<base::SequencedTaskRunner> owning_sequence_;
};
scoped_refptr<Core> core_;
// Notifies that the queue is not empty.
// Always called in the owning sequence.
base::RepeatingClosure notify_;
// WeakPtrFactory must be the last member to be destroyed first.
// Then all the messages dispatched from the IO thread will be ignored
// after the instance end of life.
base::WeakPtrFactory<SyncWebSocketImpl> weak_factory_{this};
};
struct SyncWebSocketImpl::CoreTraits {
static void Destruct(const SyncWebSocketImpl::Core* core) {
core->OnDestruct();
}
};
#endif // CHROME_TEST_CHROMEDRIVER_NET_SYNC_WEBSOCKET_IMPL_H_
|