@@ -158,38 +158,57 @@ void NodeTraceWriter::Flush(bool blocking) {
158158
159159void NodeTraceWriter::WriteToFile (std::string&& str, int highest_request_id) {
160160 if (fd_ == -1 ) return ;
161- WriteRequest* write_req = new WriteRequest ();
162- write_req->str = std::move (str);
163- write_req->writer = this ;
164- write_req->highest_request_id = highest_request_id;
165- uv_buf_t uv_buf = uv_buf_init (const_cast <char *>(write_req->str .c_str ()),
166- write_req->str .length ());
167- request_mutex_.Lock ();
168- // Manage a queue of WriteRequest objects because the behavior of uv_write is
169- // undefined if the same WriteRequest object is used more than once
170- // between WriteCb calls. In addition, this allows us to keep track of the id
171- // of the latest write request that actually been completed.
172- write_req_queue_.push (write_req);
173- request_mutex_.Unlock ();
174- int err = uv_fs_write (tracing_loop_, reinterpret_cast <uv_fs_t *>(write_req),
175- fd_, &uv_buf, 1 , -1 , WriteCb);
161+
162+ uv_buf_t buf = uv_buf_init (nullptr , 0 );
163+ {
164+ Mutex::ScopedLock lock (request_mutex_);
165+ write_req_queue_.emplace (WriteRequest {
166+ std::move (str), highest_request_id
167+ });
168+ if (write_req_queue_.size () == 1 ) {
169+ buf = uv_buf_init (
170+ const_cast <char *>(write_req_queue_.front ().str .c_str ()),
171+ write_req_queue_.front ().str .length ());
172+ }
173+ }
174+ // Only one write request for the same file descriptor should be active at
175+ // a time.
176+ if (buf.base != nullptr && fd_ != -1 ) {
177+ StartWrite (buf);
178+ }
179+ }
180+
181+ void NodeTraceWriter::StartWrite (uv_buf_t buf) {
182+ int err = uv_fs_write (
183+ tracing_loop_, &write_req_, fd_, &buf, 1 , -1 ,
184+ [](uv_fs_t * req) {
185+ NodeTraceWriter* writer =
186+ ContainerOf (&NodeTraceWriter::write_req_, req);
187+ writer->AfterWrite ();
188+ });
176189 CHECK_EQ (err, 0 );
177190}
178191
179- void NodeTraceWriter::WriteCb ( uv_fs_t * req ) {
180- WriteRequest* write_req = ContainerOf (&WriteRequest::req, req );
181- CHECK_GE (write_req-> req . result , 0 );
192+ void NodeTraceWriter::AfterWrite ( ) {
193+ CHECK_GE (write_req_. result , 0 );
194+ uv_fs_req_cleanup (&write_req_ );
182195
183- NodeTraceWriter* writer = write_req->writer ;
184- int highest_request_id = write_req->highest_request_id ;
196+ uv_buf_t buf = uv_buf_init (nullptr , 0 );
185197 {
186- Mutex::ScopedLock scoped_lock (writer->request_mutex_ );
187- CHECK_EQ (write_req, writer->write_req_queue_ .front ());
188- writer->write_req_queue_ .pop ();
189- writer->highest_request_id_completed_ = highest_request_id;
190- writer->request_cond_ .Broadcast (scoped_lock);
198+ Mutex::ScopedLock scoped_lock (request_mutex_);
199+ int highest_request_id = write_req_queue_.front ().highest_request_id ;
200+ write_req_queue_.pop ();
201+ highest_request_id_completed_ = highest_request_id;
202+ request_cond_.Broadcast (scoped_lock);
203+ if (!write_req_queue_.empty ()) {
204+ buf = uv_buf_init (
205+ const_cast <char *>(write_req_queue_.front ().str .c_str ()),
206+ write_req_queue_.front ().str .length ());
207+ }
208+ }
209+ if (buf.base != nullptr && fd_ != -1 ) {
210+ StartWrite (buf);
191211 }
192- delete write_req;
193212}
194213
195214// static
0 commit comments