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