<commit_before>/*
 Copyright (c) 2018 Anon authors, see AUTHORS file.

 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 "aws_sqs.h"
#include <aws/sqs/model/QueueAttributeName.h>
#include <aws/sqs/model/SendMessageRequest.h>

using namespace Aws::SQS;
using json = nlohmann::json;

aws_sqs_listener::aws_sqs_listener(const std::shared_ptr<Aws::Auth::AWSCredentialsProvider> &provider,
                                   const Aws::Client::ClientConfiguration &client_config,
                                   const Aws::String &queue_url,
                                   const std::function<bool(const Aws::SQS::Model::Message &m)> &handler,
                                   bool single_concurrent_message,
                                   size_t stack_size)
    : _client(provider, client_config),
      _queue_url(queue_url),
      _num_fibers(0),
      _exit_now(false),
      _process_msg(handler),
      _consecutive_errors(0),
      _single_concurrent_message(single_concurrent_message),
      _stack_size(stack_size),
      _continue_after_timeout([]{return true;})
{
}

aws_sqs_listener::aws_sqs_listener(const std::shared_ptr<Aws::Auth::AWSCredentialsProvider> &provider,
                                   const Aws::Client::ClientConfiguration &client_config,
                                   const Aws::String &queue_url,
                                   const std::function<bool(const Aws::SQS::Model::Message &m, const std::function<void()>&)> &handler,
                                   bool single_concurrent_message,
                                   size_t stack_size)
    : _client(provider, client_config),
      _queue_url(queue_url),
      _num_fibers(0),
      _exit_now(false),
      _process_msg_del(handler),
      _consecutive_errors(0),
      _single_concurrent_message(single_concurrent_message),
      _stack_size(stack_size),
      _continue_after_timeout([]{return true;})
{
}

void aws_sqs_listener::start()
{
  std::weak_ptr<aws_sqs_listener> wp = shared_from_this();

  fiber::run_in_fiber(
      [wp] {
        auto ths = wp.lock();
        if (ths)
          ths->start_listen();
      },
      aws_sqs_listener::_simple_stack_size, "aws_sqs_listener::aws_sqs_listener, start_listen");

  #if defined(ANON_DEBUG_TIMERS)
  anon_log("io_dispatch::schedule_task, aws_sqs_listener::start");
  #endif
  _timer_task = io_dispatch::schedule_task(
      [wp] {
        fiber::run_in_fiber(
            [wp] {
              auto ths = wp.lock();
              if (ths)
                ths->set_visibility_timeout();
            },
            aws_sqs_listener::_simple_stack_size, "aws_sqs_listener, set_visibility_timeout sweeper");
      },
      cur_time() + visibility_sweep_time);
}

aws_sqs_listener::~aws_sqs_listener()
{
  {
    _exit_now = true;
    fiber_lock l(_mtx);
    while (_num_fibers > 0)
      _num_fibers_cond.wait(l);
  }
  io_dispatch::remove_task(_timer_task);
}

std::function<bool(const Aws::SQS::Model::Message &m)> aws_sqs_listener::js_wrap(const std::function<bool(const Aws::SQS::Model::Message &m, const nlohmann::json &body)> &fn)
{
  return [fn](const Aws::SQS::Model::Message &m) -> bool {
    std::string body = get_body(m);
    try
    {
      json body_js = json::parse(body.begin(), body.end());
      try
      {
        return fn(m, body_js);
      }
      catch (const inval_message& exc)
      {
        anon_log_error("caught exception processing message: " << exc.what() << ", message body: '" << body << "'");
        return true;
      }
      catch (const std::exception &exc)
      {
        anon_log_error("caught exception processing message: " << exc.what() << ", message body: '" << body << "'");
        return false;
      }
      catch (...)
      {
        anon_log_error("caught unknown exception processing message, message body: '" << body << "'");
        return false;
      }
    }
    catch (const std::exception &exc)
    {
      anon_log_error("caught exception parsing message: " << exc.what() << ", message body: '" << body << "'");
      return true;
    }
    catch (...)
    {
      anon_log_error("caught unknown exception parsing message, message body: '" << body << "'");
      return true;
    }
  };
}

std::function<bool(const Aws::SQS::Model::Message &m, const std::function<void()>& del)> aws_sqs_listener::js_wrap(const std::function<bool(const Aws::SQS::Model::Message &m, const std::function<void()>& del, const nlohmann::json &body)> &fn)
{
  return [fn](const Aws::SQS::Model::Message &m, const std::function<void()>& del) -> bool {
    std::string body = get_body(m);
    try
    {
      json body_js = json::parse(body.begin(), body.end());
      try
      {
        return fn(m, del, body_js);
      }
      catch (const inval_message& exc)
      {
        anon_log_error("caught exception processing message: " << exc.what() << ", message body: '" << body << "'");
        del();
        return true;
      }
      catch (const std::exception &exc)
      {
        anon_log_error("caught exception processing message: " << exc.what() << ", message body: '" << body << "'");
        return false;
      }
      catch (...)
      {
        anon_log_error("caught unknown exception processing message, message body: '" << body << "'");
        return false;
      }
    }
    catch (const std::exception &exc)
    {
      anon_log_error("caught exception parsing message: " << exc.what() << ", message body: '" << body << "'");
      del();
      return true;
    }
    catch (...)
    {
      anon_log_error("caught unknown exception parsing message, message body: '" << body << "'");
      del();
      return true;
    }
  };
}

void aws_sqs_listener::start_listen()
{
  Model::ReceiveMessageRequest req;
  req.WithQueueUrl(_queue_url).WithMaxNumberOfMessages(_single_concurrent_message ? 1 : max_messages_per_read).WithWaitTimeSeconds(read_wait_time);
  Aws::Vector<Model::QueueAttributeName> att;
  att.push_back(Model::QueueAttributeName::All);
  req.WithAttributeNames(std::move(att));
  std::weak_ptr<aws_sqs_listener> wp = shared_from_this();
  _client.ReceiveMessageAsync(req, [wp](const SQSClient *, const Model::ReceiveMessageRequest &, const Model::ReceiveMessageOutcome &out, const std::shared_ptr<const Aws::Client::AsyncCallerContext> &) {
    auto ths = wp.lock();
    if (!ths)
      return;
    fiber::rename_fiber("aws_sqs_listener::start_listen, ReceiveMessageAsync");
    if (!out.IsSuccess())
    {
      ++ths->_consecutive_errors;
      if (ths->_consecutive_errors > 10)
      {
        anon_log_error("SQS ReceiveMessage failed, _consecutive_errors: " << ths->_consecutive_errors << "\n"
                                                                          << out.GetError());
      }
      else
      {
        anon_log("SQS ReceiveMessage failed, _consecutive_errors: " << ths->_consecutive_errors);
      }

      fiber::msleep(2000);
    }
    else
    {
      ths->_consecutive_errors = 0;
      auto &messages = out.GetResult().GetMessages();
      auto num_messages = messages.size();

      if (num_messages > 0)
      {
        ths->_num_fibers += num_messages;
        for (auto &m : messages)
          fiber::run_in_fiber(
              [wp, m] {
                auto ths = wp.lock();
                if (!ths)
                  return;
                ths->add_to_keep_alive(m);
                bool success;
                if (ths->_process_msg) {
                  success = ths->_process_msg(m);
                  if (success)
                    ths->delete_message(m);
                }
                else
                  success = ths->_process_msg_del(m, [wp, m] {
                    auto ths = wp.lock();
                    if (ths)
                      ths->delete_message(m);
                  });
                if (!success)
                  ths->remove_from_keep_alive(m, true);
                if (ths->_single_concurrent_message && !ths->_exit_now)
                  ths->start_listen();
              },
              ths->_stack_size, "aws_sqs_listener, process_msg");
      } else {
        if (!ths->_continue_after_timeout())
          ths->_exit_now = true;
      }
    }

    if (ths->_consecutive_errors < 1000)
    {
      if (!ths->_single_concurrent_message && !ths->_exit_now)
      {
        fiber_lock l(ths->_mtx);
        while (ths->_num_fibers >= max_in_flight_fibers)
          ths->_num_fibers_cond.wait(l);
        fiber::run_in_fiber(
            [wp] {
              auto ths = wp.lock();
              if (ths)
                ths->start_listen();
            },
            aws_sqs_listener::_simple_stack_size, "aws_sqs_listener, restart_listen");
      }
    }
    else
      anon_log_error("too many consecutive errors, giving up...");
  });
}

void aws_sqs_listener::set_visibility_timeout()
{
  fiber_lock l(_mtx);
  auto numMessages = _alive_set.size();
  if (numMessages > 0)
  {
    Model::ChangeMessageVisibilityBatchRequest req;
    Aws::Vector<Aws::Vector<Model::ChangeMessageVisibilityBatchRequestEntry>> entries_v;
    int index = 0;
    for (auto it : _alive_set)
    {
      Model::ChangeMessageVisibilityBatchRequestEntry ent;
      std::ostringstream str;
      if (index % 10 == 0)
        entries_v.push_back(Aws::Vector<Model::ChangeMessageVisibilityBatchRequestEntry>());
      str << "message_" << ++index;
      ent.WithReceiptHandle(it.first).WithVisibilityTimeout(visibility_time).WithId(str.str());
      entries_v.back().push_back(ent);
    }
    for (auto &entries : entries_v)
    {
      req.WithQueueUrl(_queue_url).WithEntries(entries);
      auto nMessages = entries.size();
      _client.ChangeMessageVisibilityBatchAsync(req, [nMessages](const SQSClient *, const Model::ChangeMessageVisibilityBatchRequest &, const Model::ChangeMessageVisibilityBatchOutcome &out, const std::shared_ptr<const Aws::Client::AsyncCallerContext> &) {
        fiber::rename_fiber("aws_sqs_listener::set_visibility_timeout, ChangeMessageVisibilityBatchAsync");
        if (out.IsSuccess())
        {
          anon_log("batch visibilty reset for " << nMessages << " messages");
        }
        else
        {
          do_error("batch reset visibility for " << nMessages << " messages: " << out.GetError().GetMessage());
        }
      });
    }
  }

  // schedule the sweep to run again in visibility_sweep_time seconds
  std::weak_ptr<aws_sqs_listener> wp = shared_from_this();
  #if defined(ANON_DEBUG_TIMERS)
  anon_log("io_dispatch::schedule_task, aws_sqs_listener::set_visibility_timeout");
  #endif
  _timer_task = io_dispatch::schedule_task(
      [wp] {
        fiber::run_in_fiber(
            [wp] {
              auto ths = wp.lock();
              if (ths)
                ths->set_visibility_timeout();
            },
            aws_sqs_listener::_simple_stack_size, "aws_sqs_listener, set_visibility_timeout sweeper");
      },
      cur_time() + visibility_sweep_time);
}

void aws_sqs_listener::add_to_keep_alive(const Model::Message &m)
{
  fiber_lock l(_mtx);
  _alive_set[m.GetReceiptHandle()] = m.GetMessageId();
}

void aws_sqs_listener::remove_from_keep_alive(const Model::Message &m, bool reset_visibility)
{
  {
    fiber_lock l(_mtx);
    _alive_set.erase(m.GetReceiptHandle());
  }
  if (reset_visibility)
  {
    // encourage the system to try this message again soon by resetting its visility near 0
    Model::ChangeMessageVisibilityRequest req;
    req.WithQueueUrl(_queue_url).WithReceiptHandle(m.GetReceiptHandle()).WithVisibilityTimeout(visibility_immediate_retry_time);
    auto messageId = m.GetMessageId();
    _client.ChangeMessageVisibilityAsync(req, [messageId](const SQSClient *, const Model::ChangeMessageVisibilityRequest &, const Model::ChangeMessageVisibilityOutcome &out, const std::shared_ptr<const Aws::Client::AsyncCallerContext> &) {
      fiber::rename_fiber("aws_sqs_listener::remove_from_keep_alive, ChangeMessageVisibilityAsync");
      if (out.IsSuccess())
      {
        // anon_log("reset message visibility near 0 for " << messageId);
      }
      else
      {
        do_error("reset message visibility near 0 for " << messageId << ", " << out.GetError().GetMessage());
      }
    });
  }
}

void aws_sqs_listener::delete_message(const Model::Message &m)
{
  remove_from_keep_alive(m, false);
  Model::DeleteMessageRequest req;
  req.WithQueueUrl(_queue_url).WithReceiptHandle(m.GetReceiptHandle());
  auto messageId = m.GetMessageId();
  _client.DeleteMessageAsync(req, [messageId](const SQSClient *, const Model::DeleteMessageRequest &, const Model::DeleteMessageOutcome &out, const std::shared_ptr<const Aws::Client::AsyncCallerContext> &) {
    fiber::rename_fiber("aws_sqs_listener::delete_message, DeleteMessageAsync");
    if (out.IsSuccess())
    {
      // anon_log("deleted SQS message " << messageId);
    }
    else
    {
      anon_log("delete SQS message failed, messageId:" << messageId << ", " << out.GetError().GetMessage());
    }
  });
}

aws_sqs_sender::aws_sqs_sender(const std::shared_ptr<Aws::Auth::AWSCredentialsProvider> &provider,
                               const Aws::Client::ClientConfiguration &client_config,
                               const Aws::String &queue_url)
    : _client(provider, client_config),
      _queue_url(queue_url)
{
}

void aws_sqs_sender::send(const json &body,
                          const std::function<void(const bool success, const std::string &id, const std::string &errorReason)> &response)
{
  Model::SendMessageRequest req;
  req.WithQueueUrl(_queue_url).WithMessageBody(Aws::String(body.dump()));
  _client.SendMessageAsync(req, [response](const SQSClient *, const Model::SendMessageRequest &, const Model::SendMessageOutcome &outcome, const std::shared_ptr<const Aws::Client::AsyncCallerContext> &) {
    fiber::rename_fiber("aws_sqs_sender::send, SendMessageAsync");
    response(outcome.IsSuccess(),
             std::string(outcome.GetResult().GetMessageId()),
             std::string(outcome.GetError().GetMessage()));
  });
}
<commit_msg>and this one<commit_after>/*
 Copyright (c) 2018 Anon authors, see AUTHORS file.

 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 "aws_sqs.h"
#include <aws/sqs/model/QueueAttributeName.h>
#include <aws/sqs/model/SendMessageRequest.h>

using namespace Aws::SQS;
using json = nlohmann::json;

aws_sqs_listener::aws_sqs_listener(const std::shared_ptr<Aws::Auth::AWSCredentialsProvider> &provider,
                                   const Aws::Client::ClientConfiguration &client_config,
                                   const Aws::String &queue_url,
                                   const std::function<bool(const Aws::SQS::Model::Message &m)> &handler,
                                   bool single_concurrent_message,
                                   size_t stack_size)
    : _client(provider, client_config),
      _queue_url(queue_url),
      _num_fibers(0),
      _exit_now(false),
      _process_msg(handler),
      _consecutive_errors(0),
      _single_concurrent_message(single_concurrent_message),
      _stack_size(stack_size),
      _continue_after_timeout([]{return true;})
{
}

aws_sqs_listener::aws_sqs_listener(const std::shared_ptr<Aws::Auth::AWSCredentialsProvider> &provider,
                                   const Aws::Client::ClientConfiguration &client_config,
                                   const Aws::String &queue_url,
                                   const std::function<bool(const Aws::SQS::Model::Message &m, const std::function<void()>&)> &handler,
                                   bool single_concurrent_message,
                                   size_t stack_size)
    : _client(provider, client_config),
      _queue_url(queue_url),
      _num_fibers(0),
      _exit_now(false),
      _process_msg_del(handler),
      _consecutive_errors(0),
      _single_concurrent_message(single_concurrent_message),
      _stack_size(stack_size),
      _continue_after_timeout([]{return true;})
{
}

void aws_sqs_listener::start()
{
  std::weak_ptr<aws_sqs_listener> wp = shared_from_this();

  fiber::run_in_fiber(
      [wp] {
        auto ths = wp.lock();
        if (ths)
          ths->start_listen();
      },
      aws_sqs_listener::_simple_stack_size, "aws_sqs_listener::aws_sqs_listener, start_listen");

  #if defined(ANON_DEBUG_TIMERS)
  anon_log("io_dispatch::schedule_task, aws_sqs_listener::start");
  #endif
  _timer_task = io_dispatch::schedule_task(
      [wp] {
        fiber::run_in_fiber(
            [wp] {
              auto ths = wp.lock();
              if (ths)
                ths->set_visibility_timeout();
            },
            aws_sqs_listener::_simple_stack_size, "aws_sqs_listener, set_visibility_timeout sweeper");
      },
      cur_time() + visibility_sweep_time);
}

aws_sqs_listener::~aws_sqs_listener()
{
  {
    _exit_now = true;
    fiber_lock l(_mtx);
    while (_num_fibers > 0)
      _num_fibers_cond.wait(l);
  }
  io_dispatch::remove_task(_timer_task);
}

std::function<bool(const Aws::SQS::Model::Message &m)> aws_sqs_listener::js_wrap(const std::function<bool(const Aws::SQS::Model::Message &m, const nlohmann::json &body)> &fn)
{
  return [fn](const Aws::SQS::Model::Message &m) -> bool {
    std::string body = get_body(m);
    try
    {
      json body_js = json::parse(body.begin(), body.end());
      try
      {
        return fn(m, body_js);
      }
      catch (const inval_message& exc)
      {
        anon_log_error("caught exception processing message: " << exc.what() << ", message body: '" << body << "'");
        return true;
      }
      catch (const std::exception &exc)
      {
        anon_log_error("caught exception processing message: " << exc.what() << ", message body: '" << body << "'");
        return false;
      }
      catch (...)
      {
        anon_log_error("caught unknown exception processing message, message body: '" << body << "'");
        return false;
      }
    }
    catch (const std::exception &exc)
    {
      anon_log_error("caught exception parsing message: " << exc.what() << ", message body: '" << body << "'");
      return true;
    }
    catch (...)
    {
      anon_log_error("caught unknown exception parsing message, message body: '" << body << "'");
      return true;
    }
  };
}

std::function<bool(const Aws::SQS::Model::Message &m, const std::function<void()>& del)> aws_sqs_listener::js_wrap(const std::function<bool(const Aws::SQS::Model::Message &m, const std::function<void()>& del, const nlohmann::json &body)> &fn)
{
  return [fn](const Aws::SQS::Model::Message &m, const std::function<void()>& del) -> bool {
    std::string body = get_body(m);
    try
    {
      json body_js = json::parse(body.begin(), body.end());
      try
      {
        return fn(m, del, body_js);
      }
      catch (const inval_message& exc)
      {
        anon_log_error("caught exception processing message: " << exc.what() << ", message body: '" << body << "'");
        del();
        return true;
      }
      catch (const std::exception &exc)
      {
        anon_log_error("caught exception processing message: " << exc.what() << ", message body: '" << body << "'");
        return false;
      }
      catch (...)
      {
        anon_log_error("caught unknown exception processing message, message body: '" << body << "'");
        return false;
      }
    }
    catch (const std::exception &exc)
    {
      anon_log_error("caught exception parsing message: " << exc.what() << ", message body: '" << body << "'");
      del();
      return true;
    }
    catch (...)
    {
      anon_log_error("caught unknown exception parsing message, message body: '" << body << "'");
      del();
      return true;
    }
  };
}

void aws_sqs_listener::start_listen()
{
  Model::ReceiveMessageRequest req;
  req.WithQueueUrl(_queue_url).WithMaxNumberOfMessages(_single_concurrent_message ? 1 : max_messages_per_read).WithWaitTimeSeconds(read_wait_time);
  Aws::Vector<Model::QueueAttributeName> att;
  att.push_back(Model::QueueAttributeName::All);
  req.WithAttributeNames(std::move(att));
  std::weak_ptr<aws_sqs_listener> wp = shared_from_this();
  _client.ReceiveMessageAsync(req, [wp](const SQSClient *, const Model::ReceiveMessageRequest &, const Model::ReceiveMessageOutcome &out, const std::shared_ptr<const Aws::Client::AsyncCallerContext> &) {
    auto ths = wp.lock();
    if (!ths)
      return;
    fiber::rename_fiber("aws_sqs_listener::start_listen, ReceiveMessageAsync");
    if (!out.IsSuccess())
    {
      ++ths->_consecutive_errors;
      if (ths->_consecutive_errors > 10)
      {
        anon_log_error("SQS ReceiveMessage failed, _consecutive_errors: " << ths->_consecutive_errors << "\n"
                                                                          << out.GetError());
      }
      else
      {
        anon_log("SQS ReceiveMessage failed, _consecutive_errors: " << ths->_consecutive_errors);
      }

      fiber::msleep(2000);
    }
    else
    {
      ths->_consecutive_errors = 0;
      auto &messages = out.GetResult().GetMessages();
      auto num_messages = messages.size();

      if (num_messages > 0)
      {
        ths->_num_fibers += num_messages;
        for (auto &m : messages)
          fiber::run_in_fiber(
              [wp, m] {
                auto ths = wp.lock();
                if (!ths)
                  return;
                ths->add_to_keep_alive(m);
                bool success;
                if (ths->_process_msg) {
                  success = ths->_process_msg(m);
                  if (success)
                    ths->delete_message(m);
                }
                else
                  success = ths->_process_msg_del(m, [wp, m] {
                    auto ths = wp.lock();
                    if (ths)
                      ths->delete_message(m);
                  });
                if (!success)
                  ths->remove_from_keep_alive(m, true);
                if (ths->_single_concurrent_message && !ths->_exit_now)
                  ths->start_listen();
              },
              ths->_stack_size, "aws_sqs_listener, process_msg");
      } else {
        if (!ths->_continue_after_timeout())
          ths->_exit_now = true;
      }
    }

    if (ths->_consecutive_errors < 1000)
    {
      if (!ths->_single_concurrent_message && !ths->_exit_now)
      {
        fiber_lock l(ths->_mtx);
        while (ths->_num_fibers >= max_in_flight_fibers)
          ths->_num_fibers_cond.wait(l);
        fiber::run_in_fiber(
            [wp] {
              auto ths = wp.lock();
              if (ths)
                ths->start_listen();
            },
            aws_sqs_listener::_simple_stack_size, "aws_sqs_listener, restart_listen");
      }
    }
    else
      anon_log_error("too many consecutive errors, giving up...");
  });
}

void aws_sqs_listener::set_visibility_timeout()
{
  fiber_lock l(_mtx);
  auto numMessages = _alive_set.size();
  if (numMessages > 0)
  {
    Model::ChangeMessageVisibilityBatchRequest req;
    Aws::Vector<Aws::Vector<Model::ChangeMessageVisibilityBatchRequestEntry>> entries_v;
    int index = 0;
    for (auto it : _alive_set)
    {
      Model::ChangeMessageVisibilityBatchRequestEntry ent;
      std::ostringstream str;
      if (index % 10 == 0)
        entries_v.push_back(Aws::Vector<Model::ChangeMessageVisibilityBatchRequestEntry>());
      str << "message_" << ++index;
      ent.WithReceiptHandle(it.first).WithVisibilityTimeout(visibility_time).WithId(str.str());
      entries_v.back().push_back(ent);
    }
    for (auto &entries : entries_v)
    {
      req.WithQueueUrl(_queue_url).WithEntries(entries);
      auto nMessages = entries.size();
      _client.ChangeMessageVisibilityBatchAsync(req, [nMessages](const SQSClient *, const Model::ChangeMessageVisibilityBatchRequest &, const Model::ChangeMessageVisibilityBatchOutcome &out, const std::shared_ptr<const Aws::Client::AsyncCallerContext> &) {
        fiber::rename_fiber("aws_sqs_listener::set_visibility_timeout, ChangeMessageVisibilityBatchAsync");
        if (out.IsSuccess())
        {
          anon_log("batch visibilty reset for " << nMessages << " messages");
        }
        else
        {
          do_error("batch reset visibility for " << nMessages << " messages: " << out.GetError().GetMessage());
        }
      });
    }
  }

  // schedule the sweep to run again in visibility_sweep_time seconds
  std::weak_ptr<aws_sqs_listener> wp = shared_from_this();
  #if defined(ANON_DEBUG_TIMERS)
  anon_log("io_dispatch::schedule_task, aws_sqs_listener::set_visibility_timeout");
  #endif
  _timer_task = io_dispatch::schedule_task(
      [wp] {
        fiber::run_in_fiber(
            [wp] {
              auto ths = wp.lock();
              if (ths)
                ths->set_visibility_timeout();
            },
            aws_sqs_listener::_simple_stack_size, "aws_sqs_listener, set_visibility_timeout sweeper");
      },
      cur_time() + visibility_sweep_time);
}

void aws_sqs_listener::add_to_keep_alive(const Model::Message &m)
{
  fiber_lock l(_mtx);
  _alive_set[m.GetReceiptHandle()] = m.GetMessageId();
}

void aws_sqs_listener::remove_from_keep_alive(const Model::Message &m, bool reset_visibility)
{
  {
    fiber_lock l(_mtx);
    _alive_set.erase(m.GetReceiptHandle());
  }
  if (reset_visibility)
  {
    // encourage the system to try this message again soon by resetting its visility near 0
    Model::ChangeMessageVisibilityRequest req;
    req.WithQueueUrl(_queue_url).WithReceiptHandle(m.GetReceiptHandle()).WithVisibilityTimeout(visibility_immediate_retry_time);
    auto messageId = m.GetMessageId();
    _client.ChangeMessageVisibilityAsync(req, [messageId](const SQSClient *, const Model::ChangeMessageVisibilityRequest &, const Model::ChangeMessageVisibilityOutcome &out, const std::shared_ptr<const Aws::Client::AsyncCallerContext> &) {
      fiber::rename_fiber("aws_sqs_listener::remove_from_keep_alive, ChangeMessageVisibilityAsync");
      if (out.IsSuccess())
      {
        anon_log("reset message visibility near 0 for " << messageId);
      }
      else
      {
        do_error("reset message visibility near 0 for " << messageId << ", " << out.GetError().GetMessage());
      }
    });
  }
}

void aws_sqs_listener::delete_message(const Model::Message &m)
{
  remove_from_keep_alive(m, false);
  Model::DeleteMessageRequest req;
  req.WithQueueUrl(_queue_url).WithReceiptHandle(m.GetReceiptHandle());
  auto messageId = m.GetMessageId();
  _client.DeleteMessageAsync(req, [messageId](const SQSClient *, const Model::DeleteMessageRequest &, const Model::DeleteMessageOutcome &out, const std::shared_ptr<const Aws::Client::AsyncCallerContext> &) {
    fiber::rename_fiber("aws_sqs_listener::delete_message, DeleteMessageAsync");
    if (out.IsSuccess())
    {
      // anon_log("deleted SQS message " << messageId);
    }
    else
    {
      anon_log("delete SQS message failed, messageId:" << messageId << ", " << out.GetError().GetMessage());
    }
  });
}

aws_sqs_sender::aws_sqs_sender(const std::shared_ptr<Aws::Auth::AWSCredentialsProvider> &provider,
                               const Aws::Client::ClientConfiguration &client_config,
                               const Aws::String &queue_url)
    : _client(provider, client_config),
      _queue_url(queue_url)
{
}

void aws_sqs_sender::send(const json &body,
                          const std::function<void(const bool success, const std::string &id, const std::string &errorReason)> &response)
{
  Model::SendMessageRequest req;
  req.WithQueueUrl(_queue_url).WithMessageBody(Aws::String(body.dump()));
  _client.SendMessageAsync(req, [response](const SQSClient *, const Model::SendMessageRequest &, const Model::SendMessageOutcome &outcome, const std::shared_ptr<const Aws::Client::AsyncCallerContext> &) {
    fiber::rename_fiber("aws_sqs_sender::send, SendMessageAsync");
    response(outcome.IsSuccess(),
             std::string(outcome.GetResult().GetMessageId()),
             std::string(outcome.GetError().GetMessage()));
  });
}
<|endoftext|>


<commit_before>//      © Christian Sommerfeldt Øien
//      All rights reserved

#include "fluid.hpp"
#include "tracer.hpp"
#include "palette.hpp"
#include <ctime>
#include <getopt.h>
#include <iostream>

struct ColorTracer : FluidIndicator
{
    Tracer<color_type> * tracer;
    Colorizer * colorizer;

    ColorTracer(Tracer<color_type> * tracer, Colorizer * colorizer)
            : tracer(tracer), colorizer(colorizer)
    {
        colorizer->initialize(tracer->trace);
    }

    void lapse(double delta_t, Fluid & flow, size_t i) {
        tracer->follow(flow.field, delta_t);
        colorizer->image(tracer->trace, i);
    }
};

struct ColorMatch
{
    double e;
    Color c;

    ColorMatch(double e, Color c) : e(e), c(c) {}

    bool operator()(Color m) {
        return similar(e, c, m);
    }
};

struct FeedbackParameters : FluidParameters
{
    typedef std::map<color_type, float> map_type;
    map_type densities;
    map_type viscosities;

    void configure(
            ColorTracer & color_tracer,
            double density, double viscosity,
            std::vector<ColorMatch> density_cms, double density_e,
            std::vector<ColorMatch> viscosity_cms, double viscosity_e)
    {
        const std::vector<Color> & palette = color_tracer.colorizer->palette;
        tracer = color_tracer.tracer;
        for (size_t i = 0; i < palette.size(); ++i) {
            const Color & c = palette[i];
            double d = density;
            double v = viscosity;
            for (size_t j = 0; j < density_cms.size(); ++j)
                if (density_cms[j](c)) {
                    d = density_e;
                    break;
                }
            for (size_t k = 0; k < viscosity_cms.size(); ++k)
                if (viscosity_cms[k](c)) {
                    v = viscosity_e;
                    break;
                }
            densities[i] = d;
            viscosities[i] = v;
        }
    }
    double density(const Position & p) { return densities.at(quantized->cell(p.i, p.j)); }
    double viscosity(const Position & p) { return viscosities.at(quantized->cell(p.i, p.j)); }
    ~FeedbackParameters() { delete quantized; }
    FeedbackParameters(size_t h, size_t w) : h(h), w(w), tracer(NULL), quantized(NULL) {}
    void setup(double /*t*/, double /*u*/)
    {
        if ( ! quantized) {
            quantized = new Grid<color_type>(h, w);
        }
        quantize(*quantized, *tracer->trace);
    }

private:
    size_t h;
    size_t w;
    Tracer<color_type> * tracer;
    Grid<color_type> * quantized;
};

struct SimpleFunction : FluidFunction
{
    XY placement;
    XY force;

    SimpleFunction(XY p, XY f, FluidParameters & fp) : placement(p), force(f), params(fp) {}
    bool operator()(Grid<FluidCell> * /*field_swap*/, Grid<FluidCell> * field, double step_t)
    {
        size_t i = field->h * placement.y;
        size_t j = field->w * placement.x;
        field->cell(i, j).velocity += force * (step_t / params.density(Position(i, j)));
        return false;
    }

private:
    FluidParameters & params;
};

void help()
{
    std::cerr <<
"-c R,G,B/d add color to set for exceptional density or\n"
"   R,G,B/v viscosity.  R, G and B are 0 <= N < 256\n"
"-C REAL    color-closeness at following -c options\n"
"-d REAL    normal and exceptional density, respectively\n"
"-D REAL\n"
"-h         output this help to stdandard err\n"
"-i PATH    filename of PNG image to start with\n"
"-m N>0     output-image pixel-widths per fluid-cell\n"
"-n N>0     count of output-images to produce\n"
"-p PATH    prefix for path to JPEG output-files\n"
"-q N>0     number of force-spots applied to fluid\n"
"-s N>0     seed for random-number-generator\n"
"-v REAL    normal and exceptional viscosity, respectively\n"
"-V REAL\n"
"-x W,H     dimentions of the fluid grid\n";
}

int main(int argc, char **argv)
{
    time_t seed = 0;
    unsigned q = 3, w = 256, h = 256, m = 3;
    std::vector<ColorMatch> d_exc, v_exc;
    double z = 0.1, d = 0.08, D = 0.2, v = 0.4, V = 1.0;
    const char *image_prefix = "", *photo_filename = "img.png";
    int n = 512;

    int opt;
    while ((opt = getopt(argc, argv, "c:C:d:D:hi:m:n:p:q:s:v:V:x:")) != EOF)
    switch (opt) {
        default:
            return 1;
        case 'c':
            {
                char e;
                unsigned r, g, b;
                if (std::sscanf(optarg, "%u,%u,%u/%c", &r, &g, &b, &e) != 4
                        || (e != 'd' && e != 'v')
                        || r > 255 || g > 255 || b > 255) {
                    std::cerr << "illegal format of exception-color\n"
                        "please give three X<256 folowed by '/d' or '/v'\n";
                    return 1;
                }
                std::vector<ColorMatch> & exc = (e == 'd') ? d_exc : v_exc;
                exc.push_back(ColorMatch(z,
                            {r /(real) 255, g /(real) 255, b /(real) 255}));
            }
            break;
        case 'C': std::sscanf(optarg, "%lf", &z); break;
        case 'd': std::sscanf(optarg, "%lf", &d); break;
        case 'D': std::sscanf(optarg, "%lf", &D); break;
        case 'h':
            help();
            return 0;
        case 'i':
            photo_filename = optarg;
            break;
        case 'm':
            if ((m = std::atoi(optarg)) <= 0) {
                std::cerr << "illegal optarg of -m\n"
                    "please give a positive number\n";
                return 1;
            }
            break;
        case 'n':
            if ((n = atoi(optarg)) <= 0) {
                std::cerr << "nothing to produce, as N is zero\n";
                return 1;
            }
            break;
        case 'p':
            image_prefix = optarg; break;
        case 'q':
            if ((q = std::atoi(optarg)) <= 0) {
                std::cerr << "q zero means to apply no forces to flow\n"
                    "the images would all be alike\n";
                return 1;
            }
            break;
        case 's':
            if ((seed = std::atoi(optarg)) <= 0) {
                std::cerr << "will use time as random-seed\n";
            }
            break;
        case 'v': std::sscanf(optarg, "%lf", &v); break;
        case 'V': std::sscanf(optarg, "%lf", &V); break;
        case 'x':
            if (std::sscanf(optarg, "%u,%u", &w, &h) != 2) {
                std::cerr << "illegal optarg of -x\n"
                    "please use two numbers separated by a ','\n";
                return 1;
            }
            break;
    }

    if (seed == 0)
        std::time(&seed);
    if (d_exc.empty()) {
        d_exc.push_back(ColorMatch(0.3, {0, 0, 0}));
        std::cerr << "using dark colors as exceptional density\n";
    }
    if (v_exc.empty()) {
        v_exc.push_back(ColorMatch(0.2, {0, 1, 1}));
        std::cerr << "using cyan colors as exceptional viscosity\n";
    }
    std::srand(seed);
    FeedbackParameters p(h, w);
    std::vector<FluidFunction *> functions;
    for (size_t k = 0; k < q; ++k) {
        XY placement(rnd(1), rnd(1));
        XY force(rnd(2) - 1, rnd(2) - 1);
        functions.push_back(new SimpleFunction(placement, force, p));
    }
    functions.push_back(new EdgeFunction<FluidCell>());
    CompositeFunction<FluidCell> f(functions);
    FluidAnimation a(h, w, p, f);

    PhotoColorizer c(photo_filename, image_prefix);
    Tracer<color_type> tracer(h * m, w * m);
    ColorTracer color_tracer(&tracer, &c);

    p.configure(color_tracer, d, v, d_exc, D, v_exc, V);
    a.run(n, color_tracer);
    for (size_t k = 0; k <=/*counting edge-function*/ q; ++k) delete functions[k];
}

<commit_msg>Have a few more forces applied on fluid<commit_after>//      © Christian Sommerfeldt Øien
//      All rights reserved

#include "fluid.hpp"
#include "tracer.hpp"
#include "palette.hpp"
#include <ctime>
#include <getopt.h>
#include <iostream>

struct ColorTracer : FluidIndicator
{
    Tracer<color_type> * tracer;
    Colorizer * colorizer;

    ColorTracer(Tracer<color_type> * tracer, Colorizer * colorizer)
            : tracer(tracer), colorizer(colorizer)
    {
        colorizer->initialize(tracer->trace);
    }

    void lapse(double delta_t, Fluid & flow, size_t i) {
        tracer->follow(flow.field, delta_t);
        colorizer->image(tracer->trace, i);
    }
};

struct ColorMatch
{
    double e;
    Color c;

    ColorMatch(double e, Color c) : e(e), c(c) {}

    bool operator()(Color m) {
        return similar(e, c, m);
    }
};

struct FeedbackParameters : FluidParameters
{
    typedef std::map<color_type, float> map_type;
    map_type densities;
    map_type viscosities;

    void configure(
            ColorTracer & color_tracer,
            double density, double viscosity,
            std::vector<ColorMatch> density_cms, double density_e,
            std::vector<ColorMatch> viscosity_cms, double viscosity_e)
    {
        const std::vector<Color> & palette = color_tracer.colorizer->palette;
        tracer = color_tracer.tracer;
        for (size_t i = 0; i < palette.size(); ++i) {
            const Color & c = palette[i];
            double d = density;
            double v = viscosity;
            for (size_t j = 0; j < density_cms.size(); ++j)
                if (density_cms[j](c)) {
                    d = density_e;
                    break;
                }
            for (size_t k = 0; k < viscosity_cms.size(); ++k)
                if (viscosity_cms[k](c)) {
                    v = viscosity_e;
                    break;
                }
            densities[i] = d;
            viscosities[i] = v;
        }
    }
    double density(const Position & p) { return densities.at(quantized->cell(p.i, p.j)); }
    double viscosity(const Position & p) { return viscosities.at(quantized->cell(p.i, p.j)); }
    ~FeedbackParameters() { delete quantized; }
    FeedbackParameters(size_t h, size_t w) : h(h), w(w), tracer(NULL), quantized(NULL) {}
    void setup(double /*t*/, double /*u*/)
    {
        if ( ! quantized) {
            quantized = new Grid<color_type>(h, w);
        }
        quantize(*quantized, *tracer->trace);
    }

private:
    size_t h;
    size_t w;
    Tracer<color_type> * tracer;
    Grid<color_type> * quantized;
};

struct SimpleFunction : FluidFunction
{
    XY placement;
    XY force;

    SimpleFunction(XY p, XY f, FluidParameters & fp) : placement(p), force(f), params(fp) {}
    bool operator()(Grid<FluidCell> * /*field_swap*/, Grid<FluidCell> * field, double step_t)
    {
        size_t i = field->h * placement.y;
        size_t j = field->w * placement.x;
        field->cell(i, j).velocity += force * (step_t / params.density(Position(i, j)));
        return false;
    }

private:
    FluidParameters & params;
};

void help()
{
    std::cerr <<
"-c R,G,B/d add color to set for exceptional density or\n"
"   R,G,B/v viscosity.  R, G and B are 0 <= N < 256\n"
"-C REAL    color-closeness at following -c options\n"
"-d REAL    normal and exceptional density, respectively\n"
"-D REAL\n"
"-h         output this help to stdandard err\n"
"-i PATH    filename of PNG image to start with\n"
"-m N>0     output-image pixel-widths per fluid-cell\n"
"-n N>0     count of output-images to produce\n"
"-p PATH    prefix for path to JPEG output-files\n"
"-q N>0     number of force-spots applied to fluid\n"
"-s N>0     seed for random-number-generator\n"
"-v REAL    normal and exceptional viscosity, respectively\n"
"-V REAL\n"
"-x W,H     dimentions of the fluid grid\n";
}

int main(int argc, char **argv)
{
    time_t seed = 0;
    unsigned q = 9, w = 256, h = 256, m = 3;
    std::vector<ColorMatch> d_exc, v_exc;
    double z = 0.1, d = 0.08, D = 0.2, v = 0.4, V = 1.0;
    const char *image_prefix = "", *photo_filename = "img.png";
    int n = 512;

    int opt;
    while ((opt = getopt(argc, argv, "c:C:d:D:hi:m:n:p:q:s:v:V:x:")) != EOF)
    switch (opt) {
        default:
            return 1;
        case 'c':
            {
                char e;
                unsigned r, g, b;
                if (std::sscanf(optarg, "%u,%u,%u/%c", &r, &g, &b, &e) != 4
                        || (e != 'd' && e != 'v')
                        || r > 255 || g > 255 || b > 255) {
                    std::cerr << "illegal format of exception-color\n"
                        "please give three X<256 folowed by '/d' or '/v'\n";
                    return 1;
                }
                std::vector<ColorMatch> & exc = (e == 'd') ? d_exc : v_exc;
                exc.push_back(ColorMatch(z,
                            {r /(real) 255, g /(real) 255, b /(real) 255}));
            }
            break;
        case 'C': std::sscanf(optarg, "%lf", &z); break;
        case 'd': std::sscanf(optarg, "%lf", &d); break;
        case 'D': std::sscanf(optarg, "%lf", &D); break;
        case 'h':
            help();
            return 0;
        case 'i':
            photo_filename = optarg;
            break;
        case 'm':
            if ((m = std::atoi(optarg)) <= 0) {
                std::cerr << "illegal optarg of -m\n"
                    "please give a positive number\n";
                return 1;
            }
            break;
        case 'n':
            if ((n = atoi(optarg)) <= 0) {
                std::cerr << "nothing to produce, as N is zero\n";
                return 1;
            }
            break;
        case 'p':
            image_prefix = optarg; break;
        case 'q':
            if ((q = std::atoi(optarg)) <= 0) {
                std::cerr << "q zero means to apply no forces to flow\n"
                    "the images would all be alike\n";
                return 1;
            }
            break;
        case 's':
            if ((seed = std::atoi(optarg)) <= 0) {
                std::cerr << "will use time as random-seed\n";
            }
            break;
        case 'v': std::sscanf(optarg, "%lf", &v); break;
        case 'V': std::sscanf(optarg, "%lf", &V); break;
        case 'x':
            if (std::sscanf(optarg, "%u,%u", &w, &h) != 2) {
                std::cerr << "illegal optarg of -x\n"
                    "please use two numbers separated by a ','\n";
                return 1;
            }
            break;
    }

    if (seed == 0)
        std::time(&seed);
    if (d_exc.empty()) {
        d_exc.push_back(ColorMatch(0.3, {0, 0, 0}));
        std::cerr << "using dark colors as exceptional density\n";
    }
    if (v_exc.empty()) {
        v_exc.push_back(ColorMatch(0.2, {0, 1, 1}));
        std::cerr << "using cyan colors as exceptional viscosity\n";
    }
    std::srand(seed);
    FeedbackParameters p(h, w);
    std::vector<FluidFunction *> functions;
    for (size_t k = 0; k < q; ++k) {
        XY placement(rnd(1), rnd(1));
        XY force(rnd(2) - 1, rnd(2) - 1);
        functions.push_back(new SimpleFunction(placement, force, p));
    }
    functions.push_back(new EdgeFunction<FluidCell>());
    CompositeFunction<FluidCell> f(functions);
    FluidAnimation a(h, w, p, f);

    PhotoColorizer c(photo_filename, image_prefix);
    Tracer<color_type> tracer(h * m, w * m);
    ColorTracer color_tracer(&tracer, &c);

    p.configure(color_tracer, d, v, d_exc, D, v_exc, V);
    a.run(n, color_tracer);
    for (size_t k = 0; k <=/*counting edge-function*/ q; ++k) delete functions[k];
}

<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkAppendFilter.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1998 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
#include "vtkAppendFilter.h"

vtkAppendFilter::vtkAppendFilter()
{
}

// Description:
// Add a dataset to the list of data to append.
void vtkAppendFilter::AddInput(vtkDataSet *ds)
{
  if ( ! this->InputList.IsItemPresent(ds) )
    {
    this->Modified();
    this->InputList.AddItem(ds);
    }
}

// Description:
// Remove a dataset from the list of data to append.
void vtkAppendFilter::RemoveInput(vtkDataSet *ds)
{
  if ( this->InputList.IsItemPresent(ds) )
    {
    this->Modified();
    this->InputList.RemoveItem(ds);
    }
}

void vtkAppendFilter::Update()
{
  unsigned long int mtime, dsMtime;
  vtkDataSet *ds;

  // make sure input is available
  if ( this->InputList.GetNumberOfItems() < 1 )
    {
    vtkErrorMacro(<< "No input...can't execute!");
    return;
    }

  // prevent chasing our tail
  if (this->Updating) return;

  this->Updating = 1;
  for (mtime=0, this->InputList.InitTraversal();
  (ds = this->InputList.GetNextItem()); )
    {
    ds->Update();
    dsMtime = ds->GetMTime();
    if ( dsMtime > mtime ) mtime = dsMtime;
    }
  this->Updating = 0;

  if ( mtime > this->ExecuteTime || this->GetMTime() > this->ExecuteTime )
    {
    for ( this->InputList.InitTraversal();(ds=this->InputList.GetNextItem());)
      {
      if ( ds->GetDataReleased() ) ds->ForceUpdate();
      }

    if ( this->StartMethod ) (*this->StartMethod)(this->StartMethodArg);
    this->Output->Initialize(); //clear output
    // reset AbortExecute flag and Progress
    this->AbortExecute = 0;
    this->Progress = 0.0;
    this->Execute();
    this->ExecuteTime.Modified();
    if ( !this->AbortExecute ) this->UpdateProgress(1.0);
    this->SetDataReleased(0);
    if ( this->EndMethod ) (*this->EndMethod)(this->EndMethodArg);
    }

  for (this->InputList.InitTraversal(); (ds = this->InputList.GetNextItem()); )
    if ( ds->ShouldIReleaseData() ) ds->ReleaseData();
}

// Append data sets into single unstructured grid
void vtkAppendFilter::Execute()
{
  int scalarsPresent, vectorsPresent, normalsPresent, tcoordsPresent;
  int tensorsPresent, userDefinedPresent;
  int numPts, numCells, ptOffset;
  vtkFloatPoints *newPts;
  vtkPointData *pd = NULL;
  vtkIdList ptIds(VTK_CELL_SIZE), newPtIds(VTK_CELL_SIZE);
  int i;
  vtkDataSet *ds;
  int ptId, cellId;
  vtkUnstructuredGrid *output = (vtkUnstructuredGrid *)this->Output;
  vtkPointData *outputPD = output->GetPointData();

  vtkDebugMacro(<<"Appending data together");

  // loop over all data sets, checking to see what point data is available.
  numPts = 0;
  numCells = 0;
  scalarsPresent = 1;
  vectorsPresent = 1;
  normalsPresent = 1;
  tcoordsPresent = 1;
  tensorsPresent = 1;
  userDefinedPresent = 1;

  for (this->InputList.InitTraversal(); (ds = this->InputList.GetNextItem()); )
    {
    numPts += ds->GetNumberOfPoints();
    numCells += ds->GetNumberOfCells();
    pd = ds->GetPointData();
    if ( pd->GetScalars() == NULL ) scalarsPresent &= 0;
    if ( pd->GetVectors() == NULL ) vectorsPresent &= 0;
    if ( pd->GetNormals() == NULL ) normalsPresent &= 0;
    if ( pd->GetTCoords() == NULL ) tcoordsPresent &= 0;
    if ( pd->GetTensors() == NULL ) tensorsPresent &= 0;
    if ( pd->GetUserDefined() == NULL ) userDefinedPresent &= 0;
    }

  if ( numPts < 1 || numCells < 1 )
    {
    vtkErrorMacro(<<"No data to append!");
    return;
    }

  // Now can allocate memory
  output->Allocate(numCells); //allocate storage for geometry/topology
  if ( !scalarsPresent ) outputPD->CopyScalarsOff();
  if ( !vectorsPresent ) outputPD->CopyVectorsOff();
  if ( !normalsPresent ) outputPD->CopyNormalsOff();
  if ( !tcoordsPresent ) outputPD->CopyTCoordsOff();
  if ( !tensorsPresent ) outputPD->CopyTensorsOff();
  if ( !userDefinedPresent ) outputPD->CopyUserDefinedOff();
  outputPD->CopyAllocate(pd,numPts);

  newPts = vtkFloatPoints::New();
  newPts->SetNumberOfPoints(numPts);

  for (ptOffset=0, this->InputList.InitTraversal();
       (ds = this->InputList.GetNextItem()); ptOffset+=numPts)
    {
    numPts = ds->GetNumberOfPoints();
    numCells = ds->GetNumberOfCells();
    pd = ds->GetPointData();

    // copy points and point data
    for (ptId=0; ptId < numPts; ptId++)
      {
      newPts->SetPoint(ptId+ptOffset,ds->GetPoint(ptId));
      outputPD->CopyData(pd,ptId,ptId+ptOffset);
      }

    // copy cells
    for (cellId=0; cellId < numCells; cellId++)
      {
      ds->GetCellPoints(cellId,ptIds);
      for (i=0; i < ptIds.GetNumberOfIds(); i++)
        newPtIds.InsertId(i,ptIds.GetId(i)+ptOffset);
      output->InsertNextCell(ds->GetCellType(cellId),newPtIds);
      }
    }
//
// Update ourselves and release memory
//
  output->SetPoints(newPts);
  newPts->Delete();
}

void vtkAppendFilter::PrintSelf(ostream& os, vtkIndent indent)
{
  vtkFilter::PrintSelf(os,indent);

  os << indent << "Input DataSets:\n";
  this->InputList.PrintSelf(os,indent.GetNextIndent());
}

<commit_msg>ERR: added newPtIds.Reset<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkAppendFilter.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1998 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
#include "vtkAppendFilter.h"

vtkAppendFilter::vtkAppendFilter()
{
}

// Description:
// Add a dataset to the list of data to append.
void vtkAppendFilter::AddInput(vtkDataSet *ds)
{
  if ( ! this->InputList.IsItemPresent(ds) )
    {
    this->Modified();
    this->InputList.AddItem(ds);
    }
}

// Description:
// Remove a dataset from the list of data to append.
void vtkAppendFilter::RemoveInput(vtkDataSet *ds)
{
  if ( this->InputList.IsItemPresent(ds) )
    {
    this->Modified();
    this->InputList.RemoveItem(ds);
    }
}

void vtkAppendFilter::Update()
{
  unsigned long int mtime, dsMtime;
  vtkDataSet *ds;

  // make sure input is available
  if ( this->InputList.GetNumberOfItems() < 1 )
    {
    vtkErrorMacro(<< "No input...can't execute!");
    return;
    }

  // prevent chasing our tail
  if (this->Updating) return;

  this->Updating = 1;
  for (mtime=0, this->InputList.InitTraversal();
  (ds = this->InputList.GetNextItem()); )
    {
    ds->Update();
    dsMtime = ds->GetMTime();
    if ( dsMtime > mtime ) mtime = dsMtime;
    }
  this->Updating = 0;

  if ( mtime > this->ExecuteTime || this->GetMTime() > this->ExecuteTime )
    {
    for ( this->InputList.InitTraversal();(ds=this->InputList.GetNextItem());)
      {
      if ( ds->GetDataReleased() ) ds->ForceUpdate();
      }

    if ( this->StartMethod ) (*this->StartMethod)(this->StartMethodArg);
    this->Output->Initialize(); //clear output
    // reset AbortExecute flag and Progress
    this->AbortExecute = 0;
    this->Progress = 0.0;
    this->Execute();
    this->ExecuteTime.Modified();
    if ( !this->AbortExecute ) this->UpdateProgress(1.0);
    this->SetDataReleased(0);
    if ( this->EndMethod ) (*this->EndMethod)(this->EndMethodArg);
    }

  for (this->InputList.InitTraversal(); (ds = this->InputList.GetNextItem()); )
    if ( ds->ShouldIReleaseData() ) ds->ReleaseData();
}

// Append data sets into single unstructured grid
void vtkAppendFilter::Execute()
{
  int scalarsPresent, vectorsPresent, normalsPresent, tcoordsPresent;
  int tensorsPresent, userDefinedPresent;
  int numPts, numCells, ptOffset;
  vtkFloatPoints *newPts;
  vtkPointData *pd = NULL;
  vtkIdList ptIds(VTK_CELL_SIZE), newPtIds(VTK_CELL_SIZE);
  int i;
  vtkDataSet *ds;
  int ptId, cellId;
  vtkUnstructuredGrid *output = (vtkUnstructuredGrid *)this->Output;
  vtkPointData *outputPD = output->GetPointData();

  vtkDebugMacro(<<"Appending data together");

  // loop over all data sets, checking to see what point data is available.
  numPts = 0;
  numCells = 0;
  scalarsPresent = 1;
  vectorsPresent = 1;
  normalsPresent = 1;
  tcoordsPresent = 1;
  tensorsPresent = 1;
  userDefinedPresent = 1;

  for (this->InputList.InitTraversal(); (ds = this->InputList.GetNextItem()); )
    {
    numPts += ds->GetNumberOfPoints();
    numCells += ds->GetNumberOfCells();
    pd = ds->GetPointData();
    if ( pd->GetScalars() == NULL ) scalarsPresent &= 0;
    if ( pd->GetVectors() == NULL ) vectorsPresent &= 0;
    if ( pd->GetNormals() == NULL ) normalsPresent &= 0;
    if ( pd->GetTCoords() == NULL ) tcoordsPresent &= 0;
    if ( pd->GetTensors() == NULL ) tensorsPresent &= 0;
    if ( pd->GetUserDefined() == NULL ) userDefinedPresent &= 0;
    }

  if ( numPts < 1 || numCells < 1 )
    {
    vtkErrorMacro(<<"No data to append!");
    return;
    }

  // Now can allocate memory
  output->Allocate(numCells); //allocate storage for geometry/topology
  if ( !scalarsPresent ) outputPD->CopyScalarsOff();
  if ( !vectorsPresent ) outputPD->CopyVectorsOff();
  if ( !normalsPresent ) outputPD->CopyNormalsOff();
  if ( !tcoordsPresent ) outputPD->CopyTCoordsOff();
  if ( !tensorsPresent ) outputPD->CopyTensorsOff();
  if ( !userDefinedPresent ) outputPD->CopyUserDefinedOff();
  outputPD->CopyAllocate(pd,numPts);

  newPts = vtkFloatPoints::New();
  newPts->SetNumberOfPoints(numPts);

  for (ptOffset=0, this->InputList.InitTraversal();
       (ds = this->InputList.GetNextItem()); ptOffset+=numPts)
    {
    numPts = ds->GetNumberOfPoints();
    numCells = ds->GetNumberOfCells();
    pd = ds->GetPointData();

    // copy points and point data
    for (ptId=0; ptId < numPts; ptId++)
      {
      newPts->SetPoint(ptId+ptOffset,ds->GetPoint(ptId));
      outputPD->CopyData(pd,ptId,ptId+ptOffset);
      }

    // copy cells
    for (cellId=0; cellId < numCells; cellId++)
      {
      ds->GetCellPoints(cellId,ptIds);
      newPtIds.Reset ();
      for (i=0; i < ptIds.GetNumberOfIds(); i++)
        newPtIds.InsertId(i,ptIds.GetId(i)+ptOffset);
      output->InsertNextCell(ds->GetCellType(cellId),newPtIds);
      }
    }
//
// Update ourselves and release memory
//
  output->SetPoints(newPts);
  newPts->Delete();
}

void vtkAppendFilter::PrintSelf(ostream& os, vtkIndent indent)
{
  vtkFilter::PrintSelf(os,indent);

  os << indent << "Input DataSets:\n";
  this->InputList.PrintSelf(os,indent.GetNextIndent());
}

<|endoftext|>


<commit_before>// Copyright (c) 2012 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/chromeos/login/enrollment/enterprise_enrollment_screen.h"

#include "base/bind.h"
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/metrics/histogram.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/cros/cros_library.h"
#include "chrome/browser/chromeos/cros/cryptohome_library.h"
#include "chrome/browser/chromeos/login/authenticator.h"
#include "chrome/browser/chromeos/login/screen_observer.h"
#include "chrome/browser/policy/auto_enrollment_client.h"
#include "chrome/browser/policy/browser_policy_connector.h"
#include "chrome/browser/policy/cloud_policy_data_store.h"
#include "chrome/browser/policy/enterprise_metrics.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/session_manager_client.h"

namespace chromeos {

namespace {

// Retry for InstallAttrs initialization every 500ms.
const int kLockRetryIntervalMs = 500;

}  // namespace

EnterpriseEnrollmentScreen::EnterpriseEnrollmentScreen(
    ScreenObserver* observer,
    EnterpriseEnrollmentScreenActor* actor)
    : WizardScreen(observer),
      actor_(actor),
      is_auto_enrollment_(false),
      is_showing_(false),
      ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
  actor_->SetController(this);
  // Init the TPM if it has not been done until now (in debug build we might
  // have not done that yet).
  chromeos::CryptohomeLibrary* cryptohome =
      chromeos::CrosLibrary::Get()->GetCryptohomeLibrary();
  if (cryptohome &&
      cryptohome->TpmIsEnabled() &&
      !cryptohome->TpmIsBeingOwned() &&
      !cryptohome->TpmIsOwned()) {
    cryptohome->TpmCanAttemptOwnership();
  }
}

EnterpriseEnrollmentScreen::~EnterpriseEnrollmentScreen() {}

void EnterpriseEnrollmentScreen::SetParameters(bool is_auto_enrollment,
                                               const std::string& user) {
  is_auto_enrollment_ = is_auto_enrollment;
  user_ = user.empty() ? user : Authenticator::Canonicalize(user);
}

void EnterpriseEnrollmentScreen::PrepareToShow() {
  actor_->PrepareToShow();
}

void EnterpriseEnrollmentScreen::Show() {
  is_showing_ = true;
  actor_->Show();
}

void EnterpriseEnrollmentScreen::Hide() {
  is_showing_ = false;
  actor_->Hide();
}

void EnterpriseEnrollmentScreen::OnOAuthTokenAvailable(
    const std::string& user,
    const std::string& token) {
  user_ = Authenticator::Canonicalize(user);
  RegisterForDevicePolicy(token);
}

void EnterpriseEnrollmentScreen::OnConfirmationClosed(bool go_back_to_signin) {
  // If the machine has been put in KIOSK mode we have to restart the session
  // here to go in the proper KIOSK mode login screen.
  policy::BrowserPolicyConnector* policy_connector =
      g_browser_process->browser_policy_connector();
  if (policy_connector && policy_connector->GetDeviceCloudPolicyDataStore() &&
      policy_connector->GetDeviceCloudPolicyDataStore()->device_mode() ==
          policy::DEVICE_MODE_KIOSK) {
    DBusThreadManager::Get()->GetSessionManagerClient()->StopSession();
    return;
  }

  get_screen_observer()->OnExit(go_back_to_signin ?
      ScreenObserver::ENTERPRISE_ENROLLMENT_COMPLETED :
      ScreenObserver::ENTERPRISE_AUTO_MAGIC_ENROLLMENT_COMPLETED);
}

bool EnterpriseEnrollmentScreen::IsAutoEnrollment(std::string* user) {
  if (is_auto_enrollment_)
    *user = user_;
  return is_auto_enrollment_;
}

void EnterpriseEnrollmentScreen::OnPolicyStateChanged(
    policy::CloudPolicySubsystem::PolicySubsystemState state,
    policy::CloudPolicySubsystem::ErrorDetails error_details) {

  if (is_showing_) {
    switch (state) {
      case policy::CloudPolicySubsystem::UNENROLLED:
        switch (error_details) {
          case policy::CloudPolicySubsystem::BAD_SERIAL_NUMBER:
            actor_->ShowSerialNumberError();
            break;
          case policy::CloudPolicySubsystem::BAD_ENROLLMENT_MODE:
            actor_->ShowEnrollmentModeError();
            break;
          default:  // Still working...
            return;
        }
        break;
      case policy::CloudPolicySubsystem::BAD_GAIA_TOKEN:
      case policy::CloudPolicySubsystem::LOCAL_ERROR:
        actor_->ShowFatalEnrollmentError();
        break;
      case policy::CloudPolicySubsystem::UNMANAGED:
        actor_->ShowAccountError();
        break;
      case policy::CloudPolicySubsystem::NETWORK_ERROR:
        actor_->ShowNetworkEnrollmentError();
        break;
      case policy::CloudPolicySubsystem::TOKEN_FETCHED:
        if (!is_auto_enrollment_ ||
            g_browser_process->browser_policy_connector()->
                GetDeviceCloudPolicyDataStore()->device_mode() ==
            policy::DEVICE_MODE_ENTERPRISE) {
          WriteInstallAttributesData();
          return;
        } else {
          LOG(ERROR) << "Enrollment can not proceed because Auto-enrollment is "
                     << "not supported for non-enterprise enrollment modes.";
          policy::AutoEnrollmentClient::CancelAutoEnrollment();
          is_auto_enrollment_ = false;
          actor_->ShowAutoEnrollmentError();
          // Set the error state to something distinguishable in the logs.
          state = policy::CloudPolicySubsystem::LOCAL_ERROR;
          error_details = policy::CloudPolicySubsystem::AUTO_ENROLLMENT_ERROR;
        }
        break;
      case policy::CloudPolicySubsystem::SUCCESS:
        // Success!
        registrar_.reset();
        actor_->ShowConfirmationScreen();
        return;
    }
    // We have an error.
    if (!is_auto_enrollment_) {
      UMA_HISTOGRAM_ENUMERATION(policy::kMetricEnrollment,
                                policy::kMetricEnrollmentPolicyFailed,
                                policy::kMetricEnrollmentSize);
    }
    LOG(WARNING) << "Policy subsystem error during enrollment: " << state
                 << " details: " << error_details;
  }

  // Stop the policy infrastructure.
  registrar_.reset();
  g_browser_process->browser_policy_connector()->ResetDevicePolicy();
}

void EnterpriseEnrollmentScreen::WriteInstallAttributesData() {
  // Since this method is also called directly.
  weak_ptr_factory_.InvalidateWeakPtrs();

  switch (g_browser_process->browser_policy_connector()->LockDevice(user_)) {
    case policy::EnterpriseInstallAttributes::LOCK_SUCCESS: {
      // Proceed with policy fetch.
      policy::BrowserPolicyConnector* connector =
          g_browser_process->browser_policy_connector();
      connector->FetchCloudPolicy();
      return;
    }
    case policy::EnterpriseInstallAttributes::LOCK_NOT_READY: {
      // InstallAttributes not ready yet, retry later.
      LOG(WARNING) << "Install Attributes not ready yet will retry in "
                   << kLockRetryIntervalMs << "ms.";
      MessageLoop::current()->PostDelayedTask(
          FROM_HERE,
          base::Bind(&EnterpriseEnrollmentScreen::WriteInstallAttributesData,
                     weak_ptr_factory_.GetWeakPtr()),
          kLockRetryIntervalMs);
      return;
    }
    case policy::EnterpriseInstallAttributes::LOCK_BACKEND_ERROR: {
      actor_->ShowFatalEnrollmentError();
      return;
    }
    case policy::EnterpriseInstallAttributes::LOCK_WRONG_USER: {
      LOG(ERROR) << "Enrollment can not proceed because the InstallAttrs "
                 << "has been locked already!";
      actor_->ShowFatalEnrollmentError();
      return;
    }
  }

  NOTREACHED();
}

void EnterpriseEnrollmentScreen::RegisterForDevicePolicy(
    const std::string& token) {
  policy::BrowserPolicyConnector* connector =
      g_browser_process->browser_policy_connector();
  if (!connector->device_cloud_policy_subsystem()) {
    LOG(ERROR) << "Cloud policy subsystem not initialized.";
  } else if (connector->IsEnterpriseManaged()) {
    LOG(ERROR) << "Device is already enterprise managed!";
  } else if (connector->device_cloud_policy_subsystem()->state() ==
      policy::CloudPolicySubsystem::SUCCESS) {
    LOG(ERROR) << "A previous enrollment already succeeded!";
  } else {
    // Make sure the device policy subsystem is in a clean slate.
    connector->ResetDevicePolicy();
    connector->ScheduleServiceInitialization(0);
    registrar_.reset(new policy::CloudPolicySubsystem::ObserverRegistrar(
        connector->device_cloud_policy_subsystem(), this));
    // Push the credentials to the policy infrastructure. It'll start enrollment
    // and notify us of progress through CloudPolicySubsystem::Observer.
    connector->RegisterForDevicePolicy(user_, token, is_auto_enrollment_);
    return;
  }
  NOTREACHED();
  if (is_showing_)
    actor_->ShowFatalEnrollmentError();
}

}  // namespace chromeos
<commit_msg>Update uses of TimeDelta in enrollment screen code.<commit_after>// Copyright (c) 2012 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/chromeos/login/enrollment/enterprise_enrollment_screen.h"

#include "base/bind.h"
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/metrics/histogram.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/cros/cros_library.h"
#include "chrome/browser/chromeos/cros/cryptohome_library.h"
#include "chrome/browser/chromeos/login/authenticator.h"
#include "chrome/browser/chromeos/login/screen_observer.h"
#include "chrome/browser/policy/auto_enrollment_client.h"
#include "chrome/browser/policy/browser_policy_connector.h"
#include "chrome/browser/policy/cloud_policy_data_store.h"
#include "chrome/browser/policy/enterprise_metrics.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/session_manager_client.h"

namespace chromeos {

namespace {

// Retry for InstallAttrs initialization every 500ms.
const int kLockRetryIntervalMs = 500;

}  // namespace

EnterpriseEnrollmentScreen::EnterpriseEnrollmentScreen(
    ScreenObserver* observer,
    EnterpriseEnrollmentScreenActor* actor)
    : WizardScreen(observer),
      actor_(actor),
      is_auto_enrollment_(false),
      is_showing_(false),
      ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
  actor_->SetController(this);
  // Init the TPM if it has not been done until now (in debug build we might
  // have not done that yet).
  chromeos::CryptohomeLibrary* cryptohome =
      chromeos::CrosLibrary::Get()->GetCryptohomeLibrary();
  if (cryptohome &&
      cryptohome->TpmIsEnabled() &&
      !cryptohome->TpmIsBeingOwned() &&
      !cryptohome->TpmIsOwned()) {
    cryptohome->TpmCanAttemptOwnership();
  }
}

EnterpriseEnrollmentScreen::~EnterpriseEnrollmentScreen() {}

void EnterpriseEnrollmentScreen::SetParameters(bool is_auto_enrollment,
                                               const std::string& user) {
  is_auto_enrollment_ = is_auto_enrollment;
  user_ = user.empty() ? user : Authenticator::Canonicalize(user);
}

void EnterpriseEnrollmentScreen::PrepareToShow() {
  actor_->PrepareToShow();
}

void EnterpriseEnrollmentScreen::Show() {
  is_showing_ = true;
  actor_->Show();
}

void EnterpriseEnrollmentScreen::Hide() {
  is_showing_ = false;
  actor_->Hide();
}

void EnterpriseEnrollmentScreen::OnOAuthTokenAvailable(
    const std::string& user,
    const std::string& token) {
  user_ = Authenticator::Canonicalize(user);
  RegisterForDevicePolicy(token);
}

void EnterpriseEnrollmentScreen::OnConfirmationClosed(bool go_back_to_signin) {
  // If the machine has been put in KIOSK mode we have to restart the session
  // here to go in the proper KIOSK mode login screen.
  policy::BrowserPolicyConnector* policy_connector =
      g_browser_process->browser_policy_connector();
  if (policy_connector && policy_connector->GetDeviceCloudPolicyDataStore() &&
      policy_connector->GetDeviceCloudPolicyDataStore()->device_mode() ==
          policy::DEVICE_MODE_KIOSK) {
    DBusThreadManager::Get()->GetSessionManagerClient()->StopSession();
    return;
  }

  get_screen_observer()->OnExit(go_back_to_signin ?
      ScreenObserver::ENTERPRISE_ENROLLMENT_COMPLETED :
      ScreenObserver::ENTERPRISE_AUTO_MAGIC_ENROLLMENT_COMPLETED);
}

bool EnterpriseEnrollmentScreen::IsAutoEnrollment(std::string* user) {
  if (is_auto_enrollment_)
    *user = user_;
  return is_auto_enrollment_;
}

void EnterpriseEnrollmentScreen::OnPolicyStateChanged(
    policy::CloudPolicySubsystem::PolicySubsystemState state,
    policy::CloudPolicySubsystem::ErrorDetails error_details) {

  if (is_showing_) {
    switch (state) {
      case policy::CloudPolicySubsystem::UNENROLLED:
        switch (error_details) {
          case policy::CloudPolicySubsystem::BAD_SERIAL_NUMBER:
            actor_->ShowSerialNumberError();
            break;
          case policy::CloudPolicySubsystem::BAD_ENROLLMENT_MODE:
            actor_->ShowEnrollmentModeError();
            break;
          default:  // Still working...
            return;
        }
        break;
      case policy::CloudPolicySubsystem::BAD_GAIA_TOKEN:
      case policy::CloudPolicySubsystem::LOCAL_ERROR:
        actor_->ShowFatalEnrollmentError();
        break;
      case policy::CloudPolicySubsystem::UNMANAGED:
        actor_->ShowAccountError();
        break;
      case policy::CloudPolicySubsystem::NETWORK_ERROR:
        actor_->ShowNetworkEnrollmentError();
        break;
      case policy::CloudPolicySubsystem::TOKEN_FETCHED:
        if (!is_auto_enrollment_ ||
            g_browser_process->browser_policy_connector()->
                GetDeviceCloudPolicyDataStore()->device_mode() ==
            policy::DEVICE_MODE_ENTERPRISE) {
          WriteInstallAttributesData();
          return;
        } else {
          LOG(ERROR) << "Enrollment can not proceed because Auto-enrollment is "
                     << "not supported for non-enterprise enrollment modes.";
          policy::AutoEnrollmentClient::CancelAutoEnrollment();
          is_auto_enrollment_ = false;
          actor_->ShowAutoEnrollmentError();
          // Set the error state to something distinguishable in the logs.
          state = policy::CloudPolicySubsystem::LOCAL_ERROR;
          error_details = policy::CloudPolicySubsystem::AUTO_ENROLLMENT_ERROR;
        }
        break;
      case policy::CloudPolicySubsystem::SUCCESS:
        // Success!
        registrar_.reset();
        actor_->ShowConfirmationScreen();
        return;
    }
    // We have an error.
    if (!is_auto_enrollment_) {
      UMA_HISTOGRAM_ENUMERATION(policy::kMetricEnrollment,
                                policy::kMetricEnrollmentPolicyFailed,
                                policy::kMetricEnrollmentSize);
    }
    LOG(WARNING) << "Policy subsystem error during enrollment: " << state
                 << " details: " << error_details;
  }

  // Stop the policy infrastructure.
  registrar_.reset();
  g_browser_process->browser_policy_connector()->ResetDevicePolicy();
}

void EnterpriseEnrollmentScreen::WriteInstallAttributesData() {
  // Since this method is also called directly.
  weak_ptr_factory_.InvalidateWeakPtrs();

  switch (g_browser_process->browser_policy_connector()->LockDevice(user_)) {
    case policy::EnterpriseInstallAttributes::LOCK_SUCCESS: {
      // Proceed with policy fetch.
      policy::BrowserPolicyConnector* connector =
          g_browser_process->browser_policy_connector();
      connector->FetchCloudPolicy();
      return;
    }
    case policy::EnterpriseInstallAttributes::LOCK_NOT_READY: {
      // InstallAttributes not ready yet, retry later.
      LOG(WARNING) << "Install Attributes not ready yet will retry in "
                   << kLockRetryIntervalMs << "ms.";
      MessageLoop::current()->PostDelayedTask(
          FROM_HERE,
          base::Bind(&EnterpriseEnrollmentScreen::WriteInstallAttributesData,
                     weak_ptr_factory_.GetWeakPtr()),
          base::TimeDelta::FromMilliseconds(kLockRetryIntervalMs));
      return;
    }
    case policy::EnterpriseInstallAttributes::LOCK_BACKEND_ERROR: {
      actor_->ShowFatalEnrollmentError();
      return;
    }
    case policy::EnterpriseInstallAttributes::LOCK_WRONG_USER: {
      LOG(ERROR) << "Enrollment can not proceed because the InstallAttrs "
                 << "has been locked already!";
      actor_->ShowFatalEnrollmentError();
      return;
    }
  }

  NOTREACHED();
}

void EnterpriseEnrollmentScreen::RegisterForDevicePolicy(
    const std::string& token) {
  policy::BrowserPolicyConnector* connector =
      g_browser_process->browser_policy_connector();
  if (!connector->device_cloud_policy_subsystem()) {
    LOG(ERROR) << "Cloud policy subsystem not initialized.";
  } else if (connector->IsEnterpriseManaged()) {
    LOG(ERROR) << "Device is already enterprise managed!";
  } else if (connector->device_cloud_policy_subsystem()->state() ==
      policy::CloudPolicySubsystem::SUCCESS) {
    LOG(ERROR) << "A previous enrollment already succeeded!";
  } else {
    // Make sure the device policy subsystem is in a clean slate.
    connector->ResetDevicePolicy();
    connector->ScheduleServiceInitialization(0);
    registrar_.reset(new policy::CloudPolicySubsystem::ObserverRegistrar(
        connector->device_cloud_policy_subsystem(), this));
    // Push the credentials to the policy infrastructure. It'll start enrollment
    // and notify us of progress through CloudPolicySubsystem::Observer.
    connector->RegisterForDevicePolicy(user_, token, is_auto_enrollment_);
    return;
  }
  NOTREACHED();
  if (is_showing_)
    actor_->ShowFatalEnrollmentError();
}

}  // namespace chromeos
<|endoftext|>


<commit_before>#include <cudawarping.hpp>

extern "C"
struct TensorWrapper remapCuda(struct cutorchInfo info,
        struct TensorWrapper src, struct TensorWrapper map1,
        struct TensorWrapper map2, int interpolation, struct TensorWrapper dst,
        int borderMode, struct ScalarWrapper borderValue)
{
    if (dst.isNull()) {
        cuda::GpuMat retval;
        cuda::remap(src.toGpuMat(), retval, map1.toGpuMat(), map2.toGpuMat(),
                    interpolation, borderMode, borderValue, prepareStream(info));
        return TensorWrapper(retval, info.state);
    } else if (dst.tensorPtr == src.tensorPtr) {
        // in-place
        cuda::GpuMat source = src.toGpuMat();
        cuda::remap(source, source, map1.toGpuMat(), map2.toGpuMat(), interpolation,
                    borderMode, borderValue, prepareStream(info));
    } else {
        cuda::remap(src.toGpuMat(), dst.toGpuMat(), map1.toGpuMat(), map2.toGpuMat(),
                    interpolation, borderMode, borderValue, prepareStream(info));
    }
    return dst;
}

extern "C"
struct TensorWrapper resizeCuda(struct cutorchInfo info,
        struct TensorWrapper src, struct TensorWrapper dst,
        struct SizeWrapper dsize, double fx, double fy,
        int interpolation)
{
    GpuMatT dstMat = dst.toGpuMatT();
    cuda::resize(src.toGpuMat(), dstMat, dsize, fx, fy, interpolation, prepareStream(info));
    return TensorWrapper(dstMat, info.state);
}

extern "C"
struct TensorWrapper warpAffineCuda(struct cutorchInfo info,
        struct TensorWrapper src, struct TensorWrapper dst,
        struct TensorWrapper M, struct SizeWrapper dsize,
        int flags, int borderMode, struct ScalarWrapper borderValue)
{
    if (dst.isNull()) {
        cuda::GpuMat retval;
        cuda::warpAffine(src.toGpuMat(), retval, M.toGpuMat(), dsize, flags,
                         borderMode, borderValue, prepareStream(info));
        return TensorWrapper(retval, info.state);
    } else if (dst.tensorPtr == src.tensorPtr) {
        // in-place
        cuda::GpuMat source = src.toGpuMat();
        cuda::warpAffine(source, source, M.toGpuMat(), dsize, flags, borderMode,
                         borderValue, prepareStream(info));
    } else {
        cuda::warpAffine(src.toGpuMat(), dst.toGpuMat(), M.toGpuMat(), dsize,
                         flags, borderMode, borderValue, prepareStream(info));
    }
    return dst;
}

extern "C"
struct TensorArray buildWarpAffineMapsCuda(
        struct cutorchInfo info, struct TensorWrapper M, bool inverse,
        struct SizeWrapper dsize, struct TensorWrapper xmap, struct TensorWrapper ymap)
{
    std::vector<cuda::GpuMat> retval(2);
    retval[0] = xmap.toGpuMat();
    retval[1] = ymap.toGpuMat();

    cuda::buildWarpAffineMaps(M.toGpuMat(), inverse, dsize,
                              retval[0], retval[1], prepareStream(info));

    return TensorArray(retval, info.state);
}

extern "C"
struct TensorWrapper warpPerspectiveCuda(struct cutorchInfo info,
        struct TensorWrapper src, struct TensorWrapper dst,
        struct TensorWrapper M, struct SizeWrapper dsize,
        int flags, int borderMode, struct ScalarWrapper borderValue)
{
    if (dst.isNull()) {
        cuda::GpuMat retval;
        cuda::warpPerspective(src.toGpuMat(), retval, M.toGpuMat(), dsize,
                              flags, borderMode, borderValue, prepareStream(info));
        return TensorWrapper(retval, info.state);
    } else if (dst.tensorPtr == src.tensorPtr) {
        // in-place
        cuda::GpuMat source = src.toGpuMat();
        cuda::warpPerspective(source, source, M.toGpuMat(), dsize, flags,
                              borderMode, borderValue, prepareStream(info));
    } else {
        cuda::warpPerspective(src.toGpuMat(), dst.toGpuMat(), M.toGpuMat(),
                              dsize, flags, borderMode, borderValue, prepareStream(info));
    }
    return dst;
}

extern "C"
struct TensorArray buildWarpPerspectiveMapsCuda(
        struct cutorchInfo info, struct TensorWrapper M, bool inverse,
        struct SizeWrapper dsize, struct TensorWrapper xmap, struct TensorWrapper ymap)
{
    std::vector<cuda::GpuMat> retval(2);
    retval[0] = xmap.toGpuMat();
    retval[1] = ymap.toGpuMat();

    cuda::buildWarpPerspectiveMaps(M.toGpuMat(), inverse, dsize,
                                   retval[0], retval[1], prepareStream(info));

    return TensorArray(retval, info.state);
}

extern "C"
struct TensorWrapper rotateCuda(
        struct cutorchInfo info, struct TensorWrapper src, struct TensorWrapper dst,
        struct SizeWrapper dsize, double angle, double xShift, double yShift, int interpolation)
{
    cuda::GpuMat dstMat = dst.toGpuMat();
    cuda::rotate(src.toGpuMat(), dstMat, dsize, angle, xShift, yShift,
                 interpolation, prepareStream(info));
    return TensorWrapper(dstMat, info.state);
}

extern "C"
struct TensorWrapper pyrDownCuda(struct cutorchInfo info,
        struct TensorWrapper src, struct TensorWrapper dst)
{
    if (dst.isNull()) {
        cuda::GpuMat retval;
        cuda::pyrDown(src.toGpuMat(), retval, prepareStream(info));
        return TensorWrapper(retval, info.state);
    } else if (dst.tensorPtr == src.tensorPtr) {
        // in-place
        cuda::GpuMat source = src.toGpuMat();
        cuda::pyrDown(source, source, prepareStream(info));
    } else {
        cuda::pyrDown(src.toGpuMat(), dst.toGpuMat(), prepareStream(info));
    }
    return dst;
}

extern "C"
struct TensorWrapper pyrUpCuda(struct cutorchInfo info,
        struct TensorWrapper src, struct TensorWrapper dst)
{
    if (dst.isNull()) {
        cuda::GpuMat retval;
        cuda::pyrUp(src.toGpuMat(), retval, prepareStream(info));
        return TensorWrapper(retval, info.state);
    } else if (dst.tensorPtr == src.tensorPtr) {
        // in-place
        cuda::GpuMat source = src.toGpuMat();
        cuda::pyrUp(source, source, prepareStream(info));
    } else {
        cuda::pyrUp(src.toGpuMat(), dst.toGpuMat(), prepareStream(info));
    }
    return dst;
}
<commit_msg>Fix #132<commit_after>#include <cudawarping.hpp>

extern "C"
struct TensorWrapper remapCuda(struct cutorchInfo info,
        struct TensorWrapper src, struct TensorWrapper map1,
        struct TensorWrapper map2, int interpolation, struct TensorWrapper dst,
        int borderMode, struct ScalarWrapper borderValue)
{
    if (dst.isNull()) {
        cuda::GpuMat retval;
        cuda::remap(src.toGpuMat(), retval, map1.toGpuMat(), map2.toGpuMat(),
                    interpolation, borderMode, borderValue, prepareStream(info));
        return TensorWrapper(retval, info.state);
    } else if (dst.tensorPtr == src.tensorPtr) {
        // in-place
        cuda::GpuMat source = src.toGpuMat();
        cuda::remap(source, source, map1.toGpuMat(), map2.toGpuMat(), interpolation,
                    borderMode, borderValue, prepareStream(info));
    } else {
        cuda::remap(src.toGpuMat(), dst.toGpuMat(), map1.toGpuMat(), map2.toGpuMat(),
                    interpolation, borderMode, borderValue, prepareStream(info));
    }
    return dst;
}

extern "C"
struct TensorWrapper resizeCuda(struct cutorchInfo info,
        struct TensorWrapper src, struct TensorWrapper dst,
        struct SizeWrapper dsize, double fx, double fy,
        int interpolation)
{
    GpuMatT dstMat = dst.toGpuMatT();
    cuda::resize(src.toGpuMat(), dstMat, dsize, fx, fy, interpolation, prepareStream(info));
    return TensorWrapper(dstMat, info.state);
}

extern "C"
struct TensorWrapper warpAffineCuda(struct cutorchInfo info,
        struct TensorWrapper src, struct TensorWrapper dst,
        struct TensorWrapper M, struct SizeWrapper dsize,
        int flags, int borderMode, struct ScalarWrapper borderValue)
{
    if (dst.isNull()) {
        cuda::GpuMat retval;
        cuda::warpAffine(src.toGpuMat(), retval, M.toMat(), dsize, flags,
                         borderMode, borderValue, prepareStream(info));
        return TensorWrapper(retval, info.state);
    } else if (dst.tensorPtr == src.tensorPtr) {
        // in-place
        cuda::GpuMat source = src.toGpuMat();
        cuda::warpAffine(source, source, M.toMat(), dsize, flags, borderMode,
                         borderValue, prepareStream(info));
    } else {
        cuda::warpAffine(src.toGpuMat(), dst.toGpuMat(), M.toMat(), dsize,
                         flags, borderMode, borderValue, prepareStream(info));
    }
    return dst;
}

extern "C"
struct TensorArray buildWarpAffineMapsCuda(
        struct cutorchInfo info, struct TensorWrapper M, bool inverse,
        struct SizeWrapper dsize, struct TensorWrapper xmap, struct TensorWrapper ymap)
{
    std::vector<cuda::GpuMat> retval(2);
    retval[0] = xmap.toGpuMat();
    retval[1] = ymap.toGpuMat();

    cuda::buildWarpAffineMaps(M.toGpuMat(), inverse, dsize,
                              retval[0], retval[1], prepareStream(info));

    return TensorArray(retval, info.state);
}

extern "C"
struct TensorWrapper warpPerspectiveCuda(struct cutorchInfo info,
        struct TensorWrapper src, struct TensorWrapper dst,
        struct TensorWrapper M, struct SizeWrapper dsize,
        int flags, int borderMode, struct ScalarWrapper borderValue)
{
    if (dst.isNull()) {
        cuda::GpuMat retval;
        cuda::warpPerspective(src.toGpuMat(), retval, M.toGpuMat(), dsize,
                              flags, borderMode, borderValue, prepareStream(info));
        return TensorWrapper(retval, info.state);
    } else if (dst.tensorPtr == src.tensorPtr) {
        // in-place
        cuda::GpuMat source = src.toGpuMat();
        cuda::warpPerspective(source, source, M.toGpuMat(), dsize, flags,
                              borderMode, borderValue, prepareStream(info));
    } else {
        cuda::warpPerspective(src.toGpuMat(), dst.toGpuMat(), M.toGpuMat(),
                              dsize, flags, borderMode, borderValue, prepareStream(info));
    }
    return dst;
}

extern "C"
struct TensorArray buildWarpPerspectiveMapsCuda(
        struct cutorchInfo info, struct TensorWrapper M, bool inverse,
        struct SizeWrapper dsize, struct TensorWrapper xmap, struct TensorWrapper ymap)
{
    std::vector<cuda::GpuMat> retval(2);
    retval[0] = xmap.toGpuMat();
    retval[1] = ymap.toGpuMat();

    cuda::buildWarpPerspectiveMaps(M.toGpuMat(), inverse, dsize,
                                   retval[0], retval[1], prepareStream(info));

    return TensorArray(retval, info.state);
}

extern "C"
struct TensorWrapper rotateCuda(
        struct cutorchInfo info, struct TensorWrapper src, struct TensorWrapper dst,
        struct SizeWrapper dsize, double angle, double xShift, double yShift, int interpolation)
{
    cuda::GpuMat dstMat = dst.toGpuMat();
    cuda::rotate(src.toGpuMat(), dstMat, dsize, angle, xShift, yShift,
                 interpolation, prepareStream(info));
    return TensorWrapper(dstMat, info.state);
}

extern "C"
struct TensorWrapper pyrDownCuda(struct cutorchInfo info,
        struct TensorWrapper src, struct TensorWrapper dst)
{
    if (dst.isNull()) {
        cuda::GpuMat retval;
        cuda::pyrDown(src.toGpuMat(), retval, prepareStream(info));
        return TensorWrapper(retval, info.state);
    } else if (dst.tensorPtr == src.tensorPtr) {
        // in-place
        cuda::GpuMat source = src.toGpuMat();
        cuda::pyrDown(source, source, prepareStream(info));
    } else {
        cuda::pyrDown(src.toGpuMat(), dst.toGpuMat(), prepareStream(info));
    }
    return dst;
}

extern "C"
struct TensorWrapper pyrUpCuda(struct cutorchInfo info,
        struct TensorWrapper src, struct TensorWrapper dst)
{
    if (dst.isNull()) {
        cuda::GpuMat retval;
        cuda::pyrUp(src.toGpuMat(), retval, prepareStream(info));
        return TensorWrapper(retval, info.state);
    } else if (dst.tensorPtr == src.tensorPtr) {
        // in-place
        cuda::GpuMat source = src.toGpuMat();
        cuda::pyrUp(source, source, prepareStream(info));
    } else {
        cuda::pyrUp(src.toGpuMat(), dst.toGpuMat(), prepareStream(info));
    }
    return dst;
}
<|endoftext|>