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

Side by Side Diff: libcurl_http_fetcher.cc

Issue 4190009: AU: Watch for writes on write fds only, and for reads on read fds. (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/update_engine.git
Patch Set: fix comment 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 | « libcurl_http_fetcher.h ('k') | no next file » | 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) 2009 The Chromium OS Authors. All rights reserved. 1 // Copyright (c) 2009 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/libcurl_http_fetcher.h" 5 #include "update_engine/libcurl_http_fetcher.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 9
10 #include <base/logging.h> 10 #include <base/logging.h>
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 void LibcurlHttpFetcher::Unpause() { 221 void LibcurlHttpFetcher::Unpause() {
222 CHECK(curl_handle_); 222 CHECK(curl_handle_);
223 CHECK(transfer_in_progress_); 223 CHECK(transfer_in_progress_);
224 CHECK_EQ(curl_easy_pause(curl_handle_, CURLPAUSE_CONT), CURLE_OK); 224 CHECK_EQ(curl_easy_pause(curl_handle_, CURLPAUSE_CONT), CURLE_OK);
225 } 225 }
226 226
227 // This method sets up callbacks with the glib main loop. 227 // This method sets up callbacks with the glib main loop.
228 void LibcurlHttpFetcher::SetupMainloopSources() { 228 void LibcurlHttpFetcher::SetupMainloopSources() {
229 fd_set fd_read; 229 fd_set fd_read;
230 fd_set fd_write; 230 fd_set fd_write;
231 fd_set fd_exec; 231 fd_set fd_exc;
232 232
233 FD_ZERO(&fd_read); 233 FD_ZERO(&fd_read);
234 FD_ZERO(&fd_write); 234 FD_ZERO(&fd_write);
235 FD_ZERO(&fd_exec); 235 FD_ZERO(&fd_exc);
236 236
237 int fd_max = 0; 237 int fd_max = 0;
238 238
239 // Ask libcurl for the set of file descriptors we should track on its 239 // Ask libcurl for the set of file descriptors we should track on its
240 // behalf. 240 // behalf.
241 CHECK_EQ(curl_multi_fdset(curl_multi_handle_, &fd_read, &fd_write, 241 CHECK_EQ(curl_multi_fdset(curl_multi_handle_, &fd_read, &fd_write,
242 &fd_exec, &fd_max), CURLM_OK); 242 &fd_exc, &fd_max), CURLM_OK);
243 243
244 // We should iterate through all file descriptors up to libcurl's fd_max or 244 // We should iterate through all file descriptors up to libcurl's fd_max or
245 // the highest one we're tracking, whichever is larger 245 // the highest one we're tracking, whichever is larger.
246 if (!io_channels_.empty()) 246 for (size_t t = 0; t < arraysize(io_channels_); ++t) {
247 fd_max = max(fd_max, io_channels_.rbegin()->first); 247 if (!io_channels_[t].empty())
248 fd_max = max(fd_max, io_channels_[t].rbegin()->first);
249 }
248 250
249 // For each fd, if we're not tracking it, track it. If we are tracking it, 251 // For each fd, if we're not tracking it, track it. If we are tracking it, but
250 // but libcurl doesn't care about it anymore, stop tracking it. 252 // libcurl doesn't care about it anymore, stop tracking it. After this loop,
251 // After this loop, there should be exactly as many GIOChannel objects 253 // there should be exactly as many GIOChannel objects in io_channels_[0|1] as
252 // in io_channels_ as there are fds that we're tracking. 254 // there are read/write fds that we're tracking.
253 for (int i = 0; i <= fd_max; i++) { 255 for (int fd = 0; fd <= fd_max; ++fd) {
254 if (!(FD_ISSET(i, &fd_read) || FD_ISSET(i, &fd_write) || 256 // Note that fd_exc is unused in the current version of libcurl so is_exc
255 FD_ISSET(i, &fd_exec))) { 257 // should always be false.
256 // if we have an outstanding io_channel, remove it 258 bool is_exc = FD_ISSET(fd, &fd_exc) != 0;
257 if (io_channels_.find(i) != io_channels_.end()) { 259 bool must_track[2] = {
258 g_source_remove(io_channels_[i].second); 260 is_exc || (FD_ISSET(fd, &fd_read) != 0), // track 0 -- read
259 g_io_channel_unref(io_channels_[i].first); 261 is_exc || (FD_ISSET(fd, &fd_write) != 0) // track 1 -- write
260 io_channels_.erase(io_channels_.find(i)); 262 };
263
264 for (size_t t = 0; t < arraysize(io_channels_); ++t) {
265 bool tracked = io_channels_[t].find(fd) != io_channels_[t].end();
266
267 if (!must_track[t]) {
268 // If we have an outstanding io_channel, remove it.
269 if (tracked) {
270 g_source_remove(io_channels_[t][fd].second);
271 g_io_channel_unref(io_channels_[t][fd].first);
272 io_channels_[t].erase(io_channels_[t].find(fd));
273 }
274 continue;
261 } 275 }
262 continue; 276
263 } 277 // If we are already tracking this fd, continue -- nothing to do.
264 // If we are already tracking this fd, continue. 278 if (tracked)
265 if (io_channels_.find(i) != io_channels_.end()) 279 continue;
266 continue; 280
267 // We must track a new fd 281 // Set conditions appropriately -- read for track 0, write for track 1.
268 GIOChannel *io_channel = g_io_channel_unix_new(i); 282 GIOCondition condition = static_cast<GIOCondition>(
269 guint tag = g_io_add_watch( 283 ((t == 0) ? (G_IO_IN | G_IO_PRI) : G_IO_OUT) | G_IO_ERR | G_IO_HUP);
270 io_channel, 284
271 static_cast<GIOCondition>(G_IO_IN | G_IO_OUT | G_IO_PRI | 285 // Track a new fd.
272 G_IO_ERR | G_IO_HUP), 286 GIOChannel* io_channel = g_io_channel_unix_new(fd);
273 &StaticFDCallback, 287 guint tag =
274 this); 288 g_io_add_watch(io_channel, condition, &StaticFDCallback, this);
275 io_channels_[i] = make_pair(io_channel, tag); 289
276 static int io_counter = 0; 290 io_channels_[t][fd] = make_pair(io_channel, tag);
277 io_counter++; 291 static int io_counter = 0;
278 if (io_counter % 50 == 0) { 292 io_counter++;
279 LOG(INFO) << "io_counter = " << io_counter; 293 if (io_counter % 50 == 0) {
294 LOG(INFO) << "io_counter = " << io_counter;
295 }
280 } 296 }
281 } 297 }
282 298
283 // Set up a timeout callback for libcurl. 299 // Set up a timeout callback for libcurl.
284 if (!timeout_source_) { 300 if (!timeout_source_) {
285 LOG(INFO) << "Setting up timeout source: " << idle_seconds_ << " seconds."; 301 LOG(INFO) << "Setting up timeout source: " << idle_seconds_ << " seconds.";
286 timeout_source_ = g_timeout_source_new_seconds(idle_seconds_); 302 timeout_source_ = g_timeout_source_new_seconds(idle_seconds_);
287 g_source_set_callback(timeout_source_, StaticTimeoutCallback, this, NULL); 303 g_source_set_callback(timeout_source_, StaticTimeoutCallback, this, NULL);
288 g_source_attach(timeout_source_, NULL); 304 g_source_attach(timeout_source_, NULL);
289 } 305 }
(...skipping 24 matching lines...) Expand all
314 CurlPerformOnce(); 330 CurlPerformOnce();
315 return TRUE; 331 return TRUE;
316 } 332 }
317 333
318 void LibcurlHttpFetcher::CleanUp() { 334 void LibcurlHttpFetcher::CleanUp() {
319 if (timeout_source_) { 335 if (timeout_source_) {
320 g_source_destroy(timeout_source_); 336 g_source_destroy(timeout_source_);
321 timeout_source_ = NULL; 337 timeout_source_ = NULL;
322 } 338 }
323 339
324 for (IOChannels::iterator it = io_channels_.begin(); 340 for (size_t t = 0; t < arraysize(io_channels_); ++t) {
325 it != io_channels_.end(); ++it) { 341 for (IOChannels::iterator it = io_channels_[t].begin();
326 g_source_remove(it->second.second); 342 it != io_channels_[t].end(); ++it) {
327 g_io_channel_unref(it->second.first); 343 g_source_remove(it->second.second);
344 g_io_channel_unref(it->second.first);
345 }
346 io_channels_[t].clear();
328 } 347 }
329 io_channels_.clear();
330 348
331 if (curl_handle_) { 349 if (curl_handle_) {
332 if (curl_multi_handle_) { 350 if (curl_multi_handle_) {
333 CHECK_EQ(curl_multi_remove_handle(curl_multi_handle_, curl_handle_), 351 CHECK_EQ(curl_multi_remove_handle(curl_multi_handle_, curl_handle_),
334 CURLM_OK); 352 CURLM_OK);
335 } 353 }
336 curl_easy_cleanup(curl_handle_); 354 curl_easy_cleanup(curl_handle_);
337 curl_handle_ = NULL; 355 curl_handle_ = NULL;
338 } 356 }
339 if (curl_multi_handle_) { 357 if (curl_multi_handle_) {
340 CHECK_EQ(curl_multi_cleanup(curl_multi_handle_), CURLM_OK); 358 CHECK_EQ(curl_multi_cleanup(curl_multi_handle_), CURLM_OK);
341 curl_multi_handle_ = NULL; 359 curl_multi_handle_ = NULL;
342 } 360 }
343 transfer_in_progress_ = false; 361 transfer_in_progress_ = false;
344 } 362 }
345 363
346 void LibcurlHttpFetcher::GetHttpResponseCode() { 364 void LibcurlHttpFetcher::GetHttpResponseCode() {
347 long http_response_code = 0; 365 long http_response_code = 0;
348 if (curl_easy_getinfo(curl_handle_, 366 if (curl_easy_getinfo(curl_handle_,
349 CURLINFO_RESPONSE_CODE, 367 CURLINFO_RESPONSE_CODE,
350 &http_response_code) == CURLE_OK) { 368 &http_response_code) == CURLE_OK) {
351 http_response_code_ = static_cast<int>(http_response_code); 369 http_response_code_ = static_cast<int>(http_response_code);
352 } 370 }
353 } 371 }
354 372
355 } // namespace chromeos_update_engine 373 } // namespace chromeos_update_engine
OLDNEW
« no previous file with comments | « libcurl_http_fetcher.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698