Where Online Learning is simpler!
The C and C++ Include Header Files
cat -n /usr/include/nodejs/src/node_v8_platform-inl.h
1 #ifndef SRC_NODE_V8_PLATFORM_INL_H_ 2 #define SRC_NODE_V8_PLATFORM_INL_H_ 3 4 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 5 6 #include <memory> 7 #include <string_view> 8 9 #include "env-inl.h" 10 #include "node.h" 11 #include "node_metadata.h" 12 #include "node_platform.h" 13 #include "node_options.h" 14 #include "tracing/node_trace_writer.h" 15 #include "tracing/trace_event.h" 16 #include "tracing/traced_value.h" 17 #include "util.h" 18 19 namespace node { 20 21 // Ensures that __metadata trace events are only emitted 22 // when tracing is enabled. 23 class NodeTraceStateObserver 24 : public v8::TracingController::TraceStateObserver { 25 public: 26 inline void OnTraceEnabled() override { 27 std::string title = GetProcessTitle(""); 28 if (!title.empty()) { 29 // Only emit the metadata event if the title can be retrieved 30 // successfully. Ignore it otherwise. 31 TRACE_EVENT_METADATA1( 32 "__metadata", "process_name", "name", TRACE_STR_COPY(title.c_str())); 33 } 34 TRACE_EVENT_METADATA1("__metadata", 35 "version", 36 "node", 37 per_process::metadata.versions.node.c_str()); 38 TRACE_EVENT_METADATA1( 39 "__metadata", "thread_name", "name", "JavaScriptMainThread"); 40 41 tracing::ProcessMeta trace_process; 42 TRACE_EVENT_METADATA1("__metadata", 43 "node", 44 "process", 45 tracing::CastTracedValue(trace_process)); 46 // This only runs the first time tracing is enabled 47 controller_->RemoveTraceStateObserver(this); 48 } 49 50 inline void OnTraceDisabled() override { 51 // Do nothing here. This should never be called because the 52 // observer removes itself when OnTraceEnabled() is called. 53 UNREACHABLE(); 54 } 55 56 explicit NodeTraceStateObserver(v8::TracingController* controller) 57 : controller_(controller) {} 58 ~NodeTraceStateObserver() override = default; 59 60 private: 61 v8::TracingController* controller_; 62 }; 63 64 struct V8Platform { 65 bool initialized_ = false; 66 67 #if NODE_USE_V8_PLATFORM 68 inline void Initialize(int thread_pool_size) { 69 CHECK(!initialized_); 70 initialized_ = true; 71 tracing_agent_ = std::make_unique<tracing::Agent>(); 72 node::tracing::TraceEventHelper::SetAgent(tracing_agent_.get()); 73 node::tracing::TracingController* controller = 74 tracing_agent_->GetTracingController(); 75 trace_state_observer_ = 76 std::make_unique<NodeTraceStateObserver>(controller); 77 controller->AddTraceStateObserver(trace_state_observer_.get()); 78 tracing_file_writer_ = tracing_agent_->DefaultHandle(); 79 // Only start the tracing agent if we enabled any tracing categories. 80 if (!per_process::cli_options->trace_event_categories.empty()) { 81 StartTracingAgent(); 82 } 83 // Tracing must be initialized before platform threads are created. 84 platform_ = new NodePlatform(thread_pool_size, controller); 85 v8::V8::InitializePlatform(platform_); 86 } 87 // Make sure V8Platform don not call into Libuv threadpool, 88 // see DefaultProcessExitHandlerInternal in environment.cc 89 inline void Dispose() { 90 if (!initialized_) 91 return; 92 initialized_ = false; 93 node::tracing::TraceEventHelper::SetAgent(nullptr); 94 StopTracingAgent(); 95 platform_->Shutdown(); 96 delete platform_; 97 platform_ = nullptr; 98 // Destroy tracing after the platform (and platform threads) have been 99 // stopped. 100 tracing_agent_.reset(nullptr); 101 // The observer remove itself in OnTraceEnabled 102 trace_state_observer_.reset(nullptr); 103 } 104 105 inline void DrainVMTasks(v8::Isolate* isolate) { 106 platform_->DrainTasks(isolate); 107 } 108 109 inline void StartTracingAgent() { 110 constexpr auto convert_to_set = 111 [](std::vector<std::string_view> categories) -> std::set<std::string> { 112 std::set<std::string> out; 113 for (const auto& s : categories) { 114 out.emplace(s); 115 } 116 return out; 117 }; 118 // Attach a new NodeTraceWriter only if this function hasn't been called 119 // before. 120 if (tracing_file_writer_.IsDefaultHandle()) { 121 using std::string_view_literals::operator""sv; 122 const std::vector<std::string_view> categories = 123 SplitString(per_process::cli_options->trace_event_categories, ","sv); 124 125 tracing_file_writer_ = tracing_agent_->AddClient( 126 convert_to_set(categories), 127 std::unique_ptr<tracing::AsyncTraceWriter>( 128 new tracing::NodeTraceWriter( 129 per_process::cli_options->trace_event_file_pattern)), 130 tracing::Agent::kUseDefaultCategories); 131 } 132 } 133 134 inline void StopTracingAgent() { tracing_file_writer_.reset(); } 135 136 inline tracing::AgentWriterHandle* GetTracingAgentWriter() { 137 return &tracing_file_writer_; 138 } 139 140 inline NodePlatform* Platform() { return platform_; } 141 142 std::unique_ptr<NodeTraceStateObserver> trace_state_observer_; 143 std::unique_ptr<tracing::Agent> tracing_agent_; 144 tracing::AgentWriterHandle tracing_file_writer_; 145 NodePlatform* platform_; 146 #else // !NODE_USE_V8_PLATFORM 147 inline void Initialize(int thread_pool_size) {} 148 inline void Dispose() {} 149 inline void DrainVMTasks(v8::Isolate* isolate) {} 150 inline void StartTracingAgent() { 151 if (!per_process::cli_options->trace_event_categories.empty()) { 152 fprintf(stderr, 153 "Node compiled with NODE_USE_V8_PLATFORM=0, " 154 "so event tracing is not available.\n"); 155 } 156 } 157 inline void StopTracingAgent() {} 158 159 inline tracing::AgentWriterHandle* GetTracingAgentWriter() { return nullptr; } 160 161 inline NodePlatform* Platform() { return nullptr; } 162 #endif // !NODE_USE_V8_PLATFORM 163 }; 164 165 namespace per_process { 166 extern struct V8Platform v8_platform; 167 } 168 169 inline void StartTracingAgent() { 170 return per_process::v8_platform.StartTracingAgent(); 171 } 172 173 inline tracing::AgentWriterHandle* GetTracingAgentWriter() { 174 return per_process::v8_platform.GetTracingAgentWriter(); 175 } 176 177 inline void DisposePlatform() { 178 per_process::v8_platform.Dispose(); 179 } 180 181 } // namespace node 182 183 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS 184 185 #endif // SRC_NODE_V8_PLATFORM_INL_H_