<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/gtk/download_item_drag.h"

#include "app/gfx/gtk_util.h"
#include "app/gtk_dnd_util.h"
#include "base/string_util.h"
#include "chrome/browser/download/download_manager.h"
#include "googleurl/src/gurl.h"
#include "net/base/net_util.h"
#include "third_party/skia/include/core/SkBitmap.h"

namespace {

const int kCodeMask = GtkDndUtil::TEXT_URI_LIST |
                      GtkDndUtil::CHROME_NAMED_URL;
const GdkDragAction kDragAction = GDK_ACTION_COPY;

void OnDragDataGet(GtkWidget* widget, GdkDragContext* context,
                   GtkSelectionData* selection_data,
                   guint target_type, guint time,
                   DownloadItem* download_item) {
  GURL url = net::FilePathToFileURL(download_item->full_path());
  GtkDndUtil::WriteURLWithName(selection_data, url,
      UTF8ToUTF16(download_item->GetFileName().value()), target_type);
}

} // namespace

// static
void DownloadItemDrag::SetSource(GtkWidget* widget, DownloadItem* item) {
  gtk_drag_source_set(widget, GDK_BUTTON1_MASK, NULL, 0,
                      kDragAction);
  GtkDndUtil::SetSourceTargetListFromCodeMask(widget, kCodeMask);
  g_signal_connect(widget, "drag-data-get",
                   G_CALLBACK(OnDragDataGet), item);
}

// static
void DownloadItemDrag::BeginDrag(const DownloadItem* item, SkBitmap* icon) {
  new DownloadItemDrag(item, icon);
}

DownloadItemDrag::DownloadItemDrag(const DownloadItem* item,
                                   SkBitmap* icon)
    : drag_widget_(gtk_invisible_new()),
      pixbuf_(gfx::GdkPixbufFromSkBitmap(icon)) {
  g_object_ref_sink(drag_widget_);
  g_signal_connect(drag_widget_, "drag-data-get",
                   G_CALLBACK(OnDragDataGet), const_cast<DownloadItem*>(item));
  g_signal_connect(drag_widget_, "drag-begin",
                   G_CALLBACK(OnDragBegin), this);
  g_signal_connect(drag_widget_, "drag-end",
                   G_CALLBACK(OnDragEnd), this);

  GtkTargetList* list = GtkDndUtil::GetTargetListFromCodeMask(kCodeMask);
  gtk_drag_begin(drag_widget_, list, kDragAction, 1, gtk_get_current_event());
  gtk_target_list_unref(list);
}

DownloadItemDrag::~DownloadItemDrag() {
  g_object_unref(pixbuf_);
  g_object_unref(drag_widget_);
}

// static
void DownloadItemDrag::OnDragBegin(GtkWidget* widget,
                                   GdkDragContext* drag_context,
                                   DownloadItemDrag* drag) {
  gtk_drag_set_icon_pixbuf(drag_context, drag->pixbuf_, 0, 0);
}

// static
void DownloadItemDrag::OnDragEnd(GtkWidget* widget,
                                 GdkDragContext* drag_context,
                                 DownloadItemDrag* drag) {
  delete drag;
}
<commit_msg>GTK: fix hypothetical leak.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/gtk/download_item_drag.h"

#include "app/gfx/gtk_util.h"
#include "app/gtk_dnd_util.h"
#include "base/string_util.h"
#include "chrome/browser/download/download_manager.h"
#include "googleurl/src/gurl.h"
#include "net/base/net_util.h"
#include "third_party/skia/include/core/SkBitmap.h"

namespace {

const int kCodeMask = GtkDndUtil::TEXT_URI_LIST |
                      GtkDndUtil::CHROME_NAMED_URL;
const GdkDragAction kDragAction = GDK_ACTION_COPY;

void OnDragDataGet(GtkWidget* widget, GdkDragContext* context,
                   GtkSelectionData* selection_data,
                   guint target_type, guint time,
                   DownloadItem* download_item) {
  GURL url = net::FilePathToFileURL(download_item->full_path());
  GtkDndUtil::WriteURLWithName(selection_data, url,
      UTF8ToUTF16(download_item->GetFileName().value()), target_type);
}

} // namespace

// static
void DownloadItemDrag::SetSource(GtkWidget* widget, DownloadItem* item) {
  gtk_drag_source_set(widget, GDK_BUTTON1_MASK, NULL, 0,
                      kDragAction);
  GtkDndUtil::SetSourceTargetListFromCodeMask(widget, kCodeMask);
  g_signal_connect(widget, "drag-data-get",
                   G_CALLBACK(OnDragDataGet), item);
}

// static
void DownloadItemDrag::BeginDrag(const DownloadItem* item, SkBitmap* icon) {
  new DownloadItemDrag(item, icon);
}

DownloadItemDrag::DownloadItemDrag(const DownloadItem* item,
                                   SkBitmap* icon)
    : drag_widget_(gtk_invisible_new()),
      pixbuf_(gfx::GdkPixbufFromSkBitmap(icon)) {
  g_object_ref_sink(drag_widget_);
  g_signal_connect(drag_widget_, "drag-data-get",
                   G_CALLBACK(OnDragDataGet), const_cast<DownloadItem*>(item));
  g_signal_connect(drag_widget_, "drag-begin",
                   G_CALLBACK(OnDragBegin), this);
  g_signal_connect(drag_widget_, "drag-end",
                   G_CALLBACK(OnDragEnd), this);

  GtkTargetList* list = GtkDndUtil::GetTargetListFromCodeMask(kCodeMask);
  GdkEvent* event = gtk_get_current_event();
  gtk_drag_begin(drag_widget_, list, kDragAction, 1, event);
  if (event)
    gdk_event_free(event);
  gtk_target_list_unref(list);
}

DownloadItemDrag::~DownloadItemDrag() {
  g_object_unref(pixbuf_);
  g_object_unref(drag_widget_);
}

// static
void DownloadItemDrag::OnDragBegin(GtkWidget* widget,
                                   GdkDragContext* drag_context,
                                   DownloadItemDrag* drag) {
  gtk_drag_set_icon_pixbuf(drag_context, drag->pixbuf_, 0, 0);
}

// static
void DownloadItemDrag::OnDragEnd(GtkWidget* widget,
                                 GdkDragContext* drag_context,
                                 DownloadItemDrag* drag) {
  delete drag;
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include "InsertSourceBlocks.h"

#include <algorithm>
#include <boost/algorithm/string.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/utility/string_view.hpp>
#include <cstdint>
#include <fstream>
#include <mutex>

#include "ConfigFiles.h"
#include "DexClass.h"
#include "DexStore.h"
#include "IRCode.h"
#include "Macros.h"
#include "PassManager.h"
#include "RedexMappedFile.h"
#include "ScopedCFG.h"
#include "Show.h"
#include "SourceBlocks.h"
#include "Trace.h"
#include "Walkers.h"

using namespace cfg;

namespace {
source_blocks::InsertResult source_blocks(
    DexMethod* method,
    IRCode* code,
    const std::vector<boost::optional<std::string>>& profiles,
    bool serialize,
    bool exc_inject) {
  ScopedCFG cfg(code);
  return source_blocks::insert_source_blocks(method, cfg.get(), profiles,
                                             serialize, exc_inject);
}

using namespace boost::multi_index;

struct ProfileFile {
  RedexMappedFile mapped_file;
  std::string interaction;

  using StringPos = std::pair<size_t, size_t>;

  using MethodMeta = std::unordered_map<const DexMethodRef*, StringPos>;
  MethodMeta method_meta;

  // Consider std::string_view in C++17.
  struct StringViewEquals {
    bool operator()(const std::string& s1, const std::string& s2) const {
      return s1 == s2;
    }
    bool operator()(const std::string& s1, const boost::string_view& v2) const {
      return v2 == s1;
    }
    bool operator()(const boost::string_view& v1, const std::string& s2) const {
      return v1 == s2;
    }
    bool operator()(const boost::string_view& v1,
                    const boost::string_view& v2) const {
      return v1 == v2;
    }
  };
  using UnresolvedMethodMeta = multi_index_container<
      std::pair<boost::string_view, StringPos>,
      indexed_by<hashed_unique<
          member<std::pair<boost::string_view, StringPos>,
                 boost::string_view,
                 &std::pair<boost::string_view, StringPos>::first>,
          boost::hash<boost::string_view>,
          StringViewEquals>>>;

  UnresolvedMethodMeta unresolved_method_meta;

  ProfileFile(RedexMappedFile mapped_file,
              std::string interaction,
              MethodMeta method_meta,
              UnresolvedMethodMeta unresolved_method_meta)
      : mapped_file(std::move(mapped_file)),
        interaction(std::move(interaction)),
        method_meta(std::move(method_meta)),
        unresolved_method_meta(std::move(unresolved_method_meta)) {}

  static std::unique_ptr<ProfileFile> prepare_profile_file(
      const std::string& profile_file_name) {
    if (profile_file_name.empty()) {
      return std::unique_ptr<ProfileFile>();
    }
    auto file = RedexMappedFile::open(profile_file_name, /*read_only=*/true);
    MethodMeta meta;
    UnresolvedMethodMeta unresolved_meta;

    boost::string_view data{file.const_data(), file.size()};
    size_t pos = 0;
    std::string interaction;

    // Read header.
    {
      auto next_line_fn = [&data, &pos]() {
        always_assert(pos < data.size());
        size_t newline_pos = data.find('\n', pos);
        always_assert(newline_pos != std::string::npos);
        auto ret = data.substr(pos, newline_pos - pos);
        pos = newline_pos + 1;
        return ret;
      };
      auto check_components = [](const auto& line, size_t num = 0,
                                 const std::vector<std::string>& exp = {}) {
        std::vector<std::string> split_vec;
        boost::split(split_vec, line, [](const auto& c) { return c == ','; });
        always_assert_log(num == 0 ? split_vec == exp : split_vec.size() == num,
                          "Unexpected line: %s (%s). Expected %s/%zu.",
                          line.to_string().c_str(),
                          boost::join(split_vec, "'").c_str(),
                          boost::join(exp, ",").c_str(), num);
        return split_vec;
      };
      check_components(next_line_fn(), 0, {"interaction", "appear#"});
      {
        auto line = next_line_fn();
        std::vector<std::string> split_vec;
        boost::split(split_vec, line, [](const auto& c) { return c == ','; });
        always_assert(split_vec.size() == 2);
        interaction = std::move(split_vec[0]);
      }
      check_components(next_line_fn(), 0, {"name", "profiled_srcblks_exprs"});
    }

    while (pos < data.length()) {
      const size_t src_pos = pos;

      // Find the next '\n' or EOF.
      size_t linefeed_pos = data.find('\n', src_pos);
      if (linefeed_pos == std::string::npos) {
        linefeed_pos = data.length();
      }
      pos = linefeed_pos + 1;
      // Do not use pos anymore! Ensure by scope from lambda.
      [&data, &src_pos, &linefeed_pos, &meta, &unresolved_meta]() {
        size_t comma_pos = data.find(',', src_pos);
        always_assert(comma_pos < linefeed_pos);

        auto string_pos =
            std::make_pair(comma_pos + 1, linefeed_pos - comma_pos - 1);

        auto method_view = data.substr(src_pos, comma_pos - src_pos);
        // Would be nice to avoid the conversion.
        auto mref = DexMethod::get_method</*kCheckFormat=*/true>(
            method_view.to_string());
        if (mref == nullptr) {
          TRACE(METH_PROF,
                6,
                "failed to resolve %s",
                method_view.to_string().c_str());
          unresolved_meta.emplace(method_view, string_pos);
          return;
        }
        meta.emplace(mref, string_pos);
      }();
    }

    return std::make_unique<ProfileFile>(
        std::move(file), std::move(interaction), std::move(meta),
        std::move(unresolved_meta));
  }
};

void run_source_blocks(
    DexStoresVector& stores,
    ConfigFiles& conf,
    PassManager& mgr,
    bool serialize,
    bool exc_inject,
    std::vector<std::unique_ptr<ProfileFile>>& profile_files) {
  auto scope = build_class_scope(stores);

  std::mutex serialized_guard;
  std::vector<std::pair<const DexMethod*, std::string>> serialized;
  size_t blocks{0};
  size_t profile_count{0};
  auto find_profiles = [&profile_files](const DexMethodRef* mref) {
    if (profile_files.empty()) {
      return std::make_pair(std::vector<boost::optional<std::string>>(), false);
    }
    std::vector<boost::optional<std::string>> profiles;
    bool found_one = false;
    for (auto& profile_file : profile_files) {
      auto it = profile_file->method_meta.find(mref);
      if (it == profile_file->method_meta.end()) {
        profiles.emplace_back(boost::none);
        continue;
      }
      found_one = true;
      const auto& pos = it->second;
      profiles.emplace_back(std::string(
          profile_file->mapped_file.const_data() + pos.first, pos.second));
    }
    if (!found_one) {
      TRACE(METH_PROF, 2, "No basic block profile for %s!", SHOW(mref));
    }
    return std::make_pair(std::move(profiles), found_one);
  };
  walk::parallel::methods(scope, [&](DexMethod* method) {
    auto code = method->get_code();
    if (code != nullptr) {
      auto profiles = find_profiles(method);
      auto res =
          source_blocks(method, code, profiles.first, serialize, exc_inject);
      std::unique_lock<std::mutex> lock(serialized_guard);
      serialized.emplace_back(method, std::move(res.serialized));
      blocks += res.block_count;
      profile_count += profiles.second ? 1 : 0;
    }
  });
  mgr.set_metric("inserted_source_blocks", blocks);
  mgr.set_metric("handled_methods", serialized.size());
  mgr.set_metric("methods_with_profiles", profile_count);

  if (!serialize) {
    return;
  }

  std::sort(serialized.begin(),
            serialized.end(),
            [](const auto& lhs, const auto& rhs) {
              return compare_dexmethods(lhs.first, rhs.first);
            });

  std::ofstream ofs(conf.metafile("redex-source-blocks.csv"));
  ofs << "type,version\nredex-source-blocks,1\nname,serialized\n";
  for (const auto& p : serialized) {
    ofs << show(p.first) << "," << p.second << "\n";
  }
}
} // namespace

void InsertSourceBlocksPass::bind_config() {
  bind("force_serialize",
       m_force_serialize,
       m_force_serialize,
       "Force serialization of the CFGs. Testing only.");
  bind("insert_after_excs", m_insert_after_excs, m_insert_after_excs);
  bind("profile_files", "", m_profile_files);
}

void InsertSourceBlocksPass::run_pass(DexStoresVector& stores,
                                      ConfigFiles& conf,
                                      PassManager& mgr) {
  std::vector<std::unique_ptr<ProfileFile>> profile_files;
  if (!m_profile_files.empty()) {
    std::vector<std::string> files;
    boost::split(files, m_profile_files, [](const auto& c) {
      constexpr char separator =
#if IS_WINDOWS
          ';';
#else
          ':';
#endif
      return c == separator;
    });
    for (const auto& file : files) {
      profile_files.emplace_back(ProfileFile::prepare_profile_file(file));
      TRACE(METH_PROF, 1, "Loaded basic block profile %s",
            profile_files.back()->interaction.c_str());
    }
    // Sort the interactions.
    std::sort(profile_files.begin(), profile_files.end(),
              [](const auto& lhs, const auto& rhs) {
                if (lhs == rhs) {
                  return false;
                }
                if (lhs->interaction == "ColdStart") {
                  return true;
                }
                if (rhs->interaction == "ColdStart") {
                  return false;
                }
                return lhs->interaction < rhs->interaction;
              });
    std::unordered_map<std::string, size_t> indices;
    for (size_t i = 0; i != profile_files.size(); ++i) {
      indices[profile_files[i]->interaction] = i;
    }
    g_redex->set_sb_interaction_index(indices);
  }

  run_source_blocks(stores,
                    conf,
                    mgr,
                    mgr.get_redex_options().instrument_pass_enabled ||
                        m_force_serialize,
                    m_insert_after_excs,
                    profile_files);
}

static InsertSourceBlocksPass s_pass;
<commit_msg>Back out "Enable `InsertSourceBlocks`"<commit_after>/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

#include "InsertSourceBlocks.h"

#include <algorithm>
#include <boost/algorithm/string.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/utility/string_view.hpp>
#include <cstdint>
#include <fstream>
#include <mutex>

#include "ConfigFiles.h"
#include "DexClass.h"
#include "DexStore.h"
#include "IRCode.h"
#include "Macros.h"
#include "PassManager.h"
#include "RedexMappedFile.h"
#include "ScopedCFG.h"
#include "Show.h"
#include "SourceBlocks.h"
#include "Trace.h"
#include "Walkers.h"

using namespace cfg;

namespace {
source_blocks::InsertResult source_blocks(
    DexMethod* method,
    IRCode* code,
    const std::vector<boost::optional<std::string>>& profiles,
    bool serialize,
    bool exc_inject) {
  ScopedCFG cfg(code);
  return source_blocks::insert_source_blocks(method, cfg.get(), profiles,
                                             serialize, exc_inject);
}

using namespace boost::multi_index;

struct ProfileFile {
  RedexMappedFile mapped_file;
  std::string interaction;

  using StringPos = std::pair<size_t, size_t>;

  using MethodMeta = std::unordered_map<const DexMethodRef*, StringPos>;
  MethodMeta method_meta;

  // Consider std::string_view in C++17.
  struct StringViewEquals {
    bool operator()(const std::string& s1, const std::string& s2) const {
      return s1 == s2;
    }
    bool operator()(const std::string& s1, const boost::string_view& v2) const {
      return v2 == s1;
    }
    bool operator()(const boost::string_view& v1, const std::string& s2) const {
      return v1 == s2;
    }
    bool operator()(const boost::string_view& v1,
                    const boost::string_view& v2) const {
      return v1 == v2;
    }
  };
  using UnresolvedMethodMeta = multi_index_container<
      std::pair<boost::string_view, StringPos>,
      indexed_by<hashed_unique<
          member<std::pair<boost::string_view, StringPos>,
                 boost::string_view,
                 &std::pair<boost::string_view, StringPos>::first>,
          boost::hash<boost::string_view>,
          StringViewEquals>>>;

  UnresolvedMethodMeta unresolved_method_meta;

  ProfileFile(RedexMappedFile mapped_file,
              std::string interaction,
              MethodMeta method_meta,
              UnresolvedMethodMeta unresolved_method_meta)
      : mapped_file(std::move(mapped_file)),
        interaction(std::move(interaction)),
        method_meta(std::move(method_meta)),
        unresolved_method_meta(std::move(unresolved_method_meta)) {}

  static std::unique_ptr<ProfileFile> prepare_profile_file(
      const std::string& profile_file_name) {
    if (profile_file_name.empty()) {
      return std::unique_ptr<ProfileFile>();
    }
    auto file = RedexMappedFile::open(profile_file_name, /*read_only=*/true);
    MethodMeta meta;
    UnresolvedMethodMeta unresolved_meta;

    boost::string_view data{file.const_data(), file.size()};
    size_t pos = 0;
    std::string interaction;

    // Read header.
    {
      auto next_line_fn = [&data, &pos]() {
        always_assert(pos < data.size());
        size_t newline_pos = data.find('\n', pos);
        always_assert(newline_pos != std::string::npos);
        auto ret = data.substr(pos, newline_pos - pos);
        pos = newline_pos + 1;
        return ret;
      };
      auto check_components = [](const auto& line, size_t num = 0,
                                 const std::vector<std::string>& exp = {}) {
        std::vector<std::string> split_vec;
        boost::split(split_vec, line, [](const auto& c) { return c == ','; });
        always_assert_log(num == 0 ? split_vec == exp : split_vec.size() == num,
                          "Unexpected line: %s (%s). Expected %s/%zu.",
                          line.to_string().c_str(),
                          boost::join(split_vec, "'").c_str(),
                          boost::join(exp, ",").c_str(), num);
        return split_vec;
      };
      check_components(next_line_fn(), 0, {"interaction", "appear#"});
      {
        auto line = next_line_fn();
        std::vector<std::string> split_vec;
        boost::split(split_vec, line, [](const auto& c) { return c == ','; });
        always_assert(split_vec.size() == 2);
        interaction = std::move(split_vec[0]);
      }
      check_components(next_line_fn(), 0, {"name", "profiled_srcblks_exprs"});
    }

    while (pos < data.length()) {
      const size_t src_pos = pos;

      // Find the next '\n' or EOF.
      size_t linefeed_pos = data.find('\n', src_pos);
      if (linefeed_pos == std::string::npos) {
        linefeed_pos = data.length();
      }
      pos = linefeed_pos + 1;
      // Do not use pos anymore! Ensure by scope from lambda.
      [&data, &src_pos, &linefeed_pos, &meta, &unresolved_meta]() {
        size_t comma_pos = data.find(',', src_pos);
        always_assert(comma_pos < linefeed_pos);

        auto string_pos =
            std::make_pair(comma_pos + 1, linefeed_pos - comma_pos - 1);

        auto method_view = data.substr(src_pos, comma_pos - src_pos);
        // Would be nice to avoid the conversion.
        auto mref = DexMethod::get_method</*kCheckFormat=*/true>(
            method_view.to_string());
        if (mref == nullptr) {
          TRACE(METH_PROF,
                6,
                "failed to resolve %s",
                method_view.to_string().c_str());
          unresolved_meta.emplace(method_view, string_pos);
          return;
        }
        meta.emplace(mref, string_pos);
      }();
    }

    return std::make_unique<ProfileFile>(
        std::move(file), std::move(interaction), std::move(meta),
        std::move(unresolved_meta));
  }
};

void run_source_blocks(
    DexStoresVector& stores,
    ConfigFiles& conf,
    PassManager& mgr,
    bool serialize,
    bool exc_inject,
    std::vector<std::unique_ptr<ProfileFile>>& profile_files) {
  auto scope = build_class_scope(stores);

  std::mutex serialized_guard;
  std::vector<std::pair<const DexMethod*, std::string>> serialized;
  size_t blocks{0};
  size_t profile_count{0};
  auto find_profiles = [&profile_files](const DexMethodRef* mref) {
    if (profile_files.empty()) {
      return std::make_pair(std::vector<boost::optional<std::string>>(), false);
    }
    std::vector<boost::optional<std::string>> profiles;
    bool found_one = false;
    for (auto& profile_file : profile_files) {
      auto it = profile_file->method_meta.find(mref);
      if (it == profile_file->method_meta.end()) {
        profiles.emplace_back(boost::none);
        continue;
      }
      found_one = true;
      const auto& pos = it->second;
      profiles.emplace_back(std::string(
          profile_file->mapped_file.const_data() + pos.first, pos.second));
    }
    if (!found_one) {
      TRACE(METH_PROF, 2, "No basic block profile for %s!", SHOW(mref));
    }
    return std::make_pair(std::move(profiles), found_one);
  };
  walk::parallel::methods(scope, [&](DexMethod* method) {
    auto code = method->get_code();
    if (code != nullptr) {
      auto profiles = find_profiles(method);
      auto res =
          source_blocks(method, code, profiles.first, serialize, exc_inject);
      std::unique_lock<std::mutex> lock(serialized_guard);
      serialized.emplace_back(method, std::move(res.serialized));
      blocks += res.block_count;
      profile_count += profiles.second ? 1 : 0;
    }
  });
  mgr.set_metric("inserted_source_blocks", blocks);
  mgr.set_metric("handled_methods", serialized.size());
  mgr.set_metric("methods_with_profiles", profile_count);

  if (!serialize) {
    return;
  }

  std::sort(serialized.begin(),
            serialized.end(),
            [](const auto& lhs, const auto& rhs) {
              return compare_dexmethods(lhs.first, rhs.first);
            });

  std::ofstream ofs(conf.metafile("redex-source-blocks.csv"));
  ofs << "type,version\nredex-source-blocks,1\nname,serialized\n";
  for (const auto& p : serialized) {
    ofs << show(p.first) << "," << p.second << "\n";
  }
}
} // namespace

void InsertSourceBlocksPass::bind_config() {
  bind("force_serialize",
       m_force_serialize,
       m_force_serialize,
       "Force serialization of the CFGs. Testing only.");
  bind("insert_after_excs", m_insert_after_excs, m_insert_after_excs);
  bind("profile_files", "", m_profile_files);
}

void InsertSourceBlocksPass::run_pass(DexStoresVector& stores,
                                      ConfigFiles& conf,
                                      PassManager& mgr) {
  // TODO(agampe): This should eventually go away. For now, avoid the
  // overhead.
  if (!mgr.get_redex_options().instrument_pass_enabled && !m_force_run) {
    TRACE(METH_PROF,
          1,
          "Not an instrumentation build, not running InsertSourceBlocksPass");
    return;
  }

  std::vector<std::unique_ptr<ProfileFile>> profile_files;
  if (!m_profile_files.empty()) {
    std::vector<std::string> files;
    boost::split(files, m_profile_files, [](const auto& c) {
      constexpr char separator =
#if IS_WINDOWS
          ';';
#else
          ':';
#endif
      return c == separator;
    });
    for (const auto& file : files) {
      profile_files.emplace_back(ProfileFile::prepare_profile_file(file));
      TRACE(METH_PROF, 1, "Loaded basic block profile %s",
            profile_files.back()->interaction.c_str());
    }
    // Sort the interactions.
    std::sort(profile_files.begin(), profile_files.end(),
              [](const auto& lhs, const auto& rhs) {
                if (lhs == rhs) {
                  return false;
                }
                if (lhs->interaction == "ColdStart") {
                  return true;
                }
                if (rhs->interaction == "ColdStart") {
                  return false;
                }
                return lhs->interaction < rhs->interaction;
              });
    std::unordered_map<std::string, size_t> indices;
    for (size_t i = 0; i != profile_files.size(); ++i) {
      indices[profile_files[i]->interaction] = i;
    }
    g_redex->set_sb_interaction_index(indices);
  }

  run_source_blocks(stores,
                    conf,
                    mgr,
                    mgr.get_redex_options().instrument_pass_enabled ||
                        m_force_serialize,
                    m_insert_after_excs,
                    profile_files);
}

static InsertSourceBlocksPass s_pass;
<|endoftext|>


<commit_before>// @(#)root/eve7:$Id$
// Author: Sergey Linev, 27.02.2020

/*************************************************************************
 * Copyright (C) 1995-2020, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT7_REveGeoPainter
#define ROOT7_REveGeoPainter

#include "TVirtualGeoPainter.h"

namespace ROOT {
namespace Experimental {

class REveGeoPainter : public TVirtualGeoPainter {

public:
   REveGeoPainter(TGeoManager *manager);
   virtual ~REveGeoPainter();

   void       AddSize3D(Int_t numpoints, Int_t numsegs, Int_t numpolys) override {}
   TVirtualGeoTrack *AddTrack(Int_t id, Int_t pdgcode, TObject *particle) override { return nullptr; }
   void       AddTrackPoint(Double_t *point, Double_t *box, Bool_t reset=kFALSE) override {}
   virtual void       BombTranslation(const Double_t *tr, Double_t *bombtr) override {}
   virtual void       CheckPoint(Double_t x=0, Double_t y=0, Double_t z=0, Option_t *option="") override {}
   virtual void       CheckShape(TGeoShape *shape, Int_t testNo, Int_t nsamples, Option_t *option) override {}
   virtual void       CheckBoundaryErrors(Int_t ntracks=1000000, Double_t radius=-1.) override {}
   virtual void       CheckBoundaryReference(Int_t icheck=-1) override {}
   virtual void       CheckGeometryFull(Bool_t checkoverlaps=kTRUE, Bool_t checkcrossings=kTRUE, Int_t nrays=10000, const Double_t *vertex=NULL) override {}
   virtual void       CheckGeometry(Int_t nrays, Double_t startx, Double_t starty, Double_t startz) const override {}
   virtual void       CheckOverlaps(const TGeoVolume *vol, Double_t ovlp=0.1, Option_t *option="") const override {}
   virtual Int_t      CountVisibleNodes() override { return 0; }
   virtual void       DefaultAngles() override {}
   virtual void       DefaultColors() override {}
   virtual Int_t      DistanceToPrimitiveVol(TGeoVolume *vol, Int_t px, Int_t py) override { return 0; }
   virtual void       Draw(Option_t *option="") override {}
   virtual void       DrawBatemanSol(TGeoBatemanSol *sol, Option_t *option="") override {}
   virtual void       DrawShape(TGeoShape *shape, Option_t *option="") override {}
   virtual void       DrawOnly(Option_t *option="") override {}
   virtual void       DrawOverlap(void *ovlp, Option_t *option="") override {}
   virtual void       DrawCurrentPoint(Int_t color) override {}
   virtual void       DrawPanel() override {}
   virtual void       DrawPath(const char *path, Option_t *option="") override {}
   virtual void       DrawPolygon(const TGeoPolygon *poly) override {}
   virtual void       DrawVolume(TGeoVolume *vol, Option_t *option="") override {}
   virtual void       EditGeometry(Option_t *option="") override {}
   virtual void       EstimateCameraMove(Double_t /*tmin*/, Double_t /*tmax*/, Double_t *, Double_t * ) override {}
   virtual void       ExecuteShapeEvent(TGeoShape *shape, Int_t event, Int_t px, Int_t py) override {}
   virtual void       ExecuteManagerEvent(TGeoManager *geom, Int_t event, Int_t px, Int_t py) override {}
   virtual void       ExecuteVolumeEvent(TGeoVolume *volume, Int_t event, Int_t px, Int_t py) override {}
   virtual Int_t      GetColor(Int_t base, Float_t light) const override { return 0; }
   virtual Int_t      GetNsegments() const override { return 1; }
   virtual void       GetBombFactors(Double_t &bombx, Double_t &bomby, Double_t &bombz, Double_t &bombr) const override {}
   virtual Int_t      GetBombMode() const override { return 0; }
   virtual const char *GetDrawPath() const override { return ""; }
   virtual TGeoVolume *GetDrawnVolume() const override { return nullptr; }
   virtual TGeoVolume *GetTopVolume() const override { return nullptr; }
   virtual void       GetViewAngles(Double_t &/*longitude*/, Double_t &/*latitude*/, Double_t &/*psi*/) override {}
   virtual Int_t      GetVisLevel() const override { return 0; }
   virtual Int_t      GetVisOption() const override { return 0; }
   virtual const char*GetVolumeInfo(const TGeoVolume *volume, Int_t px, Int_t py) const override { return "info"; }
   virtual void       GrabFocus(Int_t nfr=0, Double_t dlong=0, Double_t dlat=0, Double_t dpsi=0) override {}
   virtual Double_t  *GetViewBox() override { return nullptr; }
   virtual Bool_t     IsPaintingShape() const override { return kFALSE; }
   virtual Bool_t     IsRaytracing() const override { return kFALSE; }
   virtual Bool_t     IsExplodedView() const override { return kFALSE; }
   virtual TH2F      *LegoPlot(Int_t ntheta=60, Double_t themin=0., Double_t themax=180.,
                            Int_t nphi=90, Double_t phimin=0., Double_t phimax=360.,
                            Double_t rmin=0., Double_t rmax=9999999, Option_t *option="") override { return nullptr; }
   virtual void       ModifiedPad(Bool_t update=kFALSE) const override {}
   virtual void       OpProgress(const char *opname, Long64_t current, Long64_t size, TStopwatch *watch=0, Bool_t last=kFALSE, Bool_t refresh=kFALSE, const char *msg="") override {}
   virtual void       Paint(Option_t *option="") override {}
   virtual void       PaintNode(TGeoNode *node, Option_t *option="", TGeoMatrix* global=0) override {}
   virtual void       PaintShape(TGeoShape *shape, Option_t *option="") override {}
   virtual void       PaintOverlap(void *ovlp, Option_t *option="") override {}
   virtual void       PrintOverlaps() const override {}
   virtual void       PaintVolume(TGeoVolume *vol, Option_t *option="", TGeoMatrix* global=0) override {}
   virtual void       RandomPoints(const TGeoVolume *vol, Int_t npoints, Option_t *option="") override {}
   virtual void       RandomRays(Int_t nrays, Double_t startx, Double_t starty, Double_t startz, const char *target_vol, Bool_t check_norm) override {}
   virtual void       Raytrace(Option_t *option="") override {}
   virtual TGeoNode  *SamplePoints(Int_t npoints, Double_t &dist, Double_t epsil, const char* g3path) override { return nullptr; }
   virtual void       SetBombFactors(Double_t bombx=1.3, Double_t bomby=1.3, Double_t bombz=1.3,
                                     Double_t bombr=1.3) override {}
   virtual void       SetClippingShape(TGeoShape *shape) override {}
   virtual void       SetExplodedView(Int_t iopt=0) override {}
   virtual void       SetGeoManager(TGeoManager *geom) override {}
   virtual void       SetIteratorPlugin(TGeoIteratorPlugin *plugin) override {}
   virtual void       SetCheckedNode(TGeoNode *node) override {}
   virtual void       SetNsegments(Int_t nseg=20) override {}
   virtual void       SetNmeshPoints(Int_t npoints) override {}
   virtual void       SetRaytracing(Bool_t flag=kTRUE) override {}
   virtual void       SetTopVisible(Bool_t vis=kTRUE) override {}
   virtual void       SetTopVolume(TGeoVolume *vol) override {}
   virtual void       SetVisLevel(Int_t level=3) override {}
   virtual void       SetVisOption(Int_t option=0) override {}
   virtual Int_t      ShapeDistancetoPrimitive(const TGeoShape *shape, Int_t numpoints, Int_t px, Int_t py) const override { return 0; }
   virtual void       Test(Int_t npoints, Option_t *option) override {}
   virtual void       TestOverlaps(const char *path) override {}
   virtual Bool_t     TestVoxels(TGeoVolume *vol) override { return kFALSE; }
   virtual void       UnbombTranslation(const Double_t *tr, Double_t *bombtr) override {}
   virtual Double_t   Weight(Double_t precision, Option_t *option="v") override { return 0.; }

   ClassDefOverride(REveGeoPainter,0)  // Web-based geo painter
};

} // namespace Experimental
} // namespace ROOT

#endif
<commit_msg>[eve7] suppress compiler warnings from REveGeoPainter<commit_after>// @(#)root/eve7:$Id$
// Author: Sergey Linev, 27.02.2020

/*************************************************************************
 * Copyright (C) 1995-2020, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT7_REveGeoPainter
#define ROOT7_REveGeoPainter

#include "TVirtualGeoPainter.h"

namespace ROOT {
namespace Experimental {

class REveGeoPainter : public TVirtualGeoPainter {

public:
   REveGeoPainter(TGeoManager *manager);
   virtual ~REveGeoPainter();

   void       AddSize3D(Int_t, Int_t, Int_t) override {}
   TVirtualGeoTrack *AddTrack(Int_t, Int_t, TObject *) override { return nullptr; }
   void       AddTrackPoint(Double_t *, Double_t *, Bool_t =kFALSE) override {}
   void       BombTranslation(const Double_t *, Double_t *) override {}
   void       CheckPoint(Double_t =0, Double_t =0, Double_t =0, Option_t * ="") override {}
   void       CheckShape(TGeoShape *, Int_t, Int_t, Option_t *) override {}
   void       CheckBoundaryErrors(Int_t =1000000, Double_t =-1.) override {}
   void       CheckBoundaryReference(Int_t =-1) override {}
   void       CheckGeometryFull(Bool_t =kTRUE, Bool_t =kTRUE, Int_t =10000, const Double_t * = nullptr) override {}
   void       CheckGeometry(Int_t, Double_t, Double_t, Double_t) const override {}
   void       CheckOverlaps(const TGeoVolume *, Double_t =0.1, Option_t * ="") const override {}
   Int_t      CountVisibleNodes() override { return 0; }
   void       DefaultAngles() override {}
   void       DefaultColors() override {}
   Int_t      DistanceToPrimitiveVol(TGeoVolume *, Int_t, Int_t) override { return 0; }
   void       Draw(Option_t * ="") override {}
   void       DrawBatemanSol(TGeoBatemanSol *, Option_t * ="") override {}
   void       DrawShape(TGeoShape *, Option_t * ="") override {}
   void       DrawOnly(Option_t * ="") override {}
   void       DrawOverlap(void *, Option_t * ="") override {}
   void       DrawCurrentPoint(Int_t) override {}
   void       DrawPanel() override {}
   void       DrawPath(const char *, Option_t * ="") override {}
   void       DrawPolygon(const TGeoPolygon *) override {}
   void       DrawVolume(TGeoVolume *, Option_t * ="") override {}
   void       EditGeometry(Option_t * ="") override {}
   void       EstimateCameraMove(Double_t /*tmin*/, Double_t /*tmax*/, Double_t *, Double_t * ) override {}
   void       ExecuteShapeEvent(TGeoShape *, Int_t, Int_t, Int_t) override {}
   void       ExecuteManagerEvent(TGeoManager *, Int_t, Int_t, Int_t) override {}
   void       ExecuteVolumeEvent(TGeoVolume *, Int_t, Int_t, Int_t) override {}
   Int_t      GetColor(Int_t, Float_t) const override { return 0; }
   Int_t      GetNsegments() const override { return 1; }
   void       GetBombFactors(Double_t &, Double_t &, Double_t &, Double_t &) const override {}
   Int_t      GetBombMode() const override { return 0; }
   const char *GetDrawPath() const override { return ""; }
   TGeoVolume *GetDrawnVolume() const override { return nullptr; }
   TGeoVolume *GetTopVolume() const override { return nullptr; }
   void       GetViewAngles(Double_t &/*longitude*/, Double_t &/*latitude*/, Double_t &/*psi*/) override {}
   Int_t      GetVisLevel() const override { return 0; }
   Int_t      GetVisOption() const override { return 0; }
   const char *GetVolumeInfo(const TGeoVolume *, Int_t, Int_t) const override { return "info"; }
   void       GrabFocus(Int_t =0, Double_t =0, Double_t =0, Double_t =0) override {}
   Double_t  *GetViewBox() override { return nullptr; }
   Bool_t     IsPaintingShape() const override { return kFALSE; }
   Bool_t     IsRaytracing() const override { return kFALSE; }
   Bool_t     IsExplodedView() const override { return kFALSE; }
   TH2F      *LegoPlot(Int_t =60, Double_t =0., Double_t =180.,
                       Int_t =90, Double_t =0., Double_t =360.,
                       Double_t =0., Double_t =9999999, Option_t * ="") override { return nullptr; }
   void       ModifiedPad(Bool_t =kFALSE) const override {}
   void       OpProgress(const char *, Long64_t, Long64_t, TStopwatch * =nullptr, Bool_t =kFALSE, Bool_t =kFALSE, const char * ="") override {}
   void       Paint(Option_t * ="") override {}
   void       PaintNode(TGeoNode *, Option_t * ="", TGeoMatrix * = nullptr) override {}
   void       PaintShape(TGeoShape *, Option_t * ="") override {}
   void       PaintOverlap(void*, Option_t * ="") override {}
   void       PrintOverlaps() const override {}
   void       PaintVolume(TGeoVolume *, Option_t * = "", TGeoMatrix * = nullptr) override {}
   void       RandomPoints(const TGeoVolume *, Int_t, Option_t * = "") override {}
   void       RandomRays(Int_t, Double_t, Double_t, Double_t, const char *, Bool_t) override {}
   void       Raytrace(Option_t* = "") override {}
   TGeoNode  *SamplePoints(Int_t, Double_t &, Double_t, const char*) override { return nullptr; }
   void       SetBombFactors(Double_t =1.3, Double_t =1.3, Double_t =1.3, Double_t =1.3) override {}
   void       SetClippingShape(TGeoShape *) override {}
   void       SetExplodedView(Int_t =0) override {}
   void       SetGeoManager(TGeoManager *) override {}
   void       SetIteratorPlugin(TGeoIteratorPlugin *) override {}
   void       SetCheckedNode(TGeoNode *) override {}
   void       SetNsegments(Int_t =20) override {}
   void       SetNmeshPoints(Int_t) override {}
   void       SetRaytracing(Bool_t =kTRUE) override {}
   void       SetTopVisible(Bool_t =kTRUE) override {}
   void       SetTopVolume(TGeoVolume *) override {}
   void       SetVisLevel(Int_t =3) override {}
   void       SetVisOption(Int_t =0) override {}
   Int_t      ShapeDistancetoPrimitive(const TGeoShape *, Int_t, Int_t, Int_t) const override { return 0; }
   void       Test(Int_t, Option_t *) override {}
   void       TestOverlaps(const char *) override {}
   Bool_t     TestVoxels(TGeoVolume *) override { return kFALSE; }
   void       UnbombTranslation(const Double_t *, Double_t *) override {}
   Double_t   Weight(Double_t, Option_t* = "v") override { return 0.; }

   ClassDefOverride(REveGeoPainter,0)  // Web-based geo painter
};

} // namespace Experimental
} // namespace ROOT

#endif
<|endoftext|>


<commit_before>/***************************************************************
 *
 * Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
 * University of Wisconsin-Madison, WI.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you
 * may not use this file except in compliance with the License.  You may
 * obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ***************************************************************/

/* prototype in condor_includes/get_port_range.h */

#include "condor_common.h"
#include "condor_debug.h"
#include "condor_config.h"
#include "get_port_range.h"

int get_port_range(int is_outgoing, int *low_port, int *high_port)
{
	char *low = NULL, *high = NULL;
	int  t_low = 0, t_high = 0;

	// (is_outgoing != 0) means client mode, outgoing connection
	// (is_outgoing == 0) means server mode, incoming connnection

	if (is_outgoing) {
		// first check for the existence of OUT_LOWPORT and OUT_HIGHPORT
		low = param("OUT_LOWPORT");
		if (low) {
			t_low = atoi(low);
			free (low);
			high = param ("OUT_HIGHPORT");
			if (high) {
				t_high = atoi(high);
				free (high);
				dprintf (D_NETWORK, "get_port_range - (OUT_LOWPORT,OUT_HIGHPORT) is (%i,%i).\n", t_low, t_high);
			} else {
				dprintf (D_ALWAYS, "get_port_range - ERROR: OUT_LOWPORT defined but no OUT_HIGHPORT.\n");
				return FALSE;
			}
		}
	} else {
		// first check for the existence of IN_LOWPORT and IN_HIGHPORT
		low = param("IN_LOWPORT");
		if (low) {
			t_low = atoi(low);
			free (low);
			high = param ("IN_HIGHPORT");
			if (high) {
				t_high = atoi(high);
				free (high);
				dprintf (D_NETWORK, "get_port_range - (IN_LOWPORT,IN_HIGHPORT) is (%i,%i).\n", t_low, t_high);
			} else {
				dprintf (D_ALWAYS, "get_port_range - ERROR: IN_LOWPORT defined but no IN_HIGHPORT.\n");
				return FALSE;
			}
		}
	}

	// check if the above settings existed
	if ((t_low == 0) && (t_high == 0)) {
		// fallback to the old LOWPORT and HIGHPORT
		low = param ("LOWPORT");
		if (low) {
			t_low = atoi(low);
			free (low);
			high = param ("HIGHPORT");
			if (high) {
				t_high = atoi(high);
				free (high);
				dprintf (D_NETWORK, "get_port_range - (LOWPORT,HIGHPORT) is (%i,%i).\n", t_low, t_high);
			} else {
				dprintf (D_ALWAYS, "get_port_range - ERROR: LOWPORT defined but no HIGHPORT.\n");
				return FALSE;
			}
		}
	}

	// modify the command line arguments now, since that's how it was and i
	// want to avoid breaking any old code i haven't seen that relies on this
	// side effect (though i haven't seen any) -ZKM
	*low_port = t_low;
	*high_port = t_high;

	// check bounds
    if((*low_port < 0) || (*high_port < 0) || (*low_port > *high_port)) {
        dprintf(D_ALWAYS, "get_port_range - ERROR: invalid port range (%d,%d)\n ",
                           *low_port, *high_port);
        return FALSE;
    }

// windows doesn't have the concept of privileged ports
// on unix, we do print a warning if the range crosses 1024, but it
// is not a fatal error.
#ifndef WIN32
	// check privilege mix (non-fatal)
	if(*low_port < 1024 && *high_port >= 1024) {
		dprintf(D_ALWAYS, "get_port_range - WARNING: port range (%d,%d) "
				"is mix of privileged and non-privileged ports!\n",
				*low_port, *high_port );
	}
#endif

	// return TRUE if we have a valid LOWPORT and HIGHPORT.  if both are zero
	// it means bind to any port, i.e. no port range and we therefore return
	// FALSE.
	if (*low_port || *high_port) {
    	return TRUE;
	} else {
		return FALSE;
	}

}

int
_condor_bind_all_interfaces( void )
{
	int bind_all = FALSE;
	char* tmp = param( "BIND_ALL_INTERFACES" );
	if( ! tmp ) {
			// not defined, defaualts to TRUE;
		return TRUE;
	}
	switch( tmp[0] ) {
	case 'T':
	case 't':
	case 'Y':
	case 'y':
		bind_all = TRUE;
		break;
	default:
		bind_all = FALSE;
		break;
	}
	free( tmp );
	return bind_all;
}

<commit_msg>param+test+atoi -> param_integer w/ test for OUT_LOWPORT, OUT_HIGHPORT, IN_LOWPORT, IN_HIGHPORT, LOWPORT, HIGHPORT<commit_after>/***************************************************************
 *
 * Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
 * University of Wisconsin-Madison, WI.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you
 * may not use this file except in compliance with the License.  You may
 * obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ***************************************************************/

/* prototype in condor_includes/get_port_range.h */

#include "condor_common.h"
#include "condor_debug.h"
#include "condor_config.h"
#include "get_port_range.h"

int get_port_range(int is_outgoing, int *low_port, int *high_port)
{
	int  t_low = 0, t_high = 0;

	// (is_outgoing != 0) means client mode, outgoing connection
	// (is_outgoing == 0) means server mode, incoming connnection

	if (is_outgoing) {
		// first check for the existence of OUT_LOWPORT and OUT_HIGHPORT
		if (param_integer("OUT_LOWPORT", t_low, false, 0)) {
			if (param_integer("OUT_HIGHPORT", t_high, false, 0)) {
				dprintf (D_NETWORK, "get_port_range - (OUT_LOWPORT,OUT_HIGHPORT) is (%i,%i).\n", t_low, t_high);
			} else {
				dprintf (D_ALWAYS, "get_port_range - ERROR: OUT_LOWPORT defined but no OUT_HIGHPORT.\n");
				return FALSE;
			}
		}
	} else {
		// first check for the existence of IN_LOWPORT and IN_HIGHPORT
		if (param_integer("IN_LOWPORT", t_low, false, 0)) {
			if (param_integer("IN_HIGHPORT", t_high, false, 0)) {
				dprintf (D_NETWORK, "get_port_range - (IN_LOWPORT,IN_HIGHPORT) is (%i,%i).\n", t_low, t_high);
			} else {
				dprintf (D_ALWAYS, "get_port_range - ERROR: IN_LOWPORT defined but no IN_HIGHPORT.\n");
				return FALSE;
			}
		}
	}

	// check if the above settings existed
	if ((t_low == 0) && (t_high == 0)) {
		// fallback to the old LOWPORT and HIGHPORT
		if (param_integer("LOWPORT", t_low, false, 0)) {
			if (param_integer("HIGHPORT", t_high, false, 0)) {
				dprintf (D_NETWORK, "get_port_range - (LOWPORT,HIGHPORT) is (%i,%i).\n", t_low, t_high);
			} else {
				dprintf (D_ALWAYS, "get_port_range - ERROR: LOWPORT defined but no HIGHPORT.\n");
				return FALSE;
			}
		}
	}

	// modify the command line arguments now, since that's how it was and i
	// want to avoid breaking any old code i haven't seen that relies on this
	// side effect (though i haven't seen any) -ZKM
	*low_port = t_low;
	*high_port = t_high;

	// check bounds
    if((*low_port < 0) || (*high_port < 0) || (*low_port > *high_port)) {
        dprintf(D_ALWAYS, "get_port_range - ERROR: invalid port range (%d,%d)\n ",
                           *low_port, *high_port);
        return FALSE;
    }

// windows doesn't have the concept of privileged ports
// on unix, we do print a warning if the range crosses 1024, but it
// is not a fatal error.
#ifndef WIN32
	// check privilege mix (non-fatal)
	if(*low_port < 1024 && *high_port >= 1024) {
		dprintf(D_ALWAYS, "get_port_range - WARNING: port range (%d,%d) "
				"is mix of privileged and non-privileged ports!\n",
				*low_port, *high_port );
	}
#endif

	// return TRUE if we have a valid LOWPORT and HIGHPORT.  if both are zero
	// it means bind to any port, i.e. no port range and we therefore return
	// FALSE.
	if (*low_port || *high_port) {
    	return TRUE;
	} else {
		return FALSE;
	}

}

int
_condor_bind_all_interfaces( void )
{
	int bind_all = FALSE;
	char* tmp = param( "BIND_ALL_INTERFACES" );
	if( ! tmp ) {
			// not defined, defaualts to TRUE;
		return TRUE;
	}
	switch( tmp[0] ) {
	case 'T':
	case 't':
	case 'Y':
	case 'y':
		bind_all = TRUE;
		break;
	default:
		bind_all = FALSE;
		break;
	}
	free( tmp );
	return bind_all;
}

<|endoftext|>


<commit_before>#include "tilejson.hpp"
#include "fetch/overzoom.hpp"
#include "fetch/http.hpp"

#include <boost/format.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/property_tree/json_parser.hpp>

#include <curl/curl.h>

#include <mapnik/map.hpp>
#include <mapnik/layer.hpp>
#include <mapnik/feature_layer_desc.hpp>
#include <mapnik/datasource.hpp>

namespace bpt = boost::property_tree;
namespace bal = boost::algorithm;

namespace {

size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata) {
  std::stringstream *stream = static_cast<std::stringstream*>(userdata);
  size_t total_bytes = size * nmemb;
  stream->write(ptr, total_bytes);
  return stream->good() ? total_bytes : 0;
}

#define CURL_SETOPT(curl, opt, arg) { \
  CURLcode res = curl_easy_setopt((curl), (opt), (arg)); \
  if (res != CURLE_OK) { \
    throw std::runtime_error("Unable to set cURL option " #opt); \
  } \
}

struct http_client {
  CURL *m_curl;
  char m_error_buffer[CURL_ERROR_SIZE];

  http_client() : m_curl(curl_easy_init()) {
    if (m_curl == nullptr) {
      throw std::runtime_error("unable to initialise the cURL easy handle");
    }
  }

  ~http_client() {
    if (m_curl != nullptr) {
      curl_easy_cleanup(m_curl);
      m_curl = nullptr;
    }
  }

  long get(const std::string &uri, std::stringstream &stream) {
    CURL_SETOPT(m_curl, CURLOPT_URL, uri.c_str());
    CURL_SETOPT(m_curl, CURLOPT_WRITEFUNCTION, write_callback);
    CURL_SETOPT(m_curl, CURLOPT_WRITEDATA, &stream);
    CURL_SETOPT(m_curl, CURLOPT_ERRORBUFFER, &m_error_buffer[0]);

    CURLcode res = curl_easy_perform(m_curl);
    if (res != CURLE_OK) {
      throw std::runtime_error((boost::format("cURL operation failed: %1%") % m_error_buffer).str());
    }

    long status_code = 0;
    curl_easy_getinfo(m_curl, CURLINFO_RESPONSE_CODE, &status_code);
    return status_code;
  }
};

#undef CURL_SETOPT

} // anonymous namespace

namespace avecado {

bpt::ptree tilejson(const std::string &uri) {
  http_client client;
  std::stringstream data;

  long status_code = client.get(uri, data);
  if ((status_code != 200) &&
      // note: this is a bit of a hack to allow local file paths to work - it
      // seems that curl won't synthesize an HTTP status code, so we need to
      // hack around it.
      ((status_code != 0) || (!bal::starts_with(uri, "file:")))) {
    throw std::runtime_error((boost::format("Unable to fetch TileJSON \"%1%\": HTTP status %2%.") % uri % status_code).str());
  }

  bpt::ptree conf;
  bpt::read_json(data, conf);
  return conf;
}

std::unique_ptr<fetcher> make_tilejson_fetcher(const bpt::ptree &conf) {
  // parameters relating to the overzoom functionality
  int max_zoom = conf.get<int>("maxzoom", 22);
  boost::optional<int> mask_zoom = conf.get_optional<int>("maskLevel");

  // patterns for HTTP fetching
  std::vector<std::string> patterns;
  const bpt::ptree &tile_uris = conf.get_child("tiles");
  for (auto const &pattern : tile_uris) {
    patterns.push_back(pattern.second.data());
  }

  // construct fetchers
  std::unique_ptr<fetcher> http(new fetch::http(std::move(patterns)));
  std::unique_ptr<fetcher> overzoom(new fetch::overzoom(std::move(http), max_zoom, mask_zoom));

  return overzoom;
}

namespace {

struct json_converter : public mapnik::util::static_visitor<> {
  std::ostream &out;

  json_converter(std::ostream &o) : out(o) {}

  void operator()(const mapnik::value_null &) const {
    out << "null";
  }

  void operator()(const mapnik::value_integer &i) const {
    out << i;
  }

  void operator()(const mapnik::value_double &f) const {
    out << std::setprecision(16) << f;
  }

  void operator()(const std::string &s) const {
    out << "\"" << s << "\"";
  }
};

struct force_integer : public mapnik::util::static_visitor<mapnik::value_integer> {
  mapnik::value_integer operator()(const mapnik::value_null &) const {
    return mapnik::value_integer(0);
  }

  mapnik::value_integer operator()(const mapnik::value_integer &i) const {
    return i;
  }

  mapnik::value_integer operator()(const mapnik::value_double &f) const {
    return mapnik::value_integer(f);
  }

  mapnik::value_integer operator()(const std::string &s) const {
    int result = 0;
    if (mapnik::util::string2int(s, result)) {
      return mapnik::value_integer(result);

    } else {
      throw std::runtime_error((boost::format("Could not parse \"%1%\" as integer")
                                % s).str());
    }
  }
};

mapnik::parameters make_default_parameters() {
  mapnik::parameters defaults;

  defaults.emplace(std::string("minzoom"), mapnik::value_integer(0));
  defaults.emplace(std::string("maxzoom"), mapnik::value_integer(0));
  defaults.emplace(std::string("format"), std::string("pbf"));
  defaults.emplace(std::string("name"), std::string("Avecado Development Server"));
  defaults.emplace(std::string("private"), mapnik::value_bool(true));
  defaults.emplace(std::string("scheme"), std::string("xyz"));
  defaults.emplace(std::string("tilejson"), std::string("2.0.0"));

  return defaults;
}

} // anonymous namespace

std::string make_tilejson(const mapnik::Map &map,
                          const std::string &base_url) {
  static const mapnik::parameters defaults = make_default_parameters();

  // TODO: remove super-hacky hard-coded 'JSON' serialiser and use
  // a proper one.
  std::ostringstream out;
  out << "{";

  // copy Mapnik's parameters to make some changes and perhaps add
  // some default values if they're not already present.
  mapnik::parameters params = map.get_extra_parameters();

  // force some parameters to be integers.
  for (auto const &key : {"metatile", "maskLevel", "maxzoom", "minzoom"}) {
    mapnik::parameters::iterator itr = params.find(key);
    if (itr != params.end()) {
      itr->second = mapnik::util::apply_visitor(force_integer(), itr->second);
    }
  }

  // apply some defaults
  for (auto const &row : defaults) {
    mapnik::parameters::iterator itr = params.find(row.first);
    if (itr == params.end()) {
      params.emplace(row);
    }
  }

  // maskLevel is a bit special - we want to default that to maxzoom
  // if it's not already specified.
  {
    mapnik::parameters::iterator itr = params.find("maskLevel");
    if (itr == params.end()) {
      // we're guaranteed maxzoom exists, as it's inserted as a
      // default if it wasn't provided by the Map.
      params.emplace("maskLevel", params.find("maxzoom")->second);
    }
  }

  for (auto const &row : params) {
    out << "\"" << row.first << "\":";
    if (row.first == "center" || row.first == "bounds") {
      out << "[" << row.second << "]";
    } else {
      mapnik::util::apply_visitor(json_converter(out), row.second);
    }
    out << ",";
  }

  out << "\"tiles\": [";
  out << "\"" << base_url << "/{z}/{x}/{y}.pbf\"";
  out << "],";

  out << "\"vector_layers\":[";
  bool first = true;
  for (auto const &layer : map.layers()) {
    if (!layer.active()) {
      continue;
    }

    if (first) {
      first = false;
    } else {
      out << ",";
    }

    out << "{";
    out << "\"id\": \"" << layer.name() << "\",";
    out << "\"description\": \"\","; // layer description

    bool field_first = true;
    mapnik::layer_descriptor desc = layer.datasource()->get_descriptor();
    out << "\"fields\":{";
    for (auto const &attr : desc.get_descriptors()) {
      if (field_first) {
        field_first = false;
      } else {
        out << ",";
      }

      out << "\"" << attr.get_name() << "\": \"\"";
    }
    out << "}}";
  }
  out << "]";

  out << "}";
  return out.str();
}

} // namespace avecado
<commit_msg>Check for membership in an unorrdered set instead of hard-coded or<commit_after>#include "tilejson.hpp"
#include "fetch/overzoom.hpp"
#include "fetch/http.hpp"

#include <boost/format.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/property_tree/json_parser.hpp>

#include <curl/curl.h>

#include <mapnik/map.hpp>
#include <mapnik/layer.hpp>
#include <mapnik/feature_layer_desc.hpp>
#include <mapnik/datasource.hpp>

#include <unordered_set>

namespace bpt = boost::property_tree;
namespace bal = boost::algorithm;

namespace {

size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata) {
  std::stringstream *stream = static_cast<std::stringstream*>(userdata);
  size_t total_bytes = size * nmemb;
  stream->write(ptr, total_bytes);
  return stream->good() ? total_bytes : 0;
}

#define CURL_SETOPT(curl, opt, arg) { \
  CURLcode res = curl_easy_setopt((curl), (opt), (arg)); \
  if (res != CURLE_OK) { \
    throw std::runtime_error("Unable to set cURL option " #opt); \
  } \
}

struct http_client {
  CURL *m_curl;
  char m_error_buffer[CURL_ERROR_SIZE];

  http_client() : m_curl(curl_easy_init()) {
    if (m_curl == nullptr) {
      throw std::runtime_error("unable to initialise the cURL easy handle");
    }
  }

  ~http_client() {
    if (m_curl != nullptr) {
      curl_easy_cleanup(m_curl);
      m_curl = nullptr;
    }
  }

  long get(const std::string &uri, std::stringstream &stream) {
    CURL_SETOPT(m_curl, CURLOPT_URL, uri.c_str());
    CURL_SETOPT(m_curl, CURLOPT_WRITEFUNCTION, write_callback);
    CURL_SETOPT(m_curl, CURLOPT_WRITEDATA, &stream);
    CURL_SETOPT(m_curl, CURLOPT_ERRORBUFFER, &m_error_buffer[0]);

    CURLcode res = curl_easy_perform(m_curl);
    if (res != CURLE_OK) {
      throw std::runtime_error((boost::format("cURL operation failed: %1%") % m_error_buffer).str());
    }

    long status_code = 0;
    curl_easy_getinfo(m_curl, CURLINFO_RESPONSE_CODE, &status_code);
    return status_code;
  }
};

#undef CURL_SETOPT

} // anonymous namespace

namespace avecado {

bpt::ptree tilejson(const std::string &uri) {
  http_client client;
  std::stringstream data;

  long status_code = client.get(uri, data);
  if ((status_code != 200) &&
      // note: this is a bit of a hack to allow local file paths to work - it
      // seems that curl won't synthesize an HTTP status code, so we need to
      // hack around it.
      ((status_code != 0) || (!bal::starts_with(uri, "file:")))) {
    throw std::runtime_error((boost::format("Unable to fetch TileJSON \"%1%\": HTTP status %2%.") % uri % status_code).str());
  }

  bpt::ptree conf;
  bpt::read_json(data, conf);
  return conf;
}

std::unique_ptr<fetcher> make_tilejson_fetcher(const bpt::ptree &conf) {
  // parameters relating to the overzoom functionality
  int max_zoom = conf.get<int>("maxzoom", 22);
  boost::optional<int> mask_zoom = conf.get_optional<int>("maskLevel");

  // patterns for HTTP fetching
  std::vector<std::string> patterns;
  const bpt::ptree &tile_uris = conf.get_child("tiles");
  for (auto const &pattern : tile_uris) {
    patterns.push_back(pattern.second.data());
  }

  // construct fetchers
  std::unique_ptr<fetcher> http(new fetch::http(std::move(patterns)));
  std::unique_ptr<fetcher> overzoom(new fetch::overzoom(std::move(http), max_zoom, mask_zoom));

  return overzoom;
}

namespace {

struct json_converter : public mapnik::util::static_visitor<> {
  std::ostream &out;

  json_converter(std::ostream &o) : out(o) {}

  void operator()(const mapnik::value_null &) const {
    out << "null";
  }

  void operator()(const mapnik::value_integer &i) const {
    out << i;
  }

  void operator()(const mapnik::value_double &f) const {
    out << std::setprecision(16) << f;
  }

  void operator()(const std::string &s) const {
    out << "\"" << s << "\"";
  }
};

struct force_integer : public mapnik::util::static_visitor<mapnik::value_integer> {
  mapnik::value_integer operator()(const mapnik::value_null &) const {
    return mapnik::value_integer(0);
  }

  mapnik::value_integer operator()(const mapnik::value_integer &i) const {
    return i;
  }

  mapnik::value_integer operator()(const mapnik::value_double &f) const {
    return mapnik::value_integer(f);
  }

  mapnik::value_integer operator()(const std::string &s) const {
    int result = 0;
    if (mapnik::util::string2int(s, result)) {
      return mapnik::value_integer(result);

    } else {
      throw std::runtime_error((boost::format("Could not parse \"%1%\" as integer")
                                % s).str());
    }
  }
};

mapnik::parameters make_default_parameters() {
  mapnik::parameters defaults;

  defaults.emplace(std::string("minzoom"), mapnik::value_integer(0));
  defaults.emplace(std::string("maxzoom"), mapnik::value_integer(0));
  defaults.emplace(std::string("format"), std::string("pbf"));
  defaults.emplace(std::string("name"), std::string("Avecado Development Server"));
  defaults.emplace(std::string("private"), mapnik::value_bool(true));
  defaults.emplace(std::string("scheme"), std::string("xyz"));
  defaults.emplace(std::string("tilejson"), std::string("2.0.0"));

  return defaults;
}

} // anonymous namespace

std::string make_tilejson(const mapnik::Map &map,
                          const std::string &base_url) {
  static const mapnik::parameters defaults = make_default_parameters();
  static const std::unordered_set<std::string> array_keys = {"center", "bounds"};

  // TODO: remove super-hacky hard-coded 'JSON' serialiser and use
  // a proper one.
  std::ostringstream out;
  out << "{";

  // copy Mapnik's parameters to make some changes and perhaps add
  // some default values if they're not already present.
  mapnik::parameters params = map.get_extra_parameters();

  // force some parameters to be integers.
  for (auto const &key : {"metatile", "maskLevel", "maxzoom", "minzoom"}) {
    mapnik::parameters::iterator itr = params.find(key);
    if (itr != params.end()) {
      itr->second = mapnik::util::apply_visitor(force_integer(), itr->second);
    }
  }

  // apply some defaults
  for (auto const &row : defaults) {
    mapnik::parameters::iterator itr = params.find(row.first);
    if (itr == params.end()) {
      params.emplace(row);
    }
  }

  // maskLevel is a bit special - we want to default that to maxzoom
  // if it's not already specified.
  {
    mapnik::parameters::iterator itr = params.find("maskLevel");
    if (itr == params.end()) {
      // we're guaranteed maxzoom exists, as it's inserted as a
      // default if it wasn't provided by the Map.
      params.emplace("maskLevel", params.find("maxzoom")->second);
    }
  }

  for (auto const &row : params) {
    out << "\"" << row.first << "\":";
    if (array_keys.count(row.first) > 0) {
      out << "[" << row.second << "]";
    } else {
      mapnik::util::apply_visitor(json_converter(out), row.second);
    }
    out << ",";
  }

  out << "\"tiles\": [";
  out << "\"" << base_url << "/{z}/{x}/{y}.pbf\"";
  out << "],";

  out << "\"vector_layers\":[";
  bool first = true;
  for (auto const &layer : map.layers()) {
    if (!layer.active()) {
      continue;
    }

    if (first) {
      first = false;
    } else {
      out << ",";
    }

    out << "{";
    out << "\"id\": \"" << layer.name() << "\",";
    out << "\"description\": \"\","; // layer description

    bool field_first = true;
    mapnik::layer_descriptor desc = layer.datasource()->get_descriptor();
    out << "\"fields\":{";
    for (auto const &attr : desc.get_descriptors()) {
      if (field_first) {
        field_first = false;
      } else {
        out << ",";
      }

      out << "\"" << attr.get_name() << "\": \"\"";
    }
    out << "}}";
  }
  out << "]";

  out << "}";
  return out.str();
}

} // namespace avecado
<|endoftext|>


<commit_before>///////////////////////////////////////////////////////////////////////////////
// This source file is part of Hect.
//
// Copyright (c) 2014 Colin Hill
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
///////////////////////////////////////////////////////////////////////////////
#include "Material.h"

using namespace hect;

Material::Material()
{
}

Material::Material(const std::string& name) :
    Asset(name)
{
}

AssetHandle<Material> Material::base() const
{
    return _base;
}

void Material::setBase(const AssetHandle<Material>& base)
{
    if (isUploaded())
    {
        renderer().destroyMaterial(*this);
    }
    _base = base;
}

MaterialType Material::type() const
{
    return _type;
}

Material::ShaderModuleSequence Material::shaderModules()
{
    return _shaderModules;
}

const Material::ShaderModuleSequence Material::shaderModules() const
{
    return _shaderModules;
}

Material::ParameterSequence Material::parameters()
{
    if (_base)
    {
        return _base->parameters();
    }
    else
    {
        return _parameters;
    }
}

const Material::ParameterSequence Material::parameters() const
{
    if (_base)
    {
        return _base->parameters();
    }
    else
    {
        return _parameters;
    }
}

const MaterialParameter& Material::parameterWithName(const std::string& name) const
{
    if (_base)
    {
        return _base->parameterWithName(name);
    }
    else
    {
        auto it = _parameterIndices.get(name);
        if (it)
        {
            return _parameters[*it];
        }
        else
        {
            throw Error(format("Material does not have parameter of name '%s'", name.c_str()));
        }
    }
}

const MaterialParameter& Material::parameterWithName(const char* name) const
{
    if (_base)
    {
        return _base->parameterWithName(name);
    }
    else
    {
        auto it = _parameterIndices.get(name);
        if (it)
        {
            return _parameters[*it];
        }
        else
        {
            throw Error(format("Material does not have parameter of name '%s'", name));
        }
    }
}

void Material::setArgument(const MaterialParameter& parameter, MaterialValue value)
{
    size_t index = parameter._index;
    if (index >= _parameterValues.size())
    {
        _parameterValues.resize(index + 1);
    }
    _parameterValues[index] = value;
}

void Material::setArgument(const std::string& parameterName, MaterialValue value)
{
    const MaterialParameter& parameter = parameterWithName(parameterName);
    setArgument(parameter, value);
}

void Material::setArgument(const char* parameterName, MaterialValue value)
{
    const MaterialParameter& parameter = parameterWithName(parameterName);
    setArgument(parameter, value);
}

const MaterialValue& Material::argumentForParameter(const MaterialParameter& parameter) const
{
    size_t index = parameter._index;
    if (index < _parameterValues.size())
    {
        const MaterialValue& value = _parameterValues[index];
        if (value.type() == MaterialValueType_Null && _base)
        {
            return _base->argumentForParameter(parameter);
        }
        else
        {
            return value;
        }
    }
    else if (_base)
    {
        return _base->argumentForParameter(parameter);
    }

    throw Error("No material parameter at the specified index");
}

const RenderState& Material::renderState() const
{
    return _renderState;
}

void Material::setRenderState(const RenderState& renderState)
{
    _renderState = renderState;
}

int Material::priority() const
{
    return _priority;
}

void Material::setPriority(int priority)
{
    _priority = priority;
}

bool Material::operator==(const Material& material) const
{
    (void)material;
    return false;
}

bool Material::operator!=(const Material& material) const
{
    return !(*this == material);
}

void Material::addParameter(const std::string& name, MaterialValueType type, MaterialParameterBinding binding)
{
    if (_base)
    {
        throw Error("Cannot add a parameter to a material with a base");
    }

    if (isUploaded())
    {
        renderer().destroyMaterial(*this);
    }

    auto it = _parameterIndices.get(name);
    if (it)
    {
        throw Error(format("Material already has parameter with name '%s'", name.c_str()));
    }

    size_t index = _parameters.size();
    unsigned textureIndex = nextTextureIndex();

    _parameters.push_back(MaterialParameter(index, textureIndex, name, type, binding));
    _parameterValues.push_back(MaterialValue());
    _parameterIndices.set(name, index);
}

unsigned Material::nextTextureIndex() const
{
    unsigned maxTextureIndex = 0;

    bool firstTexture = true;
    for (const MaterialParameter& parameter : _parameters)
    {
        if (parameter.type() == MaterialValueType_Texture)
        {
            maxTextureIndex = std::max(maxTextureIndex, parameter.textureIndex());
            firstTexture = false;
        }
    }

    return firstTexture ? 0 : (maxTextureIndex + 1);
}

namespace hect
{

Encoder& operator<<(Encoder& encoder, const Material& material)
{
    (void)material;
    throw Error("Unsupported");
}

Decoder& operator>>(Decoder& decoder, Material& material)
{
    // Destroy the material if it is already uploaded
    if (material.isUploaded())
    {
        material.renderer().destroyMaterial(material);
    }

    decoder >> beginObject();

    if (!decoder.isBinaryStream())
    {
        // Base material
        if (decoder.selectMember("base"))
        {
            Path basePath;
            decoder >> decodeValue(basePath);

            // Load the base material
            material._base = decoder.assetCache().getHandle<Material>(basePath);
        }
    }

    if (!material._base)
    {
        // Modules
        if (decoder.selectMember("modules"))
        {
            decoder >> beginArray();
            while (decoder.hasMoreElements())
            {
                ShaderModuleType type;
                Path path;

                decoder >> beginObject()
                        >> decodeEnum("type", type)
                        >> decodeValue("path", path)
                        >> endObject();

                AssetCache& assetCache = decoder.assetCache();
                path = assetCache.resolvePath(path);

                auto stream = assetCache.fileSystem().openFileForRead(path);
                std::string source = stream->readAllToString();

                material._shaderModules.push_back(ShaderModule(type, path, source));
            }
            decoder >> endArray();
        }

        // Parameters
        if (decoder.selectMember("parameters"))
        {
            decoder >> beginArray();
            while (decoder.hasMoreElements())
            {
                decoder >> beginObject();

                std::string name;
                MaterialValueType type = MaterialValueType_Null;
                MaterialParameterBinding binding = MaterialParameterBinding_None;

                decoder >> decodeValue("name", name, true)
                        >> decodeEnum("type", type, false)
                        >> decodeEnum("binding", binding, false);

                decoder >> endObject();

                material.addParameter(name, type, binding);
            }
            decoder >> endArray();
        }
    }

    decoder >> decodeEnum("type", material._type);

    // Arguments
    if (decoder.selectMember("arguments"))
    {
        decoder >> beginArray();
        while (decoder.hasMoreElements())
        {
            decoder >> beginObject();

            std::string name;
            decoder >> decodeValue("name", name, true);

            const MaterialParameter& parameter = material.parameterWithName(name);

            MaterialValue value(parameter.type());
            decoder >> decodeValue(value);
            material.setArgument(parameter, value);

            decoder >> endObject();
        }
        decoder >> endArray();
    }

    decoder >> decodeValue("renderState", material._renderState)
            >> decodeValue("priority", material._priority);

    decoder >> endObject();

    return decoder;
}

}
<commit_msg>Another compiler warning fix<commit_after>///////////////////////////////////////////////////////////////////////////////
// This source file is part of Hect.
//
// Copyright (c) 2014 Colin Hill
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
///////////////////////////////////////////////////////////////////////////////
#include "Material.h"

using namespace hect;

Material::Material()
{
}

Material::Material(const std::string& name) :
    Asset(name)
{
}

AssetHandle<Material> Material::base() const
{
    return _base;
}

void Material::setBase(const AssetHandle<Material>& base)
{
    if (isUploaded())
    {
        renderer().destroyMaterial(*this);
    }
    _base = base;
}

MaterialType Material::type() const
{
    return _type;
}

Material::ShaderModuleSequence Material::shaderModules()
{
    return _shaderModules;
}

const Material::ShaderModuleSequence Material::shaderModules() const
{
    return _shaderModules;
}

Material::ParameterSequence Material::parameters()
{
    if (_base)
    {
        return _base->parameters();
    }
    else
    {
        return _parameters;
    }
}

const Material::ParameterSequence Material::parameters() const
{
    if (_base)
    {
        return _base->parameters();
    }
    else
    {
        return _parameters;
    }
}

const MaterialParameter& Material::parameterWithName(const std::string& name) const
{
    if (_base)
    {
        return _base->parameterWithName(name);
    }
    else
    {
        auto it = _parameterIndices.get(name);
        if (it)
        {
            return _parameters[*it];
        }
        else
        {
            throw Error(format("Material does not have parameter of name '%s'", name.c_str()));
        }
    }
}

const MaterialParameter& Material::parameterWithName(const char* name) const
{
    if (_base)
    {
        return _base->parameterWithName(name);
    }
    else
    {
        auto it = _parameterIndices.get(name);
        if (it)
        {
            return _parameters[*it];
        }
        else
        {
            throw Error(format("Material does not have parameter of name '%s'", name));
        }
    }
}

void Material::setArgument(const MaterialParameter& parameter, MaterialValue value)
{
    size_t index = parameter._index;
    if (index >= _parameterValues.size())
    {
        _parameterValues.resize(index + 1);
    }
    _parameterValues[index] = value;
}

void Material::setArgument(const std::string& parameterName, MaterialValue value)
{
    const MaterialParameter& parameter = parameterWithName(parameterName);
    setArgument(parameter, value);
}

void Material::setArgument(const char* parameterName, MaterialValue value)
{
    const MaterialParameter& parameter = parameterWithName(parameterName);
    setArgument(parameter, value);
}

const MaterialValue& Material::argumentForParameter(const MaterialParameter& parameter) const
{
    size_t index = parameter._index;
    if (index < _parameterValues.size())
    {
        const MaterialValue& value = _parameterValues[index];
        if (value.type() == MaterialValueType_Null && _base)
        {
            return _base->argumentForParameter(parameter);
        }
        else
        {
            return value;
        }
    }
    else if (_base)
    {
        return _base->argumentForParameter(parameter);
    }

    throw Error("No material parameter at the specified index");
}

const RenderState& Material::renderState() const
{
    return _renderState;
}

void Material::setRenderState(const RenderState& renderState)
{
    _renderState = renderState;
}

int Material::priority() const
{
    return _priority;
}

void Material::setPriority(int priority)
{
    _priority = priority;
}

bool Material::operator==(const Material& material) const
{
    (void)material;
    return false;
}

bool Material::operator!=(const Material& material) const
{
    return !(*this == material);
}

void Material::addParameter(const std::string& name, MaterialValueType type, MaterialParameterBinding binding)
{
    if (_base)
    {
        throw Error("Cannot add a parameter to a material with a base");
    }

    if (isUploaded())
    {
        renderer().destroyMaterial(*this);
    }

    auto it = _parameterIndices.get(name);
    if (it)
    {
        throw Error(format("Material already has parameter with name '%s'", name.c_str()));
    }

    size_t index = _parameters.size();
    unsigned textureIndex = nextTextureIndex();

    _parameters.push_back(MaterialParameter(index, textureIndex, name, type, binding));
    _parameterValues.push_back(MaterialValue());
    _parameterIndices.set(name, index);
}

unsigned Material::nextTextureIndex() const
{
    unsigned maxTextureIndex = 0;

    bool firstTexture = true;
    for (const MaterialParameter& parameter : _parameters)
    {
        if (parameter.type() == MaterialValueType_Texture)
        {
            maxTextureIndex = std::max(maxTextureIndex, parameter.textureIndex());
            firstTexture = false;
        }
    }

    return firstTexture ? 0 : (maxTextureIndex + 1);
}

namespace hect
{

Encoder& operator<<(Encoder& encoder, const Material& material)
{
    (void)encoder;
    (void)material;
    throw Error("Unsupported");
}

Decoder& operator>>(Decoder& decoder, Material& material)
{
    // Destroy the material if it is already uploaded
    if (material.isUploaded())
    {
        material.renderer().destroyMaterial(material);
    }

    decoder >> beginObject();

    if (!decoder.isBinaryStream())
    {
        // Base material
        if (decoder.selectMember("base"))
        {
            Path basePath;
            decoder >> decodeValue(basePath);

            // Load the base material
            material._base = decoder.assetCache().getHandle<Material>(basePath);
        }
    }

    if (!material._base)
    {
        // Modules
        if (decoder.selectMember("modules"))
        {
            decoder >> beginArray();
            while (decoder.hasMoreElements())
            {
                ShaderModuleType type;
                Path path;

                decoder >> beginObject()
                        >> decodeEnum("type", type)
                        >> decodeValue("path", path)
                        >> endObject();

                AssetCache& assetCache = decoder.assetCache();
                path = assetCache.resolvePath(path);

                auto stream = assetCache.fileSystem().openFileForRead(path);
                std::string source = stream->readAllToString();

                material._shaderModules.push_back(ShaderModule(type, path, source));
            }
            decoder >> endArray();
        }

        // Parameters
        if (decoder.selectMember("parameters"))
        {
            decoder >> beginArray();
            while (decoder.hasMoreElements())
            {
                decoder >> beginObject();

                std::string name;
                MaterialValueType type = MaterialValueType_Null;
                MaterialParameterBinding binding = MaterialParameterBinding_None;

                decoder >> decodeValue("name", name, true)
                        >> decodeEnum("type", type, false)
                        >> decodeEnum("binding", binding, false);

                decoder >> endObject();

                material.addParameter(name, type, binding);
            }
            decoder >> endArray();
        }
    }

    decoder >> decodeEnum("type", material._type);

    // Arguments
    if (decoder.selectMember("arguments"))
    {
        decoder >> beginArray();
        while (decoder.hasMoreElements())
        {
            decoder >> beginObject();

            std::string name;
            decoder >> decodeValue("name", name, true);

            const MaterialParameter& parameter = material.parameterWithName(name);

            MaterialValue value(parameter.type());
            decoder >> decodeValue(value);
            material.setArgument(parameter, value);

            decoder >> endObject();
        }
        decoder >> endArray();
    }

    decoder >> decodeValue("renderState", material._renderState)
            >> decodeValue("priority", material._priority);

    decoder >> endObject();

    return decoder;
}

}
<|endoftext|>


<commit_before>// ======================================================================== //
// Copyright 2009-2016 Intel Corporation                                    //
//                                                                          //
// Licensed under the Apache License, Version 2.0 (the "License");          //
// you may not use this file except in compliance with the License.         //
// You may obtain a copy of the License at                                  //
//                                                                          //
//     http://www.apache.org/licenses/LICENSE-2.0                           //
//                                                                          //
// Unless required by applicable law or agreed to in writing, software      //
// distributed under the License is distributed on an "AS IS" BASIS,        //
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
// See the License for the specific language governing permissions and      //
// limitations under the License.                                           //
// ======================================================================== //

#include <chrono>
#include <atomic>
#include <thread>
#include "BatchedIsendIrecvMessaging.h"

namespace ospray {
  namespace mpi {
    namespace async {

      enum { SEND_WINDOW_SIZE = 48 };
      enum { RECV_WINDOW_SIZE = 48 };
      enum { PROC_WINDOW_SIZE = 20 };

      BatchedIsendIrecvImpl::Group::Group(const std::string &name, MPI_Comm comm,
                                       Consumer *consumer, int32 tag)
        : async::Group(comm,consumer,tag),
          sendThread(this), recvThread(this), procThread(this), shouldExit(false)
      {
        recvThread.start();
        sendThread.start();
        procThread.start();
      }

      void BatchedIsendIrecvImpl::SendThread::run()
      {
        Group  *g = this->group;
        Action *actions[SEND_WINDOW_SIZE];
        MPI_Request request[SEND_WINDOW_SIZE];
        while (1) {
          // usleep(80);
          size_t numActions = 0;
          while (numActions == 0){
            numActions = g->sendQueue.getSome(actions,SEND_WINDOW_SIZE);
            if (g->shouldExit.load()){
              return;
            }
          }
          for (int i=0;i<numActions;i++) {
            Action *action = actions[i];
            MPI_CALL(Isend(action->data,action->size,MPI_BYTE,
                           action->addr.rank,g->tag,g->comm,&request[i]));
          }

          // TODO: Is it ok to wait even if we're exiting? Maybe we'd just get send
          // failed statuses back?
          MPI_CALL(Waitall(numActions,request,MPI_STATUSES_IGNORE));

          for (int i=0;i<numActions;i++) {
            Action *action = actions[i];
            free(action->data);
            delete action;
          }
        }
      }

      void BatchedIsendIrecvImpl::RecvThread::run()
      {
        // note this thread not only _probes_ for new receives, it
        // also immediately starts the receive operation using Irecv()
        Group *g = (Group *)this->group;

        MPI_Request request[RECV_WINDOW_SIZE];
        Action *actions[RECV_WINDOW_SIZE];
        MPI_Status status;
        int numRequests = 0;

        while (1) {
          numRequests = 0;
          // wait for first message
          {
            // usleep(280);
            int msgAvail = 0;
            while (!msgAvail) {
              MPI_CALL(Iprobe(MPI_ANY_SOURCE,g->tag,g->comm,&msgAvail,&status));
              if (g->shouldExit.load()){
                return;
              }
              std::this_thread::sleep_for(std::chrono::milliseconds(1));
            }
            //MPI_CALL(Probe(MPI_ANY_SOURCE,g->tag,g->comm,&status));
            Action *action = new Action;
            action->addr = Address(g,status.MPI_SOURCE);
            MPI_CALL(Get_count(&status,MPI_BYTE,&action->size));

            action->data = malloc(action->size);
            MPI_CALL(Irecv(action->data,action->size,MPI_BYTE,
                           status.MPI_SOURCE,status.MPI_TAG,
                           g->comm,&request[numRequests]));
            actions[numRequests++] = action;
          }
          // ... and add all the other ones that are outstanding, up
          // to max window size
          while (numRequests < RECV_WINDOW_SIZE) {
            int msgAvail;
            MPI_CALL(Iprobe(MPI_ANY_SOURCE,g->tag,g->comm,&msgAvail,&status));
            if (!msgAvail)
              break;

            Action *action = new Action;
            action->addr = Address(g,status.MPI_SOURCE);
            MPI_CALL(Get_count(&status,MPI_BYTE,&action->size));

            action->data = malloc(action->size);
            MPI_CALL(Irecv(action->data,action->size,MPI_BYTE,
                           status.MPI_SOURCE,status.MPI_TAG,
                           g->comm,&request[numRequests]));
            actions[numRequests++] = action;
          }

          // TODO: Is it ok to wait even if we're exiting? Maybe we'd just get send
          // failed statuses back?
          // now, have certain number of messages available...
          MPI_CALL(Waitall(numRequests,request,MPI_STATUSES_IGNORE));

          // OK, all actions are valid now
          g->recvQueue.putSome(&actions[0],numRequests);
        }
      }

      void BatchedIsendIrecvImpl::ProcThread::run()
      {
        Group *g = (Group *)this->group;
        while (1) {
          Action *actions[PROC_WINDOW_SIZE];
          size_t numActions = 0;
          while (numActions == 0){
            numActions = g->recvQueue.getSome(actions,PROC_WINDOW_SIZE);
            if (g->shouldExit.load()){
              return;
            }
          }
          for (int i=0;i<numActions;i++) {
            Action *action = actions[i];
            g->consumer->process(action->addr,action->data,action->size);
            delete action;
          }
        }
      }

      void BatchedIsendIrecvImpl::Group::shutdown()
      {
        std::cout << "#osp:mpi:BatchIsendIrecvMessaging:Group shutting down" << std::endl;
        shouldExit.store(true);
        sendThread.join();
        recvThread.join();
        procThread.join();
      }

      void BatchedIsendIrecvImpl::init()
      {
        mpi::world.barrier();
        printf("#osp:mpi:BatchedIsendIrecvMessaging started up %i/%i\n",
               mpi::world.rank,mpi::world.size);
        fflush(0);
        mpi::world.barrier();
      }

      void BatchedIsendIrecvImpl::shutdown()
      {
        mpi::world.barrier();
        printf("#osp:mpi:BatchedIsendIrecvMessaging shutting down %i/%i\n",
               mpi::world.rank,mpi::world.size);
        fflush(0);
        mpi::world.barrier();
        for (int i=0;i<myGroups.size();i++)
          myGroups[i]->shutdown();

        MPI_CALL(Finalize());
      }

      async::Group *BatchedIsendIrecvImpl::createGroup(const std::string &name,
                                                    MPI_Comm comm,
                                                    Consumer *consumer,
                                                    int32 tag)
      {
        Group *g = new Group(name,comm,consumer,tag);
        myGroups.push_back(g);
        return g;
      }

      void BatchedIsendIrecvImpl::send(const Address &dest,
                                       void *msgPtr,
                                       int32 msgSize)
      {
        Action *action = new Action;
        action->addr   = dest;
        action->data   = msgPtr;
        action->size   = msgSize;

        Group *g = (Group *)dest.group;
        g->sendQueue.put(action);
      }

    } // ::ospray::mpi::async
  } // ::ospray::mpi
} // ::ospray
<commit_msg>Remove the commented out Probe call<commit_after>// ======================================================================== //
// Copyright 2009-2016 Intel Corporation                                    //
//                                                                          //
// Licensed under the Apache License, Version 2.0 (the "License");          //
// you may not use this file except in compliance with the License.         //
// You may obtain a copy of the License at                                  //
//                                                                          //
//     http://www.apache.org/licenses/LICENSE-2.0                           //
//                                                                          //
// Unless required by applicable law or agreed to in writing, software      //
// distributed under the License is distributed on an "AS IS" BASIS,        //
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
// See the License for the specific language governing permissions and      //
// limitations under the License.                                           //
// ======================================================================== //

#include <chrono>
#include <atomic>
#include <thread>
#include "BatchedIsendIrecvMessaging.h"

namespace ospray {
  namespace mpi {
    namespace async {

      enum { SEND_WINDOW_SIZE = 48 };
      enum { RECV_WINDOW_SIZE = 48 };
      enum { PROC_WINDOW_SIZE = 20 };

      BatchedIsendIrecvImpl::Group::Group(const std::string &name, MPI_Comm comm,
                                       Consumer *consumer, int32 tag)
        : async::Group(comm,consumer,tag),
          sendThread(this), recvThread(this), procThread(this), shouldExit(false)
      {
        recvThread.start();
        sendThread.start();
        procThread.start();
      }

      void BatchedIsendIrecvImpl::SendThread::run()
      {
        Group  *g = this->group;
        Action *actions[SEND_WINDOW_SIZE];
        MPI_Request request[SEND_WINDOW_SIZE];
        while (1) {
          // usleep(80);
          size_t numActions = 0;
          while (numActions == 0){
            numActions = g->sendQueue.getSome(actions,SEND_WINDOW_SIZE);
            if (g->shouldExit.load()){
              return;
            }
          }
          for (int i=0;i<numActions;i++) {
            Action *action = actions[i];
            MPI_CALL(Isend(action->data,action->size,MPI_BYTE,
                           action->addr.rank,g->tag,g->comm,&request[i]));
          }

          // TODO: Is it ok to wait even if we're exiting? Maybe we'd just get send
          // failed statuses back?
          MPI_CALL(Waitall(numActions,request,MPI_STATUSES_IGNORE));

          for (int i=0;i<numActions;i++) {
            Action *action = actions[i];
            free(action->data);
            delete action;
          }
        }
      }

      void BatchedIsendIrecvImpl::RecvThread::run()
      {
        // note this thread not only _probes_ for new receives, it
        // also immediately starts the receive operation using Irecv()
        Group *g = (Group *)this->group;

        MPI_Request request[RECV_WINDOW_SIZE];
        Action *actions[RECV_WINDOW_SIZE];
        MPI_Status status;
        int numRequests = 0;

        while (1) {
          numRequests = 0;
          // wait for first message
          {
            // usleep(280);
            int msgAvail = 0;
            while (!msgAvail) {
              MPI_CALL(Iprobe(MPI_ANY_SOURCE,g->tag,g->comm,&msgAvail,&status));
              if (g->shouldExit.load()){
                return;
              }
              std::this_thread::sleep_for(std::chrono::milliseconds(1));
            }
            Action *action = new Action;
            action->addr = Address(g,status.MPI_SOURCE);
            MPI_CALL(Get_count(&status,MPI_BYTE,&action->size));

            action->data = malloc(action->size);
            MPI_CALL(Irecv(action->data,action->size,MPI_BYTE,
                           status.MPI_SOURCE,status.MPI_TAG,
                           g->comm,&request[numRequests]));
            actions[numRequests++] = action;
          }
          // ... and add all the other ones that are outstanding, up
          // to max window size
          while (numRequests < RECV_WINDOW_SIZE) {
            int msgAvail;
            MPI_CALL(Iprobe(MPI_ANY_SOURCE,g->tag,g->comm,&msgAvail,&status));
            if (!msgAvail)
              break;

            Action *action = new Action;
            action->addr = Address(g,status.MPI_SOURCE);
            MPI_CALL(Get_count(&status,MPI_BYTE,&action->size));

            action->data = malloc(action->size);
            MPI_CALL(Irecv(action->data,action->size,MPI_BYTE,
                           status.MPI_SOURCE,status.MPI_TAG,
                           g->comm,&request[numRequests]));
            actions[numRequests++] = action;
          }

          // TODO: Is it ok to wait even if we're exiting? Maybe we'd just get send
          // failed statuses back?
          // now, have certain number of messages available...
          MPI_CALL(Waitall(numRequests,request,MPI_STATUSES_IGNORE));

          // OK, all actions are valid now
          g->recvQueue.putSome(&actions[0],numRequests);
        }
      }

      void BatchedIsendIrecvImpl::ProcThread::run()
      {
        Group *g = (Group *)this->group;
        while (1) {
          Action *actions[PROC_WINDOW_SIZE];
          size_t numActions = 0;
          while (numActions == 0){
            numActions = g->recvQueue.getSome(actions,PROC_WINDOW_SIZE);
            if (g->shouldExit.load()){
              return;
            }
          }
          for (int i=0;i<numActions;i++) {
            Action *action = actions[i];
            g->consumer->process(action->addr,action->data,action->size);
            delete action;
          }
        }
      }

      void BatchedIsendIrecvImpl::Group::shutdown()
      {
        std::cout << "#osp:mpi:BatchIsendIrecvMessaging:Group shutting down" << std::endl;
        shouldExit.store(true);
        sendThread.join();
        recvThread.join();
        procThread.join();
      }

      void BatchedIsendIrecvImpl::init()
      {
        mpi::world.barrier();
        printf("#osp:mpi:BatchedIsendIrecvMessaging started up %i/%i\n",
               mpi::world.rank,mpi::world.size);
        fflush(0);
        mpi::world.barrier();
      }

      void BatchedIsendIrecvImpl::shutdown()
      {
        mpi::world.barrier();
        printf("#osp:mpi:BatchedIsendIrecvMessaging shutting down %i/%i\n",
               mpi::world.rank,mpi::world.size);
        fflush(0);
        mpi::world.barrier();
        for (int i=0;i<myGroups.size();i++)
          myGroups[i]->shutdown();

        MPI_CALL(Finalize());
      }

      async::Group *BatchedIsendIrecvImpl::createGroup(const std::string &name,
                                                    MPI_Comm comm,
                                                    Consumer *consumer,
                                                    int32 tag)
      {
        Group *g = new Group(name,comm,consumer,tag);
        myGroups.push_back(g);
        return g;
      }

      void BatchedIsendIrecvImpl::send(const Address &dest,
                                       void *msgPtr,
                                       int32 msgSize)
      {
        Action *action = new Action;
        action->addr   = dest;
        action->data   = msgPtr;
        action->size   = msgSize;

        Group *g = (Group *)dest.group;
        g->sendQueue.put(action);
      }

    } // ::ospray::mpi::async
  } // ::ospray::mpi
} // ::ospray
<|endoftext|>