Chromium Code Reviews| 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 |