GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage/nodes/benchmark/out/../src/inspector_io.h Lines: 8 8 100.0 %
Date: 2017-10-21 Branches: 0 0 0.0 %

Line Branch Exec Source
1
#ifndef SRC_INSPECTOR_IO_H_
2
#define SRC_INSPECTOR_IO_H_
3
4
#include "inspector_socket_server.h"
5
#include "node_debug_options.h"
6
#include "node_mutex.h"
7
#include "uv.h"
8
9
#include <deque>
10
#include <memory>
11
#include <stddef.h>
12
13
#if !HAVE_INSPECTOR
14
#error("This header can only be used when inspector is enabled")
15
#endif
16
17
18
// Forward declaration to break recursive dependency chain with src/env.h.
19
namespace node {
20
class Environment;
21
}  // namespace node
22
23
namespace v8_inspector {
24
class StringBuffer;
25
class StringView;
26
}  // namespace v8_inspector
27
28
namespace node {
29
namespace inspector {
30
31
std::string FormatWsAddress(const std::string& host, int port,
32
                            const std::string& target_id,
33
                            bool include_protocol);
34
35
class InspectorIoDelegate;
36
37
enum class InspectorAction {
38
  kStartSession,
39
  kEndSession,
40
  kSendMessage
41
};
42
43
// kKill closes connections and stops the server, kStop only stops the server
44
enum class TransportAction {
45
  kKill,
46
  kSendMessage,
47
  kStop
48
};
49
50
class InspectorIo {
51
 public:
52
  InspectorIo(node::Environment* env, v8::Platform* platform,
53
              const std::string& path, const DebugOptions& options,
54
              bool wait_for_connect);
55
56
  ~InspectorIo();
57
  // Start the inspector agent thread, waiting for it to initialize,
58
  // and waiting as well for a connection if wait_for_connect.
59
  bool Start();
60
  // Stop the inspector agent thread.
61
  void Stop();
62
63
  bool IsStarted();
64
  bool IsConnected();
65
66
  void WaitForDisconnect();
67
  // Called from thread to queue an incoming message and trigger
68
  // DispatchMessages() on the main thread.
69
  void PostIncomingMessage(InspectorAction action, int session_id,
70
                           const std::string& message);
71
8
  void ResumeStartup() {
72
8
    uv_sem_post(&thread_start_sem_);
73
8
  }
74
14
  void ServerDone() {
75
14
    uv_close(reinterpret_cast<uv_handle_t*>(&thread_req_), nullptr);
76
14
  }
77
78
20
  int port() const { return port_; }
79
3
  std::string host() const { return options_.host_name(); }
80
  std::vector<std::string> GetTargetIds() const;
81
82
 private:
83
  template <typename Action>
84
  using MessageQueue =
85
      std::deque<std::tuple<Action, int,
86
                  std::unique_ptr<v8_inspector::StringBuffer>>>;
87
  enum class State {
88
    kNew,
89
    kAccepting,
90
    kConnected,
91
    kDone,
92
    kError,
93
    kShutDown
94
  };
95
96
  // Callback for main_thread_req_'s uv_async_t
97
  static void MainThreadReqAsyncCb(uv_async_t* req);
98
99
  // Wrapper for agent->ThreadMain()
100
  static void ThreadMain(void* agent);
101
102
  // Runs a uv_loop_t
103
  template <typename Transport> void ThreadMain();
104
  // Called by ThreadMain's loop when triggered by thread_req_, writes
105
  // messages from outgoing_message_queue to the InspectorSockerServer
106
  template <typename Transport> static void IoThreadAsyncCb(uv_async_t* async);
107
108
  void SetConnected(bool connected);
109
  void DispatchMessages();
110
  // Write action to outgoing_message_queue, and wake the thread
111
  void Write(TransportAction action, int session_id,
112
             const v8_inspector::StringView& message);
113
  // Thread-safe append of message to a queue. Return true if the queue
114
  // used to be empty.
115
  template <typename ActionType>
116
  bool AppendMessage(MessageQueue<ActionType>* vector, ActionType action,
117
                     int session_id,
118
                     std::unique_ptr<v8_inspector::StringBuffer> buffer);
119
  // Used as equivalent of a thread-safe "pop" of an entire queue's content.
120
  template <typename ActionType>
121
  void SwapBehindLock(MessageQueue<ActionType>* vector1,
122
                      MessageQueue<ActionType>* vector2);
123
  // Wait on incoming_message_cond_
124
  void WaitForFrontendMessageWhilePaused();
125
  // Broadcast incoming_message_cond_
126
  void NotifyMessageReceived();
127
128
  const DebugOptions options_;
129
130
  // The IO thread runs its own uv_loop to implement the TCP server off
131
  // the main thread.
132
  uv_thread_t thread_;
133
  // Used by Start() to wait for thread to initialize, or for it to initialize
134
  // and receive a connection if wait_for_connect was requested.
135
  uv_sem_t thread_start_sem_;
136
137
  InspectorIoDelegate* delegate_;
138
  State state_;
139
  node::Environment* parent_env_;
140
141
  // Attached to the uv_loop in ThreadMain()
142
  uv_async_t thread_req_;
143
  // Note that this will live while the async is being closed - likely, past
144
  // the parent object lifespan
145
  std::pair<uv_async_t, Agent*>* main_thread_req_;
146
  std::unique_ptr<InspectorSessionDelegate> session_delegate_;
147
  v8::Platform* platform_;
148
149
  // Message queues
150
  ConditionVariable incoming_message_cond_;
151
  Mutex state_lock_;  // Locked before mutating either queue.
152
  MessageQueue<InspectorAction> incoming_message_queue_;
153
  MessageQueue<TransportAction> outgoing_message_queue_;
154
  MessageQueue<InspectorAction> dispatching_message_queue_;
155
156
  bool dispatching_messages_;
157
  int session_id_;
158
159
  std::string script_name_;
160
  std::string script_path_;
161
  const bool wait_for_connect_;
162
  int port_;
163
164
  friend class DispatchMessagesTask;
165
  friend class IoSessionDelegate;
166
  friend void InterruptCallback(v8::Isolate*, void* agent);
167
};
168
169
std::unique_ptr<v8_inspector::StringBuffer> Utf8ToStringView(
170
    const std::string& message);
171
172
}  // namespace inspector
173
}  // namespace node
174
175
#endif  // SRC_INSPECTOR_IO_H_