OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 #include <utility> | 4 #include <utility> |
5 | 5 |
6 #include "base/bind.h" | 6 #include "base/bind.h" |
7 #include "base/files/file_util.h" | 7 #include "base/files/file_util.h" |
8 #include "base/json/json_writer.h" | 8 #include "base/json/json_writer.h" |
9 #include "base/macros.h" | 9 #include "base/macros.h" |
10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
(...skipping 25 matching lines...) Expand all Loading... | |
36 trace_.clear(); | 36 trace_.clear(); |
37 scoped_refptr<base::RefCountedString> str = | 37 scoped_refptr<base::RefCountedString> str = |
38 base::RefCountedString::TakeString(&tmp); | 38 base::RefCountedString::TakeString(&tmp); |
39 | 39 |
40 BrowserThread::PostTask( | 40 BrowserThread::PostTask( |
41 BrowserThread::UI, FROM_HERE, | 41 BrowserThread::UI, FROM_HERE, |
42 base::Bind(completion_callback_, base::Passed(std::move(metadata)), | 42 base::Bind(completion_callback_, base::Passed(std::move(metadata)), |
43 base::RetainedRef(str))); | 43 base::RetainedRef(str))); |
44 } | 44 } |
45 | 45 |
46 void ReceiveTraceChunk(const std::string& chunk) override { trace_ << chunk; } | 46 void ReceiveTraceChunk(std::unique_ptr<std::string> chunk) override { |
47 trace_ << *chunk; | |
48 } | |
47 | 49 |
48 private: | 50 private: |
49 ~StringTraceDataEndpoint() override {} | 51 ~StringTraceDataEndpoint() override {} |
50 | 52 |
51 CompletionCallback completion_callback_; | 53 CompletionCallback completion_callback_; |
52 std::ostringstream trace_; | 54 std::ostringstream trace_; |
53 | 55 |
54 DISALLOW_COPY_AND_ASSIGN(StringTraceDataEndpoint); | 56 DISALLOW_COPY_AND_ASSIGN(StringTraceDataEndpoint); |
55 }; | 57 }; |
56 | 58 |
57 class FileTraceDataEndpoint : public TraceDataEndpoint { | 59 class FileTraceDataEndpoint : public TraceDataEndpoint { |
58 public: | 60 public: |
59 explicit FileTraceDataEndpoint(const base::FilePath& trace_file_path, | 61 explicit FileTraceDataEndpoint(const base::FilePath& trace_file_path, |
60 const base::Closure& callback) | 62 const base::Closure& callback) |
61 : file_path_(trace_file_path), | 63 : file_path_(trace_file_path), |
62 completion_callback_(callback), | 64 completion_callback_(callback), |
63 file_(NULL) {} | 65 file_(NULL) {} |
64 | 66 |
65 void ReceiveTraceChunk(const std::string& chunk) override { | 67 void ReceiveTraceChunk(std::unique_ptr<std::string> chunk) override { |
66 std::string tmp = chunk; | |
67 scoped_refptr<base::RefCountedString> chunk_ptr = | |
68 base::RefCountedString::TakeString(&tmp); | |
69 BrowserThread::PostTask( | 68 BrowserThread::PostTask( |
70 BrowserThread::FILE, FROM_HERE, | 69 BrowserThread::FILE, FROM_HERE, |
71 base::Bind(&FileTraceDataEndpoint::ReceiveTraceChunkOnFileThread, this, | 70 base::Bind(&FileTraceDataEndpoint::ReceiveTraceChunkOnFileThread, this, |
72 chunk_ptr)); | 71 base::Passed(std::move(chunk)))); |
73 } | 72 } |
74 | 73 |
75 void ReceiveTraceFinalContents( | 74 void ReceiveTraceFinalContents( |
76 std::unique_ptr<const base::DictionaryValue>) override { | 75 std::unique_ptr<const base::DictionaryValue>) override { |
77 BrowserThread::PostTask( | 76 BrowserThread::PostTask( |
78 BrowserThread::FILE, FROM_HERE, | 77 BrowserThread::FILE, FROM_HERE, |
79 base::Bind(&FileTraceDataEndpoint::CloseOnFileThread, this)); | 78 base::Bind(&FileTraceDataEndpoint::CloseOnFileThread, this)); |
80 } | 79 } |
81 | 80 |
82 private: | 81 private: |
83 ~FileTraceDataEndpoint() override { DCHECK(file_ == NULL); } | 82 ~FileTraceDataEndpoint() override { DCHECK(file_ == NULL); } |
84 | 83 |
85 void ReceiveTraceChunkOnFileThread( | 84 void ReceiveTraceChunkOnFileThread(std::unique_ptr<std::string> chunk) { |
86 const scoped_refptr<base::RefCountedString> chunk) { | |
87 if (!OpenFileIfNeededOnFileThread()) | 85 if (!OpenFileIfNeededOnFileThread()) |
88 return; | 86 return; |
89 ignore_result( | 87 ignore_result(fwrite(chunk->c_str(), chunk->size(), 1, file_)); |
90 fwrite(chunk->data().c_str(), chunk->data().size(), 1, file_)); | |
91 } | 88 } |
92 | 89 |
93 bool OpenFileIfNeededOnFileThread() { | 90 bool OpenFileIfNeededOnFileThread() { |
94 if (file_ != NULL) | 91 if (file_ != NULL) |
95 return true; | 92 return true; |
96 file_ = base::OpenFile(file_path_, "w"); | 93 file_ = base::OpenFile(file_path_, "w"); |
97 if (file_ == NULL) { | 94 if (file_ == NULL) { |
98 LOG(ERROR) << "Failed to open " << file_path_.value(); | 95 LOG(ERROR) << "Failed to open " << file_path_.value(); |
99 return false; | 96 return false; |
100 } | 97 } |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
150 | 147 |
151 void AddTraceChunk(const std::string& chunk) override { | 148 void AddTraceChunk(const std::string& chunk) override { |
152 std::string trace_string; | 149 std::string trace_string; |
153 if (had_received_first_chunk_) | 150 if (had_received_first_chunk_) |
154 trace_string = ","; | 151 trace_string = ","; |
155 else | 152 else |
156 trace_string = "{\"" + std::string(kChromeTraceLabel) + "\":["; | 153 trace_string = "{\"" + std::string(kChromeTraceLabel) + "\":["; |
157 trace_string += chunk; | 154 trace_string += chunk; |
158 had_received_first_chunk_ = true; | 155 had_received_first_chunk_ = true; |
159 | 156 |
160 endpoint_->ReceiveTraceChunk(trace_string); | 157 endpoint_->ReceiveTraceChunk(base::MakeUnique<std::string>(trace_string)); |
161 } | 158 } |
162 | 159 |
163 void Close() override { | 160 void Close() override { |
164 endpoint_->ReceiveTraceChunk("]"); | 161 endpoint_->ReceiveTraceChunk(base::MakeUnique<std::string>("]")); |
165 | 162 |
166 for (auto const &it : GetAgentTrace()) | 163 for (auto const &it : GetAgentTrace()) |
167 endpoint_->ReceiveTraceChunk(",\"" + it.first + "\": " + it.second); | 164 endpoint_->ReceiveTraceChunk( |
165 base::MakeUnique<std::string>(",\"" + it.first + "\": " + it.second)); | |
168 | 166 |
169 std::unique_ptr<base::DictionaryValue> metadata(TakeMetadata()); | 167 std::unique_ptr<base::DictionaryValue> metadata(TakeMetadata()); |
170 std::string metadataJSON; | 168 std::string metadataJSON; |
171 | 169 |
172 if (base::JSONWriter::Write(*metadata, &metadataJSON) && | 170 if (base::JSONWriter::Write(*metadata, &metadataJSON) && |
173 !metadataJSON.empty()) { | 171 !metadataJSON.empty()) { |
174 endpoint_->ReceiveTraceChunk(",\"" + std::string(kMetadataTraceLabel) + | 172 endpoint_->ReceiveTraceChunk(base::MakeUnique<std::string>( |
175 "\": " + metadataJSON); | 173 ",\"" + std::string(kMetadataTraceLabel) + "\": " + metadataJSON)); |
176 } | 174 } |
177 | 175 |
178 endpoint_->ReceiveTraceChunk("}"); | 176 endpoint_->ReceiveTraceChunk(base::MakeUnique<std::string>("}")); |
179 endpoint_->ReceiveTraceFinalContents(std::move(metadata)); | 177 endpoint_->ReceiveTraceFinalContents(std::move(metadata)); |
180 } | 178 } |
181 | 179 |
182 private: | 180 private: |
183 ~JSONTraceDataSink() override {} | 181 ~JSONTraceDataSink() override {} |
184 | 182 |
185 scoped_refptr<TraceDataEndpoint> endpoint_; | 183 scoped_refptr<TraceDataEndpoint> endpoint_; |
186 bool had_received_first_chunk_; | 184 bool had_received_first_chunk_; |
187 DISALLOW_COPY_AND_ASSIGN(JSONTraceDataSink); | 185 DISALLOW_COPY_AND_ASSIGN(JSONTraceDataSink); |
188 }; | 186 }; |
189 | 187 |
190 class CompressedTraceDataEndpoint : public TraceDataEndpoint { | 188 class CompressedTraceDataEndpoint : public TraceDataEndpoint { |
191 public: | 189 public: |
192 explicit CompressedTraceDataEndpoint( | 190 explicit CompressedTraceDataEndpoint( |
193 scoped_refptr<TraceDataEndpoint> endpoint) | 191 scoped_refptr<TraceDataEndpoint> endpoint) |
194 : endpoint_(endpoint), already_tried_open_(false) {} | 192 : endpoint_(endpoint), already_tried_open_(false) {} |
195 | 193 |
196 void ReceiveTraceChunk(const std::string& chunk) override { | 194 void ReceiveTraceChunk(std::unique_ptr<std::string> chunk) override { |
197 BrowserThread::PostTask( | 195 BrowserThread::PostTask( |
198 BrowserThread::FILE, FROM_HERE, | 196 BrowserThread::FILE, FROM_HERE, |
199 base::Bind(&CompressedTraceDataEndpoint::CompressOnFileThread, this, | 197 base::Bind(&CompressedTraceDataEndpoint::CompressOnFileThread, this, |
200 base::Passed(base::MakeUnique<std::string>(chunk)))); | 198 base::Passed(std::move(chunk)))); |
201 } | 199 } |
202 | 200 |
203 void ReceiveTraceFinalContents( | 201 void ReceiveTraceFinalContents( |
204 std::unique_ptr<const base::DictionaryValue> metadata) override { | 202 std::unique_ptr<const base::DictionaryValue> metadata) override { |
205 BrowserThread::PostTask( | 203 BrowserThread::PostTask( |
206 BrowserThread::FILE, FROM_HERE, | 204 BrowserThread::FILE, FROM_HERE, |
207 base::Bind(&CompressedTraceDataEndpoint::CloseOnFileThread, this, | 205 base::Bind(&CompressedTraceDataEndpoint::CloseOnFileThread, this, |
208 base::Passed(std::move(metadata)))); | 206 base::Passed(std::move(metadata)))); |
209 } | 207 } |
210 | 208 |
(...skipping 22 matching lines...) Expand all Loading... | |
233 Z_DEFAULT_STRATEGY); | 231 Z_DEFAULT_STRATEGY); |
234 return result == 0; | 232 return result == 0; |
235 } | 233 } |
236 | 234 |
237 void CompressOnFileThread(std::unique_ptr<std::string> chunk) { | 235 void CompressOnFileThread(std::unique_ptr<std::string> chunk) { |
238 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 236 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
239 if (!OpenZStreamOnFileThread()) | 237 if (!OpenZStreamOnFileThread()) |
240 return; | 238 return; |
241 | 239 |
242 stream_->avail_in = chunk->size(); | 240 stream_->avail_in = chunk->size(); |
243 stream_->next_in = (unsigned char*)chunk->data(); | 241 stream_->next_in = reinterpret_cast<unsigned char*>(&*chunk->begin()); |
oystein (OOO til 10th of July)
2016/07/15 16:56:26
Just curious: What's the reason for &*chunk->begin
| |
244 DrainStreamOnFileThread(false); | 242 DrainStreamOnFileThread(false); |
245 } | 243 } |
246 | 244 |
247 void DrainStreamOnFileThread(bool finished) { | 245 void DrainStreamOnFileThread(bool finished) { |
248 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 246 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
249 | 247 |
250 int err; | 248 int err; |
251 const int kChunkSize = 0x4000; | 249 const int kChunkSize = 0x4000; |
252 char buffer[kChunkSize]; | 250 char buffer[kChunkSize]; |
253 do { | 251 do { |
254 stream_->avail_out = kChunkSize; | 252 stream_->avail_out = kChunkSize; |
255 stream_->next_out = (unsigned char*)buffer; | 253 stream_->next_out = (unsigned char*)buffer; |
256 err = deflate(stream_.get(), finished ? Z_FINISH : Z_NO_FLUSH); | 254 err = deflate(stream_.get(), finished ? Z_FINISH : Z_NO_FLUSH); |
257 if (err != (finished ? Z_STREAM_END : Z_OK)) { | 255 if (err != (finished ? Z_STREAM_END : Z_OK)) { |
258 stream_.reset(); | 256 stream_.reset(); |
259 return; | 257 return; |
260 } | 258 } |
261 | 259 |
262 int bytes = kChunkSize - stream_->avail_out; | 260 int bytes = kChunkSize - stream_->avail_out; |
263 if (bytes) { | 261 if (bytes) { |
264 std::string compressed_chunk = std::string(buffer, bytes); | 262 std::string compressed(buffer, bytes); |
265 endpoint_->ReceiveTraceChunk(compressed_chunk); | 263 endpoint_->ReceiveTraceChunk(base::MakeUnique<std::string>(compressed)); |
266 } | 264 } |
267 } while (stream_->avail_out == 0); | 265 } while (stream_->avail_out == 0); |
268 } | 266 } |
269 | 267 |
270 void CloseOnFileThread( | 268 void CloseOnFileThread( |
271 std::unique_ptr<const base::DictionaryValue> metadata) { | 269 std::unique_ptr<const base::DictionaryValue> metadata) { |
272 DCHECK_CURRENTLY_ON(BrowserThread::FILE); | 270 DCHECK_CURRENTLY_ON(BrowserThread::FILE); |
273 if (!OpenZStreamOnFileThread()) | 271 if (!OpenZStreamOnFileThread()) |
274 return; | 272 return; |
275 | 273 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
332 return new JSONTraceDataSink(new CompressedTraceDataEndpoint(endpoint)); | 330 return new JSONTraceDataSink(new CompressedTraceDataEndpoint(endpoint)); |
333 } | 331 } |
334 | 332 |
335 scoped_refptr<TraceDataEndpoint> TracingControllerImpl::CreateCallbackEndpoint( | 333 scoped_refptr<TraceDataEndpoint> TracingControllerImpl::CreateCallbackEndpoint( |
336 const base::Callback<void(std::unique_ptr<const base::DictionaryValue>, | 334 const base::Callback<void(std::unique_ptr<const base::DictionaryValue>, |
337 base::RefCountedString*)>& callback) { | 335 base::RefCountedString*)>& callback) { |
338 return new StringTraceDataEndpoint(callback); | 336 return new StringTraceDataEndpoint(callback); |
339 } | 337 } |
340 | 338 |
341 } // namespace content | 339 } // namespace content |
OLD | NEW |