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

Side by Side Diff: download_action.cc

Issue 5009009: AU: Fix potential issues with premature destruction of HTTP fetchers. (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/update_engine.git@master
Patch Set: review comments Created 10 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « download_action.h ('k') | download_action_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium OS 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 "update_engine/download_action.h" 5 #include "update_engine/download_action.h"
6 #include <errno.h> 6 #include <errno.h>
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 #include <glib.h> 10 #include <glib.h>
11 #include "update_engine/action_pipe.h" 11 #include "update_engine/action_pipe.h"
12 #include "update_engine/subprocess.h" 12 #include "update_engine/subprocess.h"
13 13
14 using std::min; 14 using std::min;
15 using std::string; 15 using std::string;
16 using std::vector; 16 using std::vector;
17 17
18 namespace chromeos_update_engine { 18 namespace chromeos_update_engine {
19 19
20 // Use a buffer to reduce the number of IOPS on SSD devices. 20 // Use a buffer to reduce the number of IOPS on SSD devices.
21 const size_t kFileWriterBufferSize = 128 * 1024; // 128 KiB 21 const size_t kFileWriterBufferSize = 128 * 1024; // 128 KiB
22 22
23 DownloadAction::DownloadAction(PrefsInterface* prefs, 23 DownloadAction::DownloadAction(PrefsInterface* prefs,
24 HttpFetcher* http_fetcher) 24 HttpFetcher* http_fetcher)
25 : prefs_(prefs), 25 : prefs_(prefs),
26 writer_(NULL), 26 writer_(NULL),
27 http_fetcher_(http_fetcher), 27 http_fetcher_(http_fetcher),
28 code_(kActionCodeSuccess),
28 delegate_(NULL), 29 delegate_(NULL),
29 bytes_received_(0) {} 30 bytes_received_(0) {}
30 31
31 DownloadAction::~DownloadAction() {} 32 DownloadAction::~DownloadAction() {}
32 33
33 void DownloadAction::PerformAction() { 34 void DownloadAction::PerformAction() {
34 http_fetcher_->set_delegate(this); 35 http_fetcher_->set_delegate(this);
35 36
36 // Get the InstallPlan and read it 37 // Get the InstallPlan and read it
37 CHECK(HasInputObject()); 38 CHECK(HasInputObject());
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 delegate_->SetDownloadStatus(true); // Set to active. 95 delegate_->SetDownloadStatus(true); // Set to active.
95 } 96 }
96 http_fetcher_->BeginTransfer(install_plan_.download_url); 97 http_fetcher_->BeginTransfer(install_plan_.download_url);
97 } 98 }
98 99
99 void DownloadAction::TerminateProcessing() { 100 void DownloadAction::TerminateProcessing() {
100 if (writer_) { 101 if (writer_) {
101 LOG_IF(WARNING, writer_->Close() != 0) << "Error closing the writer."; 102 LOG_IF(WARNING, writer_->Close() != 0) << "Error closing the writer.";
102 writer_ = NULL; 103 writer_ = NULL;
103 } 104 }
104 http_fetcher_->TerminateTransfer();
105 if (delegate_) { 105 if (delegate_) {
106 delegate_->SetDownloadStatus(false); // Set to inactive. 106 delegate_->SetDownloadStatus(false); // Set to inactive.
107 } 107 }
108 // Terminates the transfer. The action is terminated, if necessary, when the
109 // TransferTerminated callback is received.
110 http_fetcher_->TerminateTransfer();
108 } 111 }
109 112
110 void DownloadAction::SeekToOffset(off_t offset) { 113 void DownloadAction::SeekToOffset(off_t offset) {
111 bytes_received_ = offset; 114 bytes_received_ = offset;
112 } 115 }
113 116
114 void DownloadAction::ReceivedBytes(HttpFetcher *fetcher, 117 void DownloadAction::ReceivedBytes(HttpFetcher *fetcher,
115 const char* bytes, 118 const char* bytes,
116 int length) { 119 int length) {
117 bytes_received_ += length; 120 bytes_received_ += length;
118 if (delegate_) 121 if (delegate_)
119 delegate_->BytesReceived(bytes_received_, install_plan_.size); 122 delegate_->BytesReceived(bytes_received_, install_plan_.size);
120 if (writer_ && writer_->Write(bytes, length) < 0) { 123 if (writer_ && writer_->Write(bytes, length) < 0) {
121 LOG(ERROR) << "Write error -- terminating processing."; 124 LOG(ERROR) << "Write error -- terminating processing.";
125 // Don't tell the action processor that the action is complete until we get
126 // the TransferTerminated callback. Otherwise, this and the HTTP fetcher
127 // objects may get destroyed before all callbacks are complete.
128 code_ = kActionCodeDownloadWriteError;
122 TerminateProcessing(); 129 TerminateProcessing();
123 processor_->ActionComplete(this, kActionCodeDownloadWriteError);
124 return; 130 return;
125 } 131 }
126 // DeltaPerformer checks the hashes for delta updates. 132 // DeltaPerformer checks the hashes for delta updates.
127 if (install_plan_.is_full_update) { 133 if (install_plan_.is_full_update) {
128 omaha_hash_calculator_.Update(bytes, length); 134 omaha_hash_calculator_.Update(bytes, length);
129 } 135 }
130 } 136 }
131 137
132 namespace { 138 namespace {
133 void FlushLinuxCaches() { 139 void FlushLinuxCaches() {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 } 193 }
188 194
189 FlushLinuxCaches(); 195 FlushLinuxCaches();
190 196
191 // Write the path to the output pipe if we're successful. 197 // Write the path to the output pipe if we're successful.
192 if (code == kActionCodeSuccess && HasOutputPipe()) 198 if (code == kActionCodeSuccess && HasOutputPipe())
193 SetOutputObject(GetInputObject()); 199 SetOutputObject(GetInputObject());
194 processor_->ActionComplete(this, code); 200 processor_->ActionComplete(this, code);
195 } 201 }
196 202
203 void DownloadAction::TransferTerminated(HttpFetcher *fetcher) {
204 if (code_ != kActionCodeSuccess) {
205 processor_->ActionComplete(this, code_);
206 }
207 }
208
197 }; // namespace {} 209 }; // namespace {}
OLDNEW
« no previous file with comments | « download_action.h ('k') | download_action_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698