12 : tracing_loop_(tracing_loop) {
13 flush_signal_.data =
this;
14 int err = uv_async_init(tracing_loop_, &flush_signal_, FlushSignalCb);
17 exit_signal_.data =
this;
18 err = uv_async_init(tracing_loop_, &exit_signal_, ExitSignalCb);
22 void NodeTraceWriter::WriteSuffix() {
26 bool should_flush =
false;
28 Mutex::ScopedLock scoped_lock(stream_mutex_);
29 if (total_traces_ > 0) {
32 delete json_trace_writer_;
46 err = uv_fs_close(tracing_loop_, &req, fd_,
nullptr);
48 uv_fs_req_cleanup(&req);
50 uv_async_send(&exit_signal_);
51 Mutex::ScopedLock scoped_lock(request_mutex_);
53 exit_cond_.
Wait(scoped_lock);
57 void NodeTraceWriter::OpenNewFileForStreaming() {
60 std::ostringstream log_file;
61 log_file <<
"node_trace." << file_num_ <<
".log";
62 fd_ = uv_fs_open(tracing_loop_, &req, log_file.str().c_str(),
63 O_CREAT | O_WRONLY | O_TRUNC, 0644, NULL);
65 uv_fs_req_cleanup(&req);
69 Mutex::ScopedLock scoped_lock(stream_mutex_);
71 if (total_traces_ == 0) {
72 OpenNewFileForStreaming();
79 json_trace_writer_ = TraceWriter::CreateJSONTraceWriter(stream_);
82 json_trace_writer_->AppendTraceEvent(trace_event);
85 void NodeTraceWriter::FlushPrivate() {
87 int highest_request_id;
89 Mutex::ScopedLock stream_scoped_lock(stream_mutex_);
94 delete json_trace_writer_;
102 Mutex::ScopedLock request_scoped_lock(request_mutex_);
103 highest_request_id = num_write_requests_;
105 WriteToFile(std::move(str), highest_request_id);
108 void NodeTraceWriter::FlushSignalCb(uv_async_t* signal) {
110 trace_writer->FlushPrivate();
120 Mutex::ScopedLock scoped_lock(request_mutex_);
121 if (!json_trace_writer_) {
124 int request_id = ++num_write_requests_;
125 int err = uv_async_send(&flush_signal_);
131 while (request_id > highest_request_id_completed_) {
132 request_cond_.
Wait(scoped_lock);
137 void NodeTraceWriter::WriteToFile(std::string&& str,
int highest_request_id) {
138 WriteRequest* write_req =
new WriteRequest();
139 write_req->str = std::move(str);
140 write_req->writer =
this;
141 write_req->highest_request_id = highest_request_id;
142 uv_buf_t uv_buf = uv_buf_init(const_cast<char*>(write_req->str.c_str()),
143 write_req->str.length());
144 request_mutex_.
Lock();
149 write_req_queue_.push(write_req);
151 int err = uv_fs_write(tracing_loop_, reinterpret_cast<uv_fs_t*>(write_req),
152 fd_, &uv_buf, 1, -1, WriteCb);
156 void NodeTraceWriter::WriteCb(uv_fs_t*
req) {
157 WriteRequest* write_req =
reinterpret_cast<WriteRequest*
>(
req);
158 CHECK_GE(write_req->req.result, 0);
161 int highest_request_id = write_req->highest_request_id;
163 Mutex::ScopedLock scoped_lock(writer->request_mutex_);
164 CHECK_EQ(write_req, writer->write_req_queue_.front());
165 writer->write_req_queue_.pop();
166 writer->highest_request_id_completed_ = highest_request_id;
167 writer->request_cond_.
Broadcast(scoped_lock);
173 void NodeTraceWriter::ExitSignalCb(uv_async_t* signal) {
175 uv_close(reinterpret_cast<uv_handle_t*>(&trace_writer->flush_signal_),
177 uv_close(reinterpret_cast<uv_handle_t*>(&trace_writer->exit_signal_),
178 [](uv_handle_t* signal) {
179 NodeTraceWriter* trace_writer =
180 static_cast<NodeTraceWriter*>(signal->data);
181 Mutex::ScopedLock scoped_lock(trace_writer->request_mutex_);
182 trace_writer->exited_ = true;
183 trace_writer->exit_cond_.Signal(scoped_lock);
void AppendTraceEvent(TraceObject *trace_event) override
void Broadcast(const ScopedLock &)
void Wait(const ScopedLock &scoped_lock)
static const int kTracesPerFile
NodeTraceWriter(uv_loop_t *tracing_loop)