Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(528)

Side by Side Diff: components/upload_list/upload_list.cc

Issue 1830383002: Fix thread safety issues with //components/upload_list. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add race condition test Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 4
5 #include "components/upload_list/upload_list.h" 5 #include "components/upload_list/upload_list.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <iterator> 10 #include <iterator>
(...skipping 27 matching lines...) Expand all
38 : delegate_(delegate), 38 : delegate_(delegate),
39 upload_log_path_(upload_log_path), 39 upload_log_path_(upload_log_path),
40 worker_pool_(worker_pool) {} 40 worker_pool_(worker_pool) {}
41 41
42 UploadList::~UploadList() {} 42 UploadList::~UploadList() {}
43 43
44 void UploadList::LoadUploadListAsynchronously() { 44 void UploadList::LoadUploadListAsynchronously() {
45 DCHECK(thread_checker_.CalledOnValidThread()); 45 DCHECK(thread_checker_.CalledOnValidThread());
46 worker_pool_->PostTask( 46 worker_pool_->PostTask(
47 FROM_HERE, 47 FROM_HERE,
48 base::Bind(&UploadList::LoadUploadListAndInformDelegateOfCompletion, 48 base::Bind(&UploadList::PerformLoadAndNotifyDelegate,
49 this, base::ThreadTaskRunnerHandle::Get())); 49 this, base::ThreadTaskRunnerHandle::Get()));
50 } 50 }
51 51
52 void UploadList::ClearDelegate() { 52 void UploadList::ClearDelegate() {
53 DCHECK(thread_checker_.CalledOnValidThread()); 53 DCHECK(thread_checker_.CalledOnValidThread());
54 delegate_ = NULL; 54 delegate_ = NULL;
55 } 55 }
56 56
57 void UploadList::LoadUploadListAndInformDelegateOfCompletion( 57 void UploadList::PerformLoadAndNotifyDelegate(
58 const scoped_refptr<base::SequencedTaskRunner>& task_runner) { 58 const scoped_refptr<base::SequencedTaskRunner>& task_runner) {
59 LoadUploadList(); 59 std::vector<UploadInfo> uploads;
60 LoadUploadList(&uploads);
60 task_runner->PostTask( 61 task_runner->PostTask(
61 FROM_HERE, 62 FROM_HERE,
62 base::Bind(&UploadList::InformDelegateOfCompletion, this)); 63 base::Bind(&UploadList::SetUploadsAndNotifyDelegate, this,
64 std::move(uploads)));
Mark Mentovai 2016/03/25 18:26:56 #include <utility>
Robert Sesek 2016/03/25 18:45:56 Done.
63 } 65 }
64 66
65 void UploadList::LoadUploadList() { 67 void UploadList::LoadUploadList(std::vector<UploadInfo>* uploads) {
66 if (base::PathExists(upload_log_path_)) { 68 if (base::PathExists(upload_log_path_)) {
67 std::string contents; 69 std::string contents;
68 base::ReadFileToString(upload_log_path_, &contents); 70 base::ReadFileToString(upload_log_path_, &contents);
69 std::vector<std::string> log_entries = base::SplitString( 71 std::vector<std::string> log_entries = base::SplitString(
70 contents, base::kWhitespaceASCII, base::KEEP_WHITESPACE, 72 contents, base::kWhitespaceASCII, base::KEEP_WHITESPACE,
71 base::SPLIT_WANT_NONEMPTY); 73 base::SPLIT_WANT_NONEMPTY);
72 ClearUploads(); 74 ParseLogEntries(log_entries, uploads);
73 ParseLogEntries(log_entries);
74 } 75 }
75 } 76 }
76 77
77 void UploadList::AppendUploadInfo(const UploadInfo& info) {
78 uploads_.push_back(info);
79 }
80
81 void UploadList::ClearUploads() {
82 uploads_.clear();
83 }
84
85 void UploadList::ParseLogEntries( 78 void UploadList::ParseLogEntries(
86 const std::vector<std::string>& log_entries) { 79 const std::vector<std::string>& log_entries,
80 std::vector<UploadInfo>* uploads) {
87 std::vector<std::string>::const_reverse_iterator i; 81 std::vector<std::string>::const_reverse_iterator i;
88 for (i = log_entries.rbegin(); i != log_entries.rend(); ++i) { 82 for (i = log_entries.rbegin(); i != log_entries.rend(); ++i) {
89 std::vector<std::string> components = base::SplitString( 83 std::vector<std::string> components = base::SplitString(
90 *i, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); 84 *i, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
91 // Skip any blank (or corrupted) lines. 85 // Skip any blank (or corrupted) lines.
92 if (components.size() < 2 || components.size() > 4) 86 if (components.size() < 2 || components.size() > 4)
93 continue; 87 continue;
94 base::Time upload_time; 88 base::Time upload_time;
95 double seconds_since_epoch; 89 double seconds_since_epoch;
96 if (!components[0].empty()) { 90 if (!components[0].empty()) {
97 if (!base::StringToDouble(components[0], &seconds_since_epoch)) 91 if (!base::StringToDouble(components[0], &seconds_since_epoch))
98 continue; 92 continue;
99 upload_time = base::Time::FromDoubleT(seconds_since_epoch); 93 upload_time = base::Time::FromDoubleT(seconds_since_epoch);
100 } 94 }
101 UploadInfo info(components[1], upload_time); 95 UploadInfo info(components[1], upload_time);
102 96
103 // Add local ID if present. 97 // Add local ID if present.
104 if (components.size() > 2) 98 if (components.size() > 2)
105 info.local_id = components[2]; 99 info.local_id = components[2];
106 100
107 // Add capture time if present. 101 // Add capture time if present.
108 if (components.size() > 3 && 102 if (components.size() > 3 &&
109 !components[3].empty() && 103 !components[3].empty() &&
110 base::StringToDouble(components[3], &seconds_since_epoch)) { 104 base::StringToDouble(components[3], &seconds_since_epoch)) {
111 info.capture_time = base::Time::FromDoubleT(seconds_since_epoch); 105 info.capture_time = base::Time::FromDoubleT(seconds_since_epoch);
112 } 106 }
113 107
114 uploads_.push_back(info); 108 uploads->push_back(info);
115 } 109 }
116 } 110 }
117 111
118 void UploadList::InformDelegateOfCompletion() { 112 void UploadList::SetUploadsAndNotifyDelegate(std::vector<UploadInfo> uploads) {
119 DCHECK(thread_checker_.CalledOnValidThread()); 113 DCHECK(thread_checker_.CalledOnValidThread());
114 uploads_ = std::move(uploads);
120 if (delegate_) 115 if (delegate_)
121 delegate_->OnUploadListAvailable(); 116 delegate_->OnUploadListAvailable();
122 } 117 }
123 118
124 void UploadList::GetUploads(unsigned int max_count, 119 void UploadList::GetUploads(size_t max_count,
Mark Mentovai 2016/03/25 18:26:56 This max_count thing seems ill-advised, certainly
Robert Sesek 2016/03/25 18:45:56 Right. There's some more cleanup I'd like to do he
125 std::vector<UploadInfo>* uploads) { 120 std::vector<UploadInfo>* uploads) {
126 DCHECK(thread_checker_.CalledOnValidThread()); 121 DCHECK(thread_checker_.CalledOnValidThread());
127 std::copy(uploads_.begin(), 122 std::copy(uploads_.begin(),
128 uploads_.begin() + std::min<size_t>(uploads_.size(), max_count), 123 uploads_.begin() + std::min<size_t>(uploads_.size(), max_count),
Mark Mentovai 2016/03/25 18:26:56 The explicit <size_t> is no longer necessary!
Robert Sesek 2016/03/25 18:45:56 Done.
129 std::back_inserter(*uploads)); 124 std::back_inserter(*uploads));
130 } 125 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698