| Index: libcurl_http_fetcher.cc
|
| diff --git a/libcurl_http_fetcher.cc b/libcurl_http_fetcher.cc
|
| index a92172544d7c499ef519173c994559047b431209..8af9d455bf64386b9f19e85df176cb346e17338e 100644
|
| --- a/libcurl_http_fetcher.cc
|
| +++ b/libcurl_http_fetcher.cc
|
| @@ -228,55 +228,71 @@ void LibcurlHttpFetcher::Unpause() {
|
| void LibcurlHttpFetcher::SetupMainloopSources() {
|
| fd_set fd_read;
|
| fd_set fd_write;
|
| - fd_set fd_exec;
|
| + fd_set fd_exc;
|
|
|
| FD_ZERO(&fd_read);
|
| FD_ZERO(&fd_write);
|
| - FD_ZERO(&fd_exec);
|
| + FD_ZERO(&fd_exc);
|
|
|
| int fd_max = 0;
|
|
|
| // Ask libcurl for the set of file descriptors we should track on its
|
| // behalf.
|
| CHECK_EQ(curl_multi_fdset(curl_multi_handle_, &fd_read, &fd_write,
|
| - &fd_exec, &fd_max), CURLM_OK);
|
| + &fd_exc, &fd_max), CURLM_OK);
|
|
|
| // We should iterate through all file descriptors up to libcurl's fd_max or
|
| - // the highest one we're tracking, whichever is larger
|
| - if (!io_channels_.empty())
|
| - fd_max = max(fd_max, io_channels_.rbegin()->first);
|
| -
|
| - // For each fd, if we're not tracking it, track it. If we are tracking it,
|
| - // but libcurl doesn't care about it anymore, stop tracking it.
|
| - // After this loop, there should be exactly as many GIOChannel objects
|
| - // in io_channels_ as there are fds that we're tracking.
|
| - for (int i = 0; i <= fd_max; i++) {
|
| - if (!(FD_ISSET(i, &fd_read) || FD_ISSET(i, &fd_write) ||
|
| - FD_ISSET(i, &fd_exec))) {
|
| - // if we have an outstanding io_channel, remove it
|
| - if (io_channels_.find(i) != io_channels_.end()) {
|
| - g_source_remove(io_channels_[i].second);
|
| - g_io_channel_unref(io_channels_[i].first);
|
| - io_channels_.erase(io_channels_.find(i));
|
| + // the highest one we're tracking, whichever is larger.
|
| + for (size_t t = 0; t < arraysize(io_channels_); ++t) {
|
| + if (!io_channels_[t].empty())
|
| + fd_max = max(fd_max, io_channels_[t].rbegin()->first);
|
| + }
|
| +
|
| + // For each fd, if we're not tracking it, track it. If we are tracking it, but
|
| + // libcurl doesn't care about it anymore, stop tracking it. After this loop,
|
| + // there should be exactly as many GIOChannel objects in io_channels_[0|1] as
|
| + // there are read/write fds that we're tracking.
|
| + for (int fd = 0; fd <= fd_max; ++fd) {
|
| + // Note that fd_exc is unused in the current version of libcurl so is_exc
|
| + // should always be false.
|
| + bool is_exc = FD_ISSET(fd, &fd_exc) != 0;
|
| + bool must_track[2] = {
|
| + is_exc || (FD_ISSET(fd, &fd_read) != 0), // track 0 -- read
|
| + is_exc || (FD_ISSET(fd, &fd_write) != 0) // track 1 -- write
|
| + };
|
| +
|
| + for (size_t t = 0; t < arraysize(io_channels_); ++t) {
|
| + bool tracked = io_channels_[t].find(fd) != io_channels_[t].end();
|
| +
|
| + if (!must_track[t]) {
|
| + // If we have an outstanding io_channel, remove it.
|
| + if (tracked) {
|
| + g_source_remove(io_channels_[t][fd].second);
|
| + g_io_channel_unref(io_channels_[t][fd].first);
|
| + io_channels_[t].erase(io_channels_[t].find(fd));
|
| + }
|
| + continue;
|
| + }
|
| +
|
| + // If we are already tracking this fd, continue -- nothing to do.
|
| + if (tracked)
|
| + continue;
|
| +
|
| + // Set conditions appropriately -- read for track 0, write for track 1.
|
| + GIOCondition condition = static_cast<GIOCondition>(
|
| + ((t == 0) ? (G_IO_IN | G_IO_PRI) : G_IO_OUT) | G_IO_ERR | G_IO_HUP);
|
| +
|
| + // Track a new fd.
|
| + GIOChannel* io_channel = g_io_channel_unix_new(fd);
|
| + guint tag =
|
| + g_io_add_watch(io_channel, condition, &StaticFDCallback, this);
|
| +
|
| + io_channels_[t][fd] = make_pair(io_channel, tag);
|
| + static int io_counter = 0;
|
| + io_counter++;
|
| + if (io_counter % 50 == 0) {
|
| + LOG(INFO) << "io_counter = " << io_counter;
|
| }
|
| - continue;
|
| - }
|
| - // If we are already tracking this fd, continue.
|
| - if (io_channels_.find(i) != io_channels_.end())
|
| - continue;
|
| - // We must track a new fd
|
| - GIOChannel *io_channel = g_io_channel_unix_new(i);
|
| - guint tag = g_io_add_watch(
|
| - io_channel,
|
| - static_cast<GIOCondition>(G_IO_IN | G_IO_OUT | G_IO_PRI |
|
| - G_IO_ERR | G_IO_HUP),
|
| - &StaticFDCallback,
|
| - this);
|
| - io_channels_[i] = make_pair(io_channel, tag);
|
| - static int io_counter = 0;
|
| - io_counter++;
|
| - if (io_counter % 50 == 0) {
|
| - LOG(INFO) << "io_counter = " << io_counter;
|
| }
|
| }
|
|
|
| @@ -321,12 +337,14 @@ void LibcurlHttpFetcher::CleanUp() {
|
| timeout_source_ = NULL;
|
| }
|
|
|
| - for (IOChannels::iterator it = io_channels_.begin();
|
| - it != io_channels_.end(); ++it) {
|
| - g_source_remove(it->second.second);
|
| - g_io_channel_unref(it->second.first);
|
| + for (size_t t = 0; t < arraysize(io_channels_); ++t) {
|
| + for (IOChannels::iterator it = io_channels_[t].begin();
|
| + it != io_channels_[t].end(); ++it) {
|
| + g_source_remove(it->second.second);
|
| + g_io_channel_unref(it->second.first);
|
| + }
|
| + io_channels_[t].clear();
|
| }
|
| - io_channels_.clear();
|
|
|
| if (curl_handle_) {
|
| if (curl_multi_handle_) {
|
|
|